Poly 모드 로더 — 아키텍처 심층 분석
이 문서는 Poly 모드 로더의 내부 아키텍처, 클래스로더 구성 및 바이트코드 가상화 메커니즘을 상세히 다룹니다.
1. 최상위 아키텍처 개요
Poly 모드 로더는 마인크래프트와 서로 다른 로더들(Fabric, Forge, NeoForge, Quilt)을 단일 Java Virtual Machine (JVM) 프로세스 안에서 상호 연동합니다.
flowchart TD
subgraph Launch["1. 부트스트랩 & 모드 탐색"]
Entry["PolyLauncherMain (poly-bootstrap)"] --> Scanner["모드 스캐너 (poly-runtime-impl)"]
Scanner --> Metadata["메타데이터 파서 (poly-mod-metadata)"]
Metadata --> Assess["사전 호환성 정밀 진단 (HostPatchCheck)"]
end
subgraph Planning["2. 바이트코드 변환 & 계획"]
Assess --> PlanEngine["ClassTransformPlanner (poly-transform-engine)"]
PlanEngine --> Adjust["HostPatchAdjustments & InjectionPointReplacements"]
Adjust --> Cache["DirectoryTransformCache (ASM 9.11)"]
end
subgraph Runtime["3. 가상화 런타임 호스팅"]
Cache --> ClassLoader["GameClassLoader"]
ClassLoader --> MixinService["통합 PolyMixinService (Mixin 0.8.7)"]
ClassLoader --> ForgeHost["Forge / NeoForge FML 레이어 가상화"]
ClassLoader --> FabricHost["FabricLoader & QuiltLoader 에뮬레이터"]
end
subgraph Game["4. 게임 실행"]
ClassLoader --> Minecraft["Minecraft: Java Edition 엔진"]
Minecraft --> Overlay["PolyLoadingOverlay (다크 커스텀 UI)"]
Minecraft --> World["통합 월드 & 엔티티 라이프사이클"]
end
2. 4단계 실행 라이프사이클
1단계: 탐색 및 사전 평가 (Discovery & Assessment)
- 모드 파일 스캔:
PolyLauncherMain이 mods 폴더를 탐색하고 중첩된 JAR(NestedJarExtractor)를 추출합니다. - 메타데이터 파싱:
poly.mod.json,fabric.mod.json,quilt.mod.json,META-INF/mods.toml,neoforge.mods.toml을 파싱합니다.- 의존성 조건, 지원 버전, 충돌 선언을 정규화합니다.
- 호스트 패치 사전 검사 (
HostPatchCheck):- Forge나 NeoForge가 활성화되면 게임 JAR가 바이너리 패치됩니다.
- Poly는 패치된 실제 바이트코드와 Fabric/Quilt의 Mixin 주입 지점을 전수 대조합니다.
- 바닐라와 달라진 메서드에 안전하게 결합할 수 없는 Mixin은
POLY-COMPAT-224코드로 식별하고 클래스로딩 전에 안전하게 격리합니다.
2단계: 바이트코드 변환 계획 (Bytecode Transformation Planning)
- 규칙 등록:
- Native API 모드의 선언적 변환 규칙과 호스트 브릿지의 주입점 대체 규칙(
NeoForgeInjectionPoints등)을 등록합니다.
- Native API 모드의 선언적 변환 규칙과 호스트 브릿지의 주입점 대체 규칙(
- 변환 캐싱:
ClassTransformPlanner가 바이트코드 서명을 검증합니다.- 변환된 클래스는 엔진 버전, 원본 바이트코드, 변환 규칙 해시 기반의 디스크 캐시(
DirectoryTransformCache, 기본 256 MiB)에 저장되어 이후 부팅 시간을 단축합니다.
3단계: 클래스로더 토폴로지 및 통합 Mixin
기존 로더들은 시스템 클래스로더나 스레드 컨텍스트를 독점하려 합니다(Forge ModLauncher vs Fabric Knot). Poly는 이를 다음과 같이 해결합니다:
GameClassLoader: 단 하나의 변환 클래스로더가 게임 전체를 담당합니다. 게임과 모드 클래스를 자식 우선(Child-first)으로 정의하여 모든 클래스가 변환 파이프라인을 거칩니다.- 단일 Mixin 엔진: Forge와 Fabric이 각자의 Mixin 인스턴스를 띄우는 대신, 단 하나의
PolyMixinService(Mixin 0.8.7 + MixinExtras 0.5.5)가 Fabric, Quilt, Forge, NeoForge 모드의 Mixin 설정을 통합 처리합니다. - FML 모듈 레이어링: Forge의 BOOT, SERVICE, PLUGIN 레이어를 변환 클래스로더에 직접 매핑하여 클래스로더 충돌을 차단합니다.
4단계: 런타임 상호 운용성 (Runtime Interoperability)
- 로더 간 모드 목록 공유:
- Fabric 모드가
FabricLoader.getInstance().isModLoaded("forge_mod")를 호출하면 Forge 모드도 정상적으로 인식됩니다. - Forge가
ModList.get().isLoaded("fabric_mod")를 호출하면 합성된IModInfo설명자(ForeignModList)를 반환합니다.
- Fabric 모드가
- 레지스트리 동결 해제:
- NeoForge는 부팅 초기에 레지스트리를 동결합니다. Poly는 Fabric 모드 초기화 시 루트 레지스트리를 일시적으로 동결 해제(
NeoForgeRegistryOpening)하여Registry is already frozen예외를 방지합니다.
- NeoForge는 부팅 초기에 레지스트리를 동결합니다. Poly는 Fabric 모드 초기화 시 루트 레지스트리를 일시적으로 동결 해제(
- 네트워크 페이로드 다중화:
- Fabric(
c:register)과 NeoForge(neoforge:) 채널이 충돌하지 않도록 페이로드를 필터링하여 접속 끊김을 방지합니다.
- Fabric(
3. 커스텀 로딩 화면 (PolyLoadingOverlay)
Minecraft 26.1, 26.2, 26.3에서 타 로더의 로딩 화면 간섭을 차단하고 자체 오버레이를 제공합니다:
- Forge/NeoForge의 조기 진행 윈도우(
earlyprogresswindow)를 숨깁니다. - 세련된 다크 테마(
#0E131F) 로딩 화면을 표시합니다. - 상단에 활성화된 모드 수를 로더별(
Fabric,Forge,NeoForge,Quilt,Poly)로 실시간 표시합니다. - 마인크래프트 내장
Component.literal및ChatFormatting렌더링 파이프라인을 사용하여 어떤 GPU 드라이버에서도 글씨 깨짐 없는 선명한 폰트를 보장합니다.