Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
24ea09d
refactor: Handle Minecraft's new version format
null2264 Jan 7, 2026
678d0a8
fix: Fix build
null2264 Jan 7, 2026
ed8be94
fix: Malformed JSON
null2264 Jan 7, 2026
f2ebca5
ci: Update mc-runtime-test
null2264 Jan 7, 2026
4183594
chore(deps): 26.1 uses Java 25
null2264 Jan 7, 2026
acc0a71
chore(deps): Update NeoForge
null2264 Apr 13, 2026
cfca7cf
fix: Fix neo build
null2264 Jan 7, 2026
4cc7920
fix: Disable obf by default
null2264 Apr 13, 2026
98824e7
chore(deps): Update loom to v1.14
null2264 Apr 13, 2026
c36a72f
chore(deps): Update gradle to v9.2.1
null2264 Jan 8, 2026
8032cc6
fix(deps): Update architectury-plugin
null2264 Apr 13, 2026
c15bdca
fix(deps): Update shadow
null2264 Jan 8, 2026
4ba1a71
fix: Gradle pain
null2264 Jan 8, 2026
fcd192f
fix: Update spongegradle to 0.2.2 to fix Shadow
null2264 Apr 13, 2026
f46d532
fix: modCompileOnly is loom only
null2264 Apr 13, 2026
63df951
fix: Fix build
null2264 Apr 13, 2026
d216c85
chore(deps): Use arch-plugin 3.5
null2264 Apr 29, 2026
7b9e50c
fix(deps): Use ArchLoom 1.13 for older versions
null2264 Apr 29, 2026
6ccbb89
fix(deps): Fix format
null2264 Apr 29, 2026
9904fff
fix(deps): That's not how you do it
null2264 Apr 29, 2026
5aa4381
fix: Maybe?
null2264 Jun 25, 2026
b267db3
fix: Gradle nightmare
null2264 Jun 25, 2026
7d60794
fix: Sleepy
null2264 Jun 25, 2026
626a974
fix: Old version number format for new MC version formatting
null2264 Jun 25, 2026
f6ada1e
fix(deps): Update fabric loader to 0.17.3
null2264 Jun 25, 2026
6a635f0
fix: Remove mapping
null2264 Jun 25, 2026
a45b5be
chore(deps): Update VanillaGradle to 0.3.2 for 26.x
null2264 Jun 26, 2026
b8ac9b5
fix: Adding back mod prefix
null2264 Jun 26, 2026
9f905d8
chore(deps): Update Mod Publish Plugin to v2.1.1
null2264 Jun 26, 2026
7a2c8f4
fix: Tf is happening?
null2264 Jun 26, 2026
7524255
revert: Tf is happening?!?
null2264 Jun 26, 2026
2137b37
fix: Remove RemapJar usage for 26.1+
null2264 Jun 26, 2026
8871014
refactor: Clean up
null2264 Jun 26, 2026
b4a808a
fix: Kotlin DSL moments
null2264 Jun 26, 2026
36aedf6
fix: What a pain
null2264 Jun 26, 2026
f7b9860
fix: Dangit
null2264 Jun 26, 2026
e6fa93b
fix: Such bs
null2264 Jun 27, 2026
4721906
fix: What if...
null2264 Jun 27, 2026
cb736df
refactor: AW -> CT
null2264 Jun 27, 2026
c954391
fix: It's named not official
null2264 Jun 27, 2026
25797c0
fix: 26.1 is no longer named
null2264 Jun 27, 2026
b60b8fc
fix: It's actually official?
null2264 Jun 27, 2026
6eee705
revert: CT for 26.1
null2264 Jun 27, 2026
77d154a
fix(deps): EMI still stuck at 1.21.1
null2264 Jun 28, 2026
c4b969d
fix(deps): REI also skipped 1.21.11
null2264 Jun 28, 2026
80945fc
chore(deps): Update JEI
null2264 Jun 28, 2026
07c73b6
fix: Skip REI in 1.21.11
null2264 Jun 28, 2026
be72a35
fix: AW/CT for NeoForge 1.21.5
null2264 Jun 28, 2026
7a9e3a1
fix: Target remapJar on 1.21.5 not jar
null2264 Jun 28, 2026
0a18476
fix(deps): Update loom to v1.17
null2264 Jun 28, 2026
763cad5
fix: Annoying bs
null2264 Jun 28, 2026
ee81ec2
fix: Use Aw2At API
null2264 Jul 2, 2026
5bb9954
chore(deps/pre-26.1): Update to 1.17
null2264 Jul 2, 2026
4e61002
fix(deps): Update gradle to v9.4.1
null2264 Jul 3, 2026
cc2ba3d
fix: CT for 26.1
null2264 Jul 3, 2026
cd53473
fix(deps): EMI dropping some MC versions
null2264 Jul 3, 2026
4baf7c3
fix: Manually do the AT
null2264 Jul 3, 2026
ff5e69a
fix: Remove AT from mods.toml
null2264 Jul 3, 2026
4124413
fix: Neo can't find the AT
null2264 Jul 3, 2026
cbf605f
fix: Fix AT
null2264 Jul 3, 2026
4ac4eb4
fix(deps): `basic-math` dependency
null2264 Jul 3, 2026
5084a80
refactor: Dynamically generate AW/CT and AT
null2264 Jul 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
- name: Retrieve JSON
run: |
curl -Ls -o "headlessmc.json" "https://api.github.com/repos/3arthqu4ke/headlessmc/releases/tags/2.7.1" --header "Authorization: ${{ secrets.GITHUB_TOKEN }}"
curl -Ls -o "mc-runtime-test.json" "https://api.github.com/repos/null2264/mc-runtime-test/releases/tags/5.2.3" --header "Authorization: ${{ secrets.GITHUB_TOKEN }}"
curl -Ls -o "mc-runtime-test.json" "https://api.github.com/repos/null2264/mc-runtime-test/releases/tags/5.2.5" --header "Authorization: ${{ secrets.GITHUB_TOKEN }}"

- name: Upload jar files
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -98,11 +98,12 @@ jobs:
8
17
21
25
gradle-no-cache-if: true

- name: Setup properties
run: |
echo "org.gradle.java.installations.fromEnv=JAVA_HOME,JAVA_HOME_8_X64,JAVA_HOME_17_X64,JAVA_HOME_21_X64" >> gradle.properties
echo "org.gradle.java.installations.fromEnv=JAVA_HOME,JAVA_HOME_8_X64,JAVA_HOME_17_X64,JAVA_HOME_21_X64,JAVA_HOME_25_X64" >> gradle.properties

- name: Build with Gradle
run: |
Expand Down
98 changes: 71 additions & 27 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import net.fabricmc.loom.LoomGradleExtension
import net.fabricmc.loom.api.LoomGradleExtensionAPI
import dependencies.minecraft as MC
import org.apache.tools.ant.filters.StripJavaComments
import org.gradle.api.internal.file.copy.CopySpecInternal

plugins {
id("java")
id("architectury-plugin") version "3.4-SNAPSHOT"
id("io.github.null2264.architectury-loom") version "1.13-SNAPSHOT" apply false
id("architectury-plugin") version "3.5-SNAPSHOT"
id("io.github.null2264.architectury-loom-dyn") apply false
id("com.gradleup.shadow") apply false
id("me.modmuss50.mod-publish-plugin") version "1.1.0"
id("me.modmuss50.mod-publish-plugin") version "2.1.1"
}

val modVersion = System.getenv("VERSION") ?: project.properties["mod_version"] as? String ?: "0.0.0"
Expand All @@ -19,21 +20,18 @@ val loaderName = project.properties["null2264.platform"] as? String ?: ""
val isForge = loaderName.endsWith("forge")
val isNeo = loaderName.endsWith("neoforge")
val isFabric = loaderName.endsWith("fabric")
val _mcVer = project.properties["mcVer"] as? String ?: ""
val mcVersionStr = if (_mcVer.startsWith("1.")) _mcVer else "2.$_mcVer"
val (major, minor, patch, hotfix) = mcVersionStr
val mcVersionStr = project.properties["mcVer"] as? String ?: ""
val (major, minor, patch) = mcVersionStr
.split(".")
.toMutableList()
.apply { while (this.size < 4) this.add("") }
val mcHotfix: Int = hotfix.toIntOrNull() ?: 0
.apply { while (this.size < 3) this.add("") }
val mcVersion: Int = "${major}${minor.padStart(2, '0')}${patch.padStart(2, '0')}".toInt()
val versionRange = supportedVersionRange(mcVersion, loaderName)

fun setupPreprocessor() {
val buildProps = buildString {
append("# DON'T TOUCH THIS FILE, This is handled by the build script\n")
append("MC=${mcVersion}\n")
append("BUILD=${mcHotfix}\n")
if (isFabric) append("FABRIC=1\n")
if (isForge) append("FORGE=${if (!isNeo) "1" else "2"}\n")
}
Expand All @@ -43,7 +41,7 @@ fun setupPreprocessor() {
setupPreprocessor()

architectury {
minecraft = MC.versioned(mcVersion, mcHotfix)
minecraft = MC.versioned(mcVersion)
}

allprojects {
Expand All @@ -52,7 +50,6 @@ allprojects {

ext["mcVersion"] = mcVersion
ext["mcVersionStr"] = mcVersionStr
ext["mcHotfix"] = mcHotfix
ext["loaderName"] = loaderName
ext["isFabric"] = isFabric
ext["isForge"] = isForge
Expand Down Expand Up @@ -132,21 +129,27 @@ subprojects {
if (isModModule) {
// NOTE: This must be set before archloom is applied!
extra.set("loom.platform", loaderName)
}

if (isMcModule) {
apply(plugin = "architectury-plugin")
apply(plugin = "io.github.null2264.architectury-loom")

if (mcVersion < 260100) {
apply(plugin = "io.github.null2264.architectury-loom")
} else {
apply(plugin = "io.github.null2264.architectury-loom-no-remap")
}

val arch = project.extensions["architectury"] as ArchitectPluginExtension
arch.apply {
if (isModModule)
loader(loaderName)
else
common(listOf(loaderName))
}
val loom = project.extensions["loom"] as LoomGradleExtension
loom.apply {
silentMojangMappingsLicense()
if (mcVersion < 260100) {
val loom = project.extensions["loom"] as LoomGradleExtension
loom.apply {
silentMojangMappingsLicense()
}
}
}

Expand Down Expand Up @@ -184,19 +187,21 @@ subprojects {
}

val loom by lazy {
if (!isMcModule) {
throw IllegalStateException("Loom only available for MC modules")
if (!isModModule) {
throw IllegalStateException("Loom only available for submodules that applied Loom")
}
project.the<LoomGradleExtensionAPI>()
}

dependencies {
if (isMcModule) {
if (isModModule) {
val minecraft by configurations
val mappings by configurations
minecraft(MC.versioned(mcVersion))

minecraft(MC.versioned(mcVersion, mcHotfix))
mappings(loom.officialMojangMappings())
if (mcVersion < 260100) {
val mappings by configurations
mappings(loom.officialMojangMappings())
}
}

shade("blue.endless:jankson:${project.properties["jankson_version"]}")
Expand All @@ -207,8 +212,8 @@ subprojects {

if (isModModule) {
compileOnly(project(":stubs"))
compileInternal(project(":mclib", configuration = "namedElements")) { isTransitive = false }
shadeInternal(project(":mclib", configuration = "transformProduction$loaderProd")) {
compileInternal(project(":mclib")) { isTransitive = false }
shadeInternal(project(":mclib")) {
// Remove Junit test libraries
exclude(group = "org.junit.jupiter", module = "junit-jupiter")
exclude(group = "org.junit.jupiter", module = "junit-jupiter-engine")
Expand All @@ -226,6 +231,21 @@ subprojects {
}

val shadowJar by tasks.getting(ShadowJar::class) {
if (mcVersion >= 260100) {
dependsOn(tasks.jar)

val mainSpecMethod = AbstractCopyTask::class.java.getDeclaredMethod("getMainSpec").apply {
isAccessible = true
}
val actualMainSpec = mainSpecMethod.invoke(this)

val sourcePathsMethod = actualMainSpec::class.java.getMethod("getSourcePaths")
val sourcePaths = sourcePathsMethod.invoke(actualMainSpec) as MutableCollection<*>
sourcePaths.clear()

from(tasks.jar.map { zipTree(it.archiveFile) })
}

isZip64 = true
relocate("blue.endless.jankson", "io.github.null2264.shadowed.jankson")
if (mcVersion <= 11605) {
Expand All @@ -237,14 +257,16 @@ subprojects {
if (isFabric) {
exclude("META-INF/mods.toml")
exclude("META-INF/neoforge.mods.toml")
exclude("META-INF/accesstransformer.cfg")
} else if (isForge) {
exclude("fabric.mod.json")
exclude(if (isNeo && mcVersion >= 12006) "META-INF/mods.toml" else "META-INF/neoforge.mods.toml")
if (mcVersion < 12105) exclude("META-INF/accesstransformer.cfg")
}
exclude("architectury.common.json")

configurations = listOf(shade, shadeInternal)
archiveClassifier.set("dev-shade")
archiveClassifier.set(if (mcVersion >= 260100) null else "dev-shade")
mergeServiceFiles()
}

Expand Down Expand Up @@ -295,14 +317,29 @@ subprojects {
project.file("build/resources/main/META-INF/mods.toml")
.processModsToml(mcVersion, if (!isForge) 0 else (if (isNeo) 2 else 1))

if (mcVersion >= 12105) {
if (isForge)
project.file("build/resources/main/META-INF/accesstransformer.cfg")
.processAT(mcVersion)
else
project.file("build/resources/main/cobblegen.classtweaker")
.processAW(mcVersion)
}

// We can't preprocess resources files with Manifold, so we'll construct the json files manually here instead.
project.file("build/resources/main/cobblegen.mixins.json").processMixinsJson(mcVersion, isFabric)
if (isFabric) project.file("build/resources/main/fabric.mod.json").processFabricModJson(mcVersion)
}
}

val targetJavaVersion = if (!isApi) {
if (mcVersion >= 12006) 21 else (if (mcVersion >= 11700) 17 else 8)
when (mcVersion) {
in 11200..11605 -> 8
in 11700..11701 -> 16
in 11800..12004 -> 17
in 12005..12111 -> 21
else -> 25
}
} else {
8 // APIs should always target Java 8
}
Expand All @@ -324,6 +361,10 @@ subprojects {
}

tasks.jar {
if (mcVersion >= 260100) {
archiveClassifier.set("raw")
}

from("LICENSE") {
rename { "${it}_${base.archivesName.get()}" }
}
Expand Down Expand Up @@ -398,6 +439,9 @@ publishMods {
embeds {
slug = "jankson"
}

client.set(true) // Mostly for Recipe Viewer
server.set(true)
}
}

Expand Down
36 changes: 36 additions & 0 deletions buildSrc/src/main/kotlin/ProcessAWAT.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import java.io.File
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive

fun File.processAW(
mcVersion: Int,
) {
val content = buildString {
val mappingType = if (mcVersion >= 260100) "official" else "named"
appendLine("classTweaker v1 ${mappingType}")

appendLine("accessible class net/minecraft/resources/RegistryDataLoader\$Loader")

val structureProviderName = if (mcVersion >= 260100) "\$Provider" else "\$Source"
appendLine("accessible class net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplateManager$structureProviderName")
appendLine("accessible method net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplateManager$structureProviderName <init> (Ljava/util/function/Function;Ljava/util/function/Supplier;)V")
}
writeText(content)
}

fun File.processAT(
mcVersion: Int,
) {
val content = buildString {
appendLine("public net.minecraft.resources.RegistryDataLoader\$Loader")

val structureProviderName = if (mcVersion >= 260100) "\$Provider" else "\$Source"
appendLine("public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager$structureProviderName")
appendLine("public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager$structureProviderName <init>(Ljava/util/function/Function;Ljava/util/function/Supplier;)V")
}
writeText(content)
}
3 changes: 2 additions & 1 deletion buildSrc/src/main/kotlin/VersionRange.kt
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ fun supportedVersionRange(mcVersion: Int, loader: String): VersionRange {
in 12100..12101 -> VersionRange("1.20.x", "1.21.1")
in 12102..12104 -> VersionRange("1.21.1", "1.21.4")
in 12105..12110 -> VersionRange("1.21.4", "1.21.10")
12111 -> VersionRange("1.21.10", null)
12111 -> VersionRange("1.21.10", "1.21.11")
260100 -> VersionRange("1.21.11", null)
else -> VersionRange(null, null)
}
}
Expand Down
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/dependencies/Create.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ fun createMod(isNeo: Boolean) = Dependency(
group = "com.simibubi.create",
// Create finally support Neo on 1.21.1
name = "create" + (if (!isNeo) "-1.18.2" else "-1.21.1"),
version = { mcVersion, hotfix ->
version = { mcVersion ->
val version = if (!isNeo) "0.5.1.e-318" else "6.0.4-59"
return@Dependency "$version:slim"
},
Expand Down
36 changes: 26 additions & 10 deletions buildSrc/src/main/kotlin/dependencies/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,42 @@ package dependencies
data class Dependency(
private val group: String,
private val name: String,
private val version: (Int, Int) -> String,
private val version: (Int) -> String,
) {
fun versioned(mcVersion: Int, mcBuild: Int): String = "${group}:${name}:${version(mcVersion, mcBuild)}"
fun versioned(mcVersion: Int): String = "${group}:${name}:${version(mcVersion)}"
}

fun versionStr(versionCode: Int, hotfix: Int = 0, alwaysShowHotfix: Boolean = false): String {
fun legacyVersionStr(versionCode: Int): String {
val versionCodeStr = versionCode.toString()
val major = versionCodeStr.getOrNull(0)?.toString() ?: "0"
val minor = versionCodeStr
.substring(1, 3 + (versionCodeStr.length - 5)) // Future proofing, in case "1.100.0" happened
.substring(1, 3)
.padStart(2, '0')
.trimStart('0')
val patch = versionCodeStr
.substring(3 + (versionCodeStr.length - 5))
.substring(3)
.padEnd(1, '0').trimStart('0')

if (patch.isEmpty()) return "$major.$minor"
return "$major.$minor.$patch"
}

/**
* Transform version code (e.g. 260100) back to formatted string (e.g. 26.01).
*/
fun versionStr(versionCode: Int, alwaysShowHotfix: Boolean = false): String {
val versionCodeStr = versionCode.toString()
if (versionCodeStr.length == 5) return legacyVersionStr(versionCode)

if (major.toInt() <= 1) {
if (patch.isEmpty()) return "$major.$minor"
return "$major.$minor.$patch"
}
val year = versionCodeStr.substring(0, 2)
val release = versionCodeStr
.substring(2, 4)
.trimStart('0')
.let { if (it == "") "0" else it }
val hotfix = versionCodeStr
.substring(4)
.trimStart('0')
.let { if (it == "" && alwaysShowHotfix) "0" else it }

return if (hotfix > 0 || alwaysShowHotfix) "$minor.$patch.$hotfix" else "$minor.$patch"
return if (hotfix != "") "$year.$release.$hotfix" else "$year.$release"
}
11 changes: 7 additions & 4 deletions buildSrc/src/main/kotlin/dependencies/FabricAPI.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package dependencies
val fapi = Dependency(
group = "net.fabricmc.fabric-api",
name = "fabric-api",
version = { mcVersion, hotfix ->
version = { mcVersion ->
when (mcVersion) {
11605 -> "0.42.0+1.16"
11802 -> "0.76.0+1.18.2"
Expand All @@ -16,6 +16,7 @@ val fapi = Dependency(
in 12102..12104 -> "0.106.1+1.21.3"
in 12105..12110 -> "0.119.9+1.21.5"
12111 -> "0.139.5+1.21.11"
260100 -> "0.141.1+26.1"
else -> throw IllegalStateException("$mcVersion is not yet supported!")
}
},
Expand All @@ -24,9 +25,11 @@ val fapi = Dependency(
val fapiGameTest = Dependency(
group = "net.fabricmc.fabric-api",
name = "fabric-gametest-api-v1",
version = { mcVersion, hotfix ->
version = { mcVersion ->
when (mcVersion) {
12105 -> "3.1.2+2a6ec84b49"
in 12105..12110 -> "3.1.2+2a6ec84b49"
12111 -> "3.1.27+4fc5413f3e"
260100 -> "4.0.0+574290bac9"
else -> throw IllegalStateException("$mcVersion is not yet supported!")
}
},
Expand All @@ -35,7 +38,7 @@ val fapiGameTest = Dependency(
val fapiResourceLoader = Dependency(
group = "net.fabricmc.fabric-api",
name = "fabric-resource-loader-v0",
version = { mcVersion, hotfix ->
version = { mcVersion ->
when (mcVersion) {
12105 -> "3.1.6+02ca679649"
else -> throw IllegalStateException("$mcVersion is not yet supported!")
Expand Down
Loading
Loading