Added 1.21.1 mod targets

- Build Fabric, Forge and NeoForge per target listed in gradle/mod-targets.json (1.21.1, 26.3)
- Add 1.21.1 adapter source overlays under adapters/*/src/versions/1.21.1
- Add verifyModdedMatrix and per-target Java runtime verification of loader jars
- Re-inject persistent dimensions from the levels-ready hook before the watchdog starts
- Wait for queued chunks and the final save before pregen completes
- Add the 1.21.1 data version and datapack supported_formats range
- Cascade regions whose sea or shore pool loses every biome
- Use Gson calls available on the 1.21.1 runtime
This commit is contained in:
Brian Neumann-Fopiano committed 2026-10-16 10:25:19 -04:00
1 parent 0ca33068f3
commit 62062c4a95
58 files changed
+3279 -133

No files matched your search

+15
View File
@@ -0,0 +1,15 @@
import groovy.json.JsonSlurper
File irisDirectory = project.name.startsWith('iris-') ? file('../..') : rootDir
String targetMinecraft = providers.gradleProperty('minecraftVersion').getOrElse('26.3')
Map<String, Map<String, Object>> targets = (Map<String, Map<String, Object>>) new JsonSlurper()
.parse(new File(irisDirectory, 'gradle/mod-targets.json'))
Map<String, Object> target = targets.get(targetMinecraft)
if (target == null) {
throw new GradleException("Unsupported Iris mod target ${targetMinecraft}; choose ${targets.keySet().join(', ')}")
}
ext.irisModTarget = target
ext.irisModTargets = targets
if (project.name.startsWith('iris-')) {
layout.buildDirectory.set(layout.projectDirectory.dir("build/${targetMinecraft}"))
}
+32
View File
@@ -0,0 +1,32 @@
{
"1.21.1": {
"java": 21,
"fabricRemap": true,
"fabricLoader": "0.19.5",
"forge": "1.21.1-52.1.20",
"neoForge": "21.1.262",
"nativeAccess": "minecraft1_21_1",
"fabricModules": {
"fabric-api-base": "0.4.42+6573ed8c19",
"fabric-registry-sync-v0": "5.3.2+e3eddc2119",
"fabric-resource-loader-v0": "1.3.1+5b5275af19",
"fabric-lifecycle-events-v1": "2.6.0+0865547519",
"fabric-command-api-v2": "2.2.28+6ced4dd919",
"fabric-events-interaction-v0": "0.7.14+ba9dae0619",
"fabric-networking-api-v1": "4.3.1+d30f6a7919",
"fabric-rendering-v1": "5.2.1+f44c2eea19",
"fabric-key-binding-api-v1": "1.0.47+0af3f5a719"
},
"fabricPermissions": "0.3.1",
"slf4j": "2.0.9"
},
"26.3": {
"java": 25,
"fabricRemap": false,
"fabricLoader": "0.19.5",
"forge": "26.3-66.0.8",
"neoForge": "26.3.0.33-beta",
"nativeAccess": "minecraft26_2",
"slf4j": "2.0.17"
}
}
@@ -18,7 +18,8 @@ TaskProvider<JavaExec> resolvedRevisionVerification = tasks.register('verifyReso
classpath = files('../../buildSrc/build/libs/buildSrc.jar')
mainClass.set('art.arcane.iris.buildtools.GenerationBuildRevision')
doFirst {
List<String> arguments = ['verify-dependencies', file('../../core/build/generated/generation-revision/META-INF/iris/generation-kernels/abi-1.revision').absolutePath]
String runtimeVariant = providers.gradleProperty('irisRuntimeJava').getOrElse(irisModTarget.java.toString()) == '21' ? 'java21/' : ''
List<String> arguments = ['verify-dependencies', file("../../core/build/${runtimeVariant}generated/generation-revision/META-INF/iris/generation-kernels/abi-1.revision").absolutePath]
for (ResolvedArtifact artifact : configurations.bundle.resolvedConfiguration.resolvedArtifacts) {
String group = artifact.moduleVersion.id.group
String name = artifact.moduleVersion.id.name
+80
View File
@@ -0,0 +1,80 @@
import groovy.json.JsonSlurper
String sourceMinecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse('26.3')
List<File> adapterSourceRoots = [projectDir, file('../modded-common'), file('../client-common')]
tasks.named('compileTestJava', JavaCompile).configure {
options.release.set((int) irisModTarget.java)
}
tasks.withType(Test).configureEach {
javaLauncher.set(javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of((int) irisModTarget.java)
})
}
['java', 'resources'].each { String kind ->
List<File> overlays = adapterSourceRoots.collect { File adapter ->
new File(adapter, "src/versions/${sourceMinecraftVersion}/${kind}")
}
if (!overlays.any { File directory -> directory.isDirectory() }) {
return
}
TaskProvider<Sync> prepareSources = tasks.register("prepareVersion${kind.capitalize()}", Sync) {
adapterSourceRoots.each { File adapter ->
File overlay = new File(adapter, "src/versions/${sourceMinecraftVersion}/${kind}")
from(new File(adapter, "src/main/${kind}")) {
exclude { FileTreeElement entry -> new File(overlay, entry.path).isFile() }
}
from(overlay)
}
includeEmptyDirs = false
into(layout.buildDirectory.dir("generated/sources/iris/${kind}"))
}
Set<File> replacedRoots = adapterSourceRoots.collect { File adapter ->
new File(adapter, "src/main/${kind}").canonicalFile
}.toSet()
List<Object> retainedRoots = sourceSets.main."${kind}".srcDirs.findAll { File source ->
!replacedRoots.contains(source.canonicalFile)
}.toList()
sourceSets.main."${kind}".setSrcDirs(retainedRoots + [prepareSources])
tasks.named('verifyLoggingPolicy').configure { dependsOn(prepareSources) }
tasks.named('verifyNativeBoundary').configure { dependsOn(prepareSources) }
}
File testRulesFile = file("../modded-common/src/versions/${sourceMinecraftVersion}/test/source-replacements.json")
if (testRulesFile.isFile()) {
Map<String, Object> testRules = (Map<String, Object>) new JsonSlurper().parse(testRulesFile)
TaskProvider<Sync> prepareTests = tasks.register('prepareVersionTests', Sync) {
inputs.file(testRulesFile)
adapterSourceRoots.each { File adapter ->
File overlay = new File(adapter, "src/versions/${sourceMinecraftVersion}/test/java")
from(new File(adapter, 'src/test/java')) {
exclude { FileTreeElement entry -> new File(overlay, entry.path).isFile() }
}
from(overlay)
}
includeEmptyDirs = false
into(layout.buildDirectory.dir('generated/sources/iris/test'))
doLast {
List<Map<String, String>> rules = (List<Map<String, String>>) (testRules.get('global') ?: [])
Map<String, List<Map<String, String>>> fileRules = (Map<String, List<Map<String, String>>>) (testRules.get('files') ?: [:])
project.fileTree(destinationDir).matching { include('**/*.java') }.each { File source ->
String path = destinationDir.toPath().relativize(source.toPath()).toString().replace(File.separator, '/')
boolean overridden = adapterSourceRoots.any { File adapter ->
new File(adapter, "src/versions/${sourceMinecraftVersion}/test/java/${path}").isFile()
}
if (!overridden) {
String content = source.getText('UTF-8')
String rewritten = content
for (Map<String, String> rule : rules + (fileRules.get(path) ?: [])) {
rewritten = rewritten.replaceAll(rule.pattern, rule.replacement)
}
if (content != rewritten) {
source.setText(rewritten, 'UTF-8')
}
}
}
}
}
sourceSets.test.java.setSrcDirs([prepareTests])
}
+59 -11
View File
@@ -1,3 +1,6 @@
import groovy.json.JsonSlurper
import java.util.zip.ZipFile
Configuration nativeMinecraftSources = configurations.create('nativeMinecraftSources') {
canBeConsumed = false
canBeResolved = true
@@ -6,41 +9,86 @@ Configuration nativeMinecraftSources = configurations.create('nativeMinecraftSou
String nativeSourceLoader = extensions.extraProperties.get('nativeSourceLoader')
String nativeSourceImplementation = 'minecraft26_2'
String nativeSourceMinecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse('26.3')
String versionPrefix = "versions/${nativeSourceMinecraftVersion}/"
extensions.extraProperties.set('nativeSourceImplementation', nativeSourceImplementation)
dependencies.add(nativeMinecraftSources.name,
"com.github.VolmitSoftware.VolmLib:native-${nativeSourceImplementation}-sources:master-SNAPSHOT")
Set<String> overrides = new HashSet<>()
Map<String, Object> replacements = [:]
TaskProvider<Sync> unpackNativeMinecraftSources = tasks.register('unpackNativeMinecraftSources', Sync) {
dependsOn(nativeMinecraftSources)
from(provider { nativeMinecraftSources.collect { File artifact -> zipTree(artifact) } }) {
include('art/**', 'modded/**', "${nativeSourceLoader}/**",
'resources/modded/**', "resources/${nativeSourceLoader}/**", "versions/${nativeSourceMinecraftVersion}/**")
eachFile { FileCopyDetails source ->
String versionPrefix = "versions/${nativeSourceMinecraftVersion}/"
if (source.path.startsWith(versionPrefix)) {
source.path = source.path.substring(versionPrefix.length())
inputs.property('minecraftVersion', nativeSourceMinecraftVersion)
inputs.property('loader', nativeSourceLoader)
doFirst {
overrides.clear()
for (File artifact : nativeMinecraftSources) {
new ZipFile(artifact).withCloseable { ZipFile archive ->
archive.entries().each { entry ->
if (entry.name.startsWith(versionPrefix)) {
overrides.add(entry.name.substring(versionPrefix.length()))
}
}
java.util.zip.ZipEntry rules = archive.getEntry(versionPrefix + 'source-replacements.json')
if (rules != null) {
archive.getInputStream(rules).withCloseable { InputStream stream ->
replacements = (Map<String, Object>) new JsonSlurper().parse(stream)
}
}
}
}
}
from(provider { nativeMinecraftSources.collect { File artifact -> zipTree(artifact) } }) {
include('art/**', 'modded/**', "${nativeSourceLoader}/**",
'resources/modded/**', "resources/${nativeSourceLoader}/**")
eachFile { FileCopyDetails source ->
if (overrides.contains(source.path)) {
source.exclude()
}
}
}
from(provider { nativeMinecraftSources.collect { File artifact -> zipTree(artifact) } }) {
include("${versionPrefix}art/**", "${versionPrefix}modded/**", "${versionPrefix}${nativeSourceLoader}/**",
"${versionPrefix}resources/modded/**", "${versionPrefix}resources/${nativeSourceLoader}/**")
eachFile { FileCopyDetails source -> source.path = source.path.substring(versionPrefix.length()) }
}
includeEmptyDirs = false
into(layout.buildDirectory.dir('generated/sources/native-minecraft'))
doLast {
List<Map<String, String>> rules = (List<Map<String, String>>) (replacements.get('global') ?: [])
Map<String, List<Map<String, String>>> fileRules = (Map<String, List<Map<String, String>>>) (replacements.get('files') ?: [:])
project.fileTree(destinationDir).matching { include('**/*.java') }.each { File source ->
String path = destinationDir.toPath().relativize(source.toPath()).toString().replace(File.separator, '/')
if (!overrides.contains(path)) {
String content = source.getText('UTF-8')
String rewritten = content
for (Map<String, String> rule : rules + (fileRules.get(path) ?: [])) {
rewritten = rewritten.replaceAll(rule.pattern, rule.replacement)
}
if (content != rewritten) {
source.setText(rewritten, 'UTF-8')
}
}
}
}
}
sourceSets.main.java.srcDir(unpackNativeMinecraftSources)
tasks.named('compileJava').configure { dependsOn(unpackNativeMinecraftSources) }
sourceSets.main.resources.srcDir(layout.buildDirectory.dir('generated/sources/native-minecraft/resources/modded'))
sourceSets.main.resources.srcDir(layout.buildDirectory.dir("generated/sources/native-minecraft/resources/${nativeSourceLoader}"))
tasks.named('processResources').configure {
dependsOn(unpackNativeMinecraftSources)
}
tasks.named('verifyLoggingPolicy').configure {
dependsOn(unpackNativeMinecraftSources)
}
tasks.named('verifyNativeBoundary').configure {
dependsOn(unpackNativeMinecraftSources)
}
tasks.named('verifyNativeClassBoundary').configure {
dependsOn(tasks.named('classes'))
}
tasks.matching { Task task -> task.name == 'createMinecraftArtifacts' }.configureEach {
dependsOn(unpackNativeMinecraftSources)
}