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

@@ -23,6 +23,7 @@ import static art.arcane.iris.testsupport.PackCompatFixtures.find;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -132,6 +133,133 @@ public class IrisRegionCompatPoolTest {
assertFalse(region.evaluateCompat(gate(report)).excluded());
}
@Test
public void evaluateCompatExcludesRegionWithNoShoreBiomesLeft() {
PackCompatReport report = new PackCompatReport();
IrisBiome plains = biome("land/plains");
IrisBiome beach = PackCompatFixtures.exclude(biome("swamp/shore/beach"),
CompatRegistry.BLOCK, "minecraft:firefly_bush");
IrisData data = dataWith(report, plains, beach);
IrisRegion region = PackCompatFixtures.region("swamp");
region.setLoader(data);
region.setLandBiomes(new KList<>("land/plains"));
region.setShoreBiomes(new KList<>("swamp/shore/beach"));
CompatStatus status = region.evaluateCompat(gate(report));
assertTrue(status.excluded());
assertSame(plains, region.getRealLandBiomes(() -> data).getFirst());
CompatFinding cascade = find(report, CompatAction.EXCLUDED, "region", "swamp");
assertNotNull(cascade);
assertEquals("minecraft:firefly_bush", cascade.key());
assertEquals("no shore biomes remain", cascade.detail());
CompatFinding dropped = find(report, CompatAction.DROPPED, "region", "swamp");
assertNotNull(dropped);
assertEquals("shoreBiomes[0] swamp/shore/beach", dropped.detail());
}
@Test
public void evaluateCompatExcludesRegionWithNoSeaBiomesLeft() {
PackCompatReport report = new PackCompatReport();
IrisBiome plains = biome("land/plains");
IrisBiome sea = excludeBlock(biome("sea/sulfur"));
IrisData data = dataWith(report, plains, sea);
IrisRegion region = PackCompatFixtures.region("overworld");
region.setLoader(data);
region.setLandBiomes(new KList<>("land/plains"));
region.setSeaBiomes(new KList<>("sea/sulfur"));
assertTrue(region.evaluateCompat(gate(report)).excluded());
CompatFinding cascade = find(report, CompatAction.EXCLUDED, "region", "overworld");
assertNotNull(cascade);
assertEquals(MISSING_BLOCK, cascade.key());
assertEquals("no sea biomes remain", cascade.detail());
}
@Test
public void evaluateCompatPreservesSurvivingSurfacePoolOrder() {
PackCompatReport report = new PackCompatReport();
IrisBiome plains = biome("land/plains");
IrisBiome sea = biome("sea/ocean");
IrisBiome sand = biome("shore/sand");
IrisBiome gravel = biome("shore/gravel");
IrisBiome sulfur = excludeBlock(biome("shore/sulfur"));
IrisData data = dataWith(report, plains, sea, sand, gravel, sulfur);
IrisRegion region = PackCompatFixtures.region("overworld");
region.setLoader(data);
region.setLandBiomes(new KList<>("land/plains"));
region.setSeaBiomes(new KList<>("shore/sulfur", "sea/ocean"));
region.setShoreBiomes(new KList<>("shore/sand", "shore/sulfur", "shore/gravel"));
assertFalse(region.evaluateCompat(gate(report)).excluded());
KList<IrisBiome> shores = region.getRealShoreBiomes(() -> data);
assertEquals(2, shores.size());
assertSame(sand, shores.get(0));
assertSame(gravel, shores.get(1));
assertSame(sea, region.getRealSeaBiomes(() -> data).getFirst());
}
@Test
public void evaluateCompatAllowsOmittedSurfacePoolsAndDepletedCavePool() {
PackCompatReport report = new PackCompatReport();
IrisBiome plains = biome("land/plains");
IrisBiome sulfur = excludeBlock(biome("cave/sulfur"));
IrisData data = dataWith(report, plains, sulfur);
IrisRegion region = PackCompatFixtures.region("highlands");
region.setLoader(data);
region.setLandBiomes(new KList<>("land/plains"));
region.setCaveBiomes(new KList<>("cave/sulfur"));
assertFalse(region.evaluateCompat(gate(report)).excluded());
assertTrue(region.getRealSeaBiomes(() -> data).isEmpty());
assertTrue(region.getRealShoreBiomes(() -> data).isEmpty());
assertTrue(region.getRealCaveBiomes(() -> data).isEmpty());
}
@Test
public void evaluateCompatDoesNotMisattributeUnresolvedShorePoolToLandDrop() {
PackCompatReport report = new PackCompatReport();
IrisBiome plains = biome("land/plains");
IrisBiome sulfur = excludeBlock(biome("land/sulfur"));
IrisData data = dataWith(report, plains, sulfur);
IrisRegion region = PackCompatFixtures.region("overworld");
region.setLoader(data);
region.setLandBiomes(new KList<>("land/plains", "land/sulfur"));
region.setShoreBiomes(new KList<>("shore/missing"));
assertFalse(region.evaluateCompat(gate(report)).excluded());
}
@Test
@SuppressWarnings("unchecked")
public void dimensionDropsRegionWhoseDeclaredShorePoolWasExcluded() {
PackCompatReport report = new PackCompatReport();
IrisBiome plains = biome("land/plains");
IrisBiome beach = excludeBlock(biome("shore/sulfur"));
IrisData data = dataWith(report, plains, beach);
IrisRegion swamp = PackCompatFixtures.region("swamp");
swamp.setLoader(data);
swamp.setLandBiomes(new KList<>("land/plains"));
swamp.setShoreBiomes(new KList<>("shore/sulfur"));
swamp.setCompat(swamp.evaluateCompat(gate(report)));
IrisRegion highlands = PackCompatFixtures.region("highlands");
ResourceLoader<IrisRegion> regions = mock(ResourceLoader.class);
when(data.getRegionLoader()).thenReturn(regions);
when(regions.load("swamp")).thenReturn(swamp);
when(regions.load("highlands")).thenReturn(highlands);
IrisDimension dimension = new IrisDimension().setRegions(new KList<>("swamp", "highlands"));
dimension.setLoadKey("overworld");
dimension.setLoader(data);
assertFalse(dimension.evaluateCompat(gate(report)).excluded());
KList<IrisRegion> surviving = dimension.getAllRegions(() -> data);
assertEquals(1, surviving.size());
assertSame(highlands, surviving.getFirst());
CompatFinding drop = find(report, CompatAction.DROPPED, "dimension", "overworld");
assertNotNull(drop);
assertEquals("regions[0] swamp", drop.detail());
}
@Test
public void evaluateCompatDoesNotExcludeRegionThatNeverDeclaredLandBiomes() {
PackCompatReport report = new PackCompatReport();
@@ -71,7 +71,15 @@ public class BuiltInPackUpdatesTest {
@Test
public void boundsReleaseMetadataSize() throws Exception {
assertEquals(BuiltInPackUpdates.Update.unavailable(), checkResponse(" ".repeat(1024 * 1024 + 1)));
String release = release("4010", "overworld.zip", false);
assertEquals(BuiltInPackUpdates.Update.unavailable(),
checkResponse(release + " ".repeat(1024 * 1024 - release.length() + 1)));
}
@Test
public void acceptsReleaseMetadataAtSizeLimit() throws Exception {
String release = release("4010", "overworld.zip", false);
assertEquals("4010", checkResponse(release + " ".repeat(1024 * 1024 - release.length())).version());
}
@Test
@@ -58,7 +58,7 @@ public class DefaultPackBootstrapProvisionerTest {
Path dataDirectory = root.resolve("plugins/Iris");
writePack(dataDirectory.resolve("packs/overworld"), "overworld", "runtime");
BukkitStartupPaths startupPaths = BukkitStartupPaths.resolve(root, new String[0]);
for (DataVersion version : new DataVersion[]{DataVersion.V26_1_2, DataVersion.V26_2, DataVersion.V26_3}) {
for (DataVersion version : new DataVersion[]{DataVersion.V1_21_1, DataVersion.V26_1_2, DataVersion.V26_2, DataVersion.V26_3}) {
DefaultPackBootstrapProvisioner.ProvisionResult result = DefaultPackBootstrapProvisioner.provision(
new DefaultPackBootstrapProvisioner.BootstrapRequest(dataDirectory, ignored -> {}, startupPaths, version));
Path biomeRoot = result.datapackRoot().resolve("data/iris/worldgen/biome/biomes");
@@ -9,6 +9,7 @@ import static org.junit.Assert.assertSame;
public class DataVersionTest {
@Test
public void runtimeSelectionPreservesEverySupportedVersion() {
assertSame(DataVersion.V1_21_1, DataVersion.forMinecraftVersion("1.21.1"));
assertSame(DataVersion.V26_1_2, DataVersion.forMinecraftVersion("26.1.2"));
assertSame(DataVersion.V26_2, DataVersion.forMinecraftVersion("26.2"));
assertSame(DataVersion.V26_2, DataVersion.forMinecraftVersion("26.2.0"));
@@ -24,6 +25,7 @@ public class DataVersionTest {
@Test
public void packFormatsMatchServerVersionJson() {
assertEquals(48, DataVersion.V1_21_1.getPackFormat());
assertEquals(101, DataVersion.V26_1_2.getPackFormat());
assertEquals(107, DataVersion.V26_2.getPackFormat());
assertEquals(121, DataVersion.V26_3.getPackFormat());
@@ -31,7 +33,7 @@ public class DataVersionTest {
@Test
public void minSupportedPackFormatIsTheOldestSupportedRuntime() {
assertEquals(101, DataVersion.minSupportedPackFormat());
assertEquals(48, DataVersion.minSupportedPackFormat());
}
@Test
@@ -142,6 +142,47 @@ public class VanillaJigsawDatapackExporterTest {
assertEquals("north_up", paletteEntry.getCompoundTag("Properties").getString("orientation"));
}
@Test
public void exports1211RuntimeBlockStatesAndPackFormat() throws Exception {
when(IrisPlatforms.get().minecraftVersion()).thenReturn("1.21.1");
try {
TestGraph graph = connectorGraph();
Path output = temporaryFolder.getRoot().toPath().resolve("village-1211");
VanillaJigsawExportSettings settings = VanillaJigsawExportSettings.builder()
.maxDistanceVertical(graph.structure.getMaxSizeChunks() * 16).build();
VanillaJigsawExportResult result = new VanillaJigsawDatapackExporter().export(
request(graph, output).namespace("studio").resourcePath("village/test").settings(settings).build());
assertTrue(result.diagnostics().toString(), result.isSuccess());
JsonObject pack = json(output.resolve("pack.mcmeta")).getAsJsonObject("pack");
assertEquals(48, pack.get("pack_format").getAsInt());
JsonObject structure = json(output.resolve("data/studio/worldgen/structure/village/test.json"));
assertTrue(structure.get("max_distance_from_center").isJsonPrimitive());
CompoundTag template = (CompoundTag) NBTUtil.read(output.resolve(
"data/studio/structure/village/test/piece/pieces/start.nbt").toFile()).getTag();
assertEquals(3955, template.getInt("DataVersion"));
CompoundTag palette = (CompoundTag) template.getListTag("palette").get(0);
assertEquals("minecraft:jigsaw", palette.getString("Name"));
} finally {
when(IrisPlatforms.get().minecraftVersion()).thenReturn("26.2");
}
}
@Test
public void rejects1211VanillaExportWithDifferentVerticalDistance() throws Exception {
when(IrisPlatforms.get().minecraftVersion()).thenReturn("1.21.1");
try {
Path output = temporaryFolder.getRoot().toPath().resolve("unequal-1211");
VanillaJigsawExportResult result = new VanillaJigsawDatapackExporter().export(
request(connectorGraph(), output).settings(VanillaJigsawExportSettings.builder()
.maxDistanceVertical(127).build()).build());
assertFalse(result.isSuccess());
assertTrue(result.diagnostics().stream().anyMatch(diagnostic ->
diagnostic.code() == VanillaJigsawExportDiagnostic.Code.INVALID_MAX_DISTANCE));
} finally {
when(IrisPlatforms.get().minecraftVersion()).thenReturn("26.2");
}
}
@Test
public void exports26_3RuntimeBlockStatesAndPackFormat() throws Exception {
when(IrisPlatforms.get().minecraftVersion()).thenReturn("26.3.0");