v1.3.0 — single jar covers Fabric 1.21.6 + Fabric 26.1.2 + NeoForge 1.21.6
이전엔 1.21.6 (v1.1.1) 와 26.1.2 (v1.2.1) 가 분리된 jar 였음. 사용자 입장에서
버전별로 다른 파일을 받아야 했고 합친 의미가 없어서, 한 jar 가 어느 환경에든
들어갈 수 있도록 컨테이너 구조로 재작업.
구조:
- outer chat_answer-1.3.0.jar
├── fabric.mod.json (entrypoint 없는 컨테이너 메타. MC dep 없음.)
├── META-INF/neoforge.mods.toml (NeoForge 1.21.6 모드 본체 메타)
├── kr/.../neoforge/ (NeoForge 1.21.6 entry + core, Mojang 매핑)
├── kr/.../core/ (NeoForge 가 쓰는 공유 core 사본)
└── META-INF/jars/ (Fabric Loader 가 자동 스캔)
├── chat_answer-fabric-1216-1.3.0.jar (MC ">=1.21.6 <1.22")
└── chat_answer-fabric-2612-1.3.0.jar (MC ">=26.1.2")
로더별 동작:
- Fabric 1.21.6 → outer 는 no-op 컨테이너, 1216 nested 가 활성 (intermediary class_NNNN 리매핑됨)
- Fabric 26.1.2 → outer 는 no-op 컨테이너, 2612 nested 가 활성 (intermediary 0.0.0 identity)
- NeoForge 1.21.6 → outer 의 NeoForge entry 가 동작. Fabric 메타와 nested jars 는 NeoForge 가 무시.
핵심 트레이드오프:
- 1.21.6 fabric subproject 는 modImplementation 필수 (intermediary 매핑 리맵 필요)
- 26.1.2 fabric subproject 는 implementation 으로 충분 (서버 jar unobfuscated → identity 매핑)
- 26.1.2 NeoForge 는 moddev plugin 이 아직 26.x 를 파싱 못 함 → 1.21.6 만 지원
- 두 nested fabric jar 는 mod id 동일 (chat_answer_fabric) — depends.minecraft 가 상호 배타라
한 환경에서 둘이 동시 candidate 가 되지 않으므로 충돌 없음.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
52
build.gradle
52
build.gradle
@@ -8,6 +8,8 @@ allprojects {
|
||||
group = project.mod_group
|
||||
version = project.mod_version
|
||||
|
||||
// 기본 JDK toolchain 은 Java 25 (26.x Loom 빌드 요구). subproject 가 필요하면
|
||||
// 자체 release 21 등으로 다운그레이드.
|
||||
java {
|
||||
toolchain.languageVersion = JavaLanguageVersion.of(25)
|
||||
}
|
||||
@@ -24,7 +26,51 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
// MC 26.1.2 배포물은 Fabric jar 단일 빌드. buildAll = fabric remapJar 결과물.
|
||||
tasks.register('buildAll') {
|
||||
dependsOn ':fabric:remapJar'
|
||||
// ───── 단일 배포 jar 컨테이너 ────────────────────────────────────────────────
|
||||
// 한 jar 가 어떤 환경에서도 동작하도록:
|
||||
// * outer = NeoForge 1.21.6 모드 본체 (NeoForge 만 fabric.mod.json 을 무시)
|
||||
// + 메타로 fabric.mod.json (entrypoint 없는 컨테이너)
|
||||
// * META-INF/jars/ = Fabric 용 nested jar 둘 (1.21.6 / 26.1.2)
|
||||
// Fabric Loader 가 depends.minecraft 로 자동 매칭. NeoForge 는 무시.
|
||||
//
|
||||
// 결과: chat_answer-<version>.jar 한 개를 Fabric 1.21.6 / Fabric 26.1.2 / NeoForge
|
||||
// 1.21.6 어디에 넣어도 적절한 코드 경로가 활성화된다.
|
||||
|
||||
tasks.register('containerJar', Jar) {
|
||||
dependsOn ':fabric-1216:remapJar',
|
||||
':fabric-2612:remapJar',
|
||||
':neoforge-1216:jar'
|
||||
|
||||
archiveBaseName = project.mod_id
|
||||
archiveVersion = project.mod_version
|
||||
archiveClassifier = ''
|
||||
destinationDirectory = file('build/libs')
|
||||
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
|
||||
// 1. NeoForge 모드 본체 (classes + META-INF/neoforge.mods.toml + icon.png) 을 통째로.
|
||||
// MANIFEST.MF 는 새 jar 가 자체적으로 생성하니 제외.
|
||||
from(zipTree(project(':neoforge-1216').tasks.named('jar').flatMap { it.archiveFile })) {
|
||||
exclude 'META-INF/MANIFEST.MF'
|
||||
}
|
||||
|
||||
// 2. Fabric 컨테이너 메타데이터 (entrypoint 없이 그냥 "외피") 와 아이콘.
|
||||
// fabric.mod.json 의 ${version} 만 치환.
|
||||
filteringCharset = 'UTF-8'
|
||||
from("${rootDir}/container-resources") {
|
||||
filesMatching("fabric.mod.json") {
|
||||
expand("version": project.mod_version)
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Fabric nested jars (Fabric Loader 가 META-INF/jars/ 를 스캔해서
|
||||
// depends.minecraft 매칭되는 jar 만 활성화).
|
||||
into('META-INF/jars') {
|
||||
from project(':fabric-1216').tasks.named('remapJar').flatMap { it.archiveFile }
|
||||
from project(':fabric-2612').tasks.named('remapJar').flatMap { it.archiveFile }
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('buildAll') {
|
||||
dependsOn 'containerJar'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user