본문으로 건너뛰기
버전: Minecraft 26.2

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)​

  1. 모드 파일 스캔: PolyLauncherMain이 mods 폴더를 탐색하고 중첩된 JAR(NestedJarExtractor)를 추출합니다.
  2. 메타데이터 파싱:
    • poly.mod.json, fabric.mod.json, quilt.mod.json, META-INF/mods.toml, neoforge.mods.toml을 파싱합니다.
    • 의존성 조건, 지원 버전, 충돌 선언을 정규화합니다.
  3. 호스트 패치 사전 검사 (HostPatchCheck):
    • Forge나 NeoForge가 활성화되면 게임 JAR가 바이너리 패치됩니다.
    • Poly는 패치된 실제 바이트코드와 Fabric/Quilt의 Mixin 주입 지점을 전수 대조합니다.
    • 바닐라와 달라진 메서드에 안전하게 결합할 수 없는 Mixin은 POLY-COMPAT-224 코드로 식별하고 클래스로딩 전에 안전하게 격리합니다.

2단계: 바이트코드 변환 계획 (Bytecode Transformation Planning)​

  1. 규칙 등록:
    • Native API 모드의 선언적 변환 규칙과 호스트 브릿지의 주입점 대체 규칙(NeoForgeInjectionPoints 등)을 등록합니다.
  2. 변환 캐싱:
    • 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)​

  1. 로더 간 모드 목록 공유:
    • Fabric 모드가 FabricLoader.getInstance().isModLoaded("forge_mod")를 호출하면 Forge 모드도 정상적으로 인식됩니다.
    • Forge가 ModList.get().isLoaded("fabric_mod")를 호출하면 합성된 IModInfo 설명자(ForeignModList)를 반환합니다.
  2. 레지스트리 동결 해제:
    • NeoForge는 부팅 초기에 레지스트리를 동결합니다. Poly는 Fabric 모드 초기화 시 루트 레지스트리를 일시적으로 동결 해제(NeoForgeRegistryOpening)하여 Registry is already frozen 예외를 방지합니다.
  3. 네트워크 페이로드 다중화:
    • Fabric(c:register)과 NeoForge(neoforge:) 채널이 충돌하지 않도록 페이로드를 필터링하여 접속 끊김을 방지합니다.

3. 커스텀 로딩 화면 (PolyLoadingOverlay)​

Minecraft 26.1, 26.2, 26.3에서 타 로더의 로딩 화면 간섭을 차단하고 자체 오버레이를 제공합니다:

  • Forge/NeoForge의 조기 진행 윈도우(earlyprogresswindow)를 숨깁니다.
  • 세련된 다크 테마(#0E131F) 로딩 화면을 표시합니다.
  • 상단에 활성화된 모드 수를 로더별(Fabric, Forge, NeoForge, Quilt, Poly)로 실시간 표시합니다.
  • 마인크래프트 내장 Component.literal 및 ChatFormatting 렌더링 파이프라인을 사용하여 어떤 GPU 드라이버에서도 글씨 깨짐 없는 선명한 폰트를 보장합니다.
Buy me a coffee