Merged platform diet

- Per-chunk biome stage resolver, subterrain candidate gate, section-walk heightmaps, reused history compressors

# Conflicts:
#	core/src/main/java/art/arcane/iris/generation/runtime/Engine.java
This commit is contained in:
Brian Neumann-Fopiano committed 2026-10-22 11:29:26 -04:00
commit c62a31e16b
14 files changed
+554 -149

No files matched your search

@@ -0,0 +1,111 @@
package art.arcane.iris.platform.bukkit.nms;
import art.arcane.iris.generation.biome.IrisBiome;
import art.arcane.iris.generation.biome.IrisBiomeCustom;
import art.arcane.iris.generation.mantle.EngineMantle;
import art.arcane.iris.generation.runtime.Engine;
import art.arcane.iris.generation.runtime.GenerationSessionLease;
import art.arcane.iris.generation.runtime.IrisComplex;
import art.arcane.iris.generation.runtime.IrisEngine;
import art.arcane.iris.generation.terrain.IrisDimension;
import art.arcane.iris.generation.terrain.IrisDimensionCarvingResolver;
import art.arcane.iris.pack.loading.IrisData;
import art.arcane.iris.world.IrisWorld;
import art.arcane.volmlib.nativelib.terrain.NativeBiomeRegistry;
import art.arcane.volmlib.nativelib.terrain.NativeBiomeSourcePolicy;
import art.arcane.volmlib.util.collection.KList;
import org.junit.Test;
import java.lang.reflect.Field;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import static org.junit.Assert.assertEquals;
import static org.mockito.Answers.CALLS_REAL_METHODS;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class BukkitBiomeVisibleResolverTest {
@Test
public void chunkResolverMatchesThePerQuartResolution() throws Exception {
IrisBiome surface = customBiome("surface", "meadow");
IrisBiome cave = customBiome("cave", "grotto");
IrisBiome custom = customBiome("custom", "mirage");
IrisBiome feature = customBiome("feature", "bloom");
IrisDimension dimension = mock(IrisDimension.class);
when(dimension.getReachableBiomes(any())).thenReturn(new KList<>(surface, cave, custom, feature));
when(dimension.getCustomBiomeKey(anyString())).thenAnswer(invocation -> "pack:" + invocation.getArgument(0));
IrisData data = mock(IrisData.class);
when(data.customBiomeResourceKey(any(IrisDimension.class), anyString()))
.thenAnswer(invocation -> "pack:" + invocation.getArgument(1));
IrisComplex complex = mock(IrisComplex.class);
when(complex.historicalPhysicalBiomeKeyAt(anyInt(), anyInt(), anyInt())).thenReturn(Optional.empty());
EngineMantle mantle = mock(EngineMantle.class);
when(mantle.trueHeight(anyInt(), anyInt())).thenAnswer(invocation ->
120 + Math.floorMod(invocation.<Integer>getArgument(0) * 7 + invocation.<Integer>getArgument(1) * 3, 160));
IrisEngine engine = mock(IrisEngine.class);
when(engine.getDimension()).thenReturn(dimension);
when(engine.getData()).thenReturn(data);
when(engine.getComplex()).thenReturn(complex);
when(engine.getMantle()).thenReturn(mantle);
when(engine.getWorld()).thenReturn(IrisWorld.builder().minHeight(-64).maxHeight(320).build());
when(engine.getMinHeight()).thenReturn(-64);
when(engine.getCacheID()).thenReturn(1);
when(engine.acquireGenerationLease(anyString())).thenReturn(GenerationSessionLease.noop());
when(engine.answersFromNaturalTerrain(anyInt(), anyInt())).thenReturn(false);
when(engine.getHostSurfaceBiome(anyInt(), anyInt())).thenAnswer(invocation ->
Math.floorMod(invocation.<Integer>getArgument(0) + invocation.<Integer>getArgument(1), 8) == 0 ? custom : surface);
when(engine.getCaveBiome(anyInt(), anyInt(), anyInt(), any(IrisDimensionCarvingResolver.State.class)))
.thenAnswer(invocation -> invocation.<Integer>getArgument(1) % 3 == 0 ? custom : cave);
when(engine.getSubterrainBiome(anyInt(), anyInt(), anyInt())).thenAnswer(invocation ->
invocation.<Integer>getArgument(0) == 4 && invocation.<Integer>getArgument(1) == 40 ? feature : null);
when(engine.subterrainAbsentInChunk(1, 0)).thenReturn(true);
@SuppressWarnings("unchecked")
NativeBiomeRegistry<String, String> registry = mock(NativeBiomeRegistry.class);
when(registry.lookupCustom(anyString())).thenAnswer(invocation -> invocation.getArgument(0));
BukkitBiomePolicy<String, String> policy = policy(engine, registry, "fallback");
for (int chunkX = 0; chunkX <= 1; chunkX++) {
NativeBiomeSourcePolicy.VisibleResolver<String> resolver = policy.visibleResolver();
for (int quartY = -16; quartY < 80; quartY++) {
for (int localX = 0; localX < 4; localX++) {
for (int localZ = 0; localZ < 4; localZ++) {
int quartX = (chunkX << 2) + localX;
String expected = policy.getVisibleNoiseBiomeWithActiveGenerationLease(
quartX, quartY, localZ, new IrisDimensionCarvingResolver.State());
assertEquals("quart " + quartX + "," + quartY + "," + localZ, expected,
resolver.biome(quartX, quartY, localZ));
}
}
}
}
}
private static IrisBiome customBiome(String key, String customId) {
IrisBiome biome = new IrisBiome().setCustomDerivitives(new KList<>(new IrisBiomeCustom().setId(customId)));
biome.setLoadKey(key);
return biome;
}
@SuppressWarnings("unchecked")
private static BukkitBiomePolicy<String, String> policy(Engine engine, NativeBiomeRegistry<String, String> registry,
String fallback) throws Exception {
BukkitBiomePolicy<String, String> policy = mock(BukkitBiomePolicy.class, CALLS_REAL_METHODS);
set(policy, "engine", engine);
set(policy, "biomeCustomRegistry", registry);
set(policy, "biomeRegistry", registry);
set(policy, "fallbackBiome", fallback);
set(policy, "runtimeBiomeStates", new ConcurrentHashMap<>());
set(policy, "noiseBiomeCache", new ConcurrentHashMap<>());
return policy;
}
private static void set(Object target, String name, Object value) throws Exception {
Field field = BukkitBiomePolicy.class.getDeclaredField(name);
field.setAccessible(true);
field.set(target, value);
}
}
@@ -36,10 +36,12 @@ public class BukkitSubterrainBiomePrecedenceTest {
owner.setAccessible(true);
owner.set(policy, engine);
DimensionStackLayout stack = mock(DimensionStackLayout.class);
Class<?> chunkResolution = Class.forName(BukkitBiomePolicy.class.getName() + "$ChunkResolution");
Method resolve = BukkitBiomePolicy.class.getDeclaredMethod("resolveBiomeResolution", int.class, int.class,
int.class, IrisDimensionCarvingResolver.State.class, boolean.class, DimensionStackLayout.class);
int.class, IrisDimensionCarvingResolver.State.class, boolean.class, DimensionStackLayout.class,
chunkResolution);
resolve.setAccessible(true);
Object resolved = resolve.invoke(policy, 3, 40, -5, null, true, stack);
Object resolved = resolve.invoke(policy, 3, 40, -5, null, true, stack, null);
assertSame(feature, field(resolved, "irisBiome"));
assertSame(host, field(resolved, "dimension"));
assertEquals(true, field(resolved, "underground"));
@@ -0,0 +1,69 @@
package art.arcane.iris.structure.nativegen;
import art.arcane.iris.generation.runtime.Engine;
import art.arcane.volmlib.nativelib.terrain.structure.NativeStructureVolume;
import art.arcane.volmlib.util.collection.KList;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class NativeStructureVolumeIndexCacheTest {
@Test
public void concurrentQueriesBuildEachOriginOnceAndAnswerIdentically() throws Exception {
Map<Long, AtomicInteger> builds = new ConcurrentHashMap<>();
NativeStructureVolumeIndex index = NativeStructureVolumeIndex.forTesting((engine, chunkX, chunkZ) -> {
builds.computeIfAbsent(((long) chunkX << 32) ^ (chunkZ & 0xffffffffL), key -> new AtomicInteger()).incrementAndGet();
return volumesAt(chunkX, chunkZ);
});
Engine engine = mock(Engine.class);
when(engine.getCacheID()).thenReturn(7);
KList<NativeStructureVolume> expected = NativeStructureVolumeIndex.forTesting(
(ignored, chunkX, chunkZ) -> volumesAt(chunkX, chunkZ)).resolve(engine, 0, 0, 47, 47);
ExecutorService pool = Executors.newFixedThreadPool(8);
try {
List<Future<KList<NativeStructureVolume>>> results = new ArrayList<>();
for (int task = 0; task < 32; task++) {
results.add(pool.submit(() -> index.resolve(engine, 0, 0, 47, 47)));
}
for (Future<KList<NativeStructureVolume>> result : results) {
assertEquals(expected, result.get(30, TimeUnit.SECONDS));
}
} finally {
pool.shutdown();
assertTrue(pool.awaitTermination(30, TimeUnit.SECONDS));
}
for (AtomicInteger count : builds.values()) {
assertEquals(1, count.get());
}
int distinct = builds.size();
index.evictRuntime(7);
assertEquals(expected, index.resolve(engine, 0, 0, 47, 47));
assertEquals(distinct, builds.size());
for (AtomicInteger count : builds.values()) {
assertEquals(2, count.get());
}
}
private static KList<NativeStructureVolume> volumesAt(int chunkX, int chunkZ) {
if (Math.floorMod(chunkX * 31 + chunkZ * 17, 5) != 0) {
return NativeStructureVolume.NONE;
}
int minX = chunkX << 4;
int minZ = chunkZ << 4;
return new KList<>(new NativeStructureVolume("test:" + chunkX + "_" + chunkZ,
minX - 20, -10, minZ - 20, minX + 36, 40, minZ + 36, null));
}
}
@@ -60,6 +60,15 @@ public class NativeTerrainReceiptTest {
}
}
@Test
public void repeatedEncodingOnOneThreadKeepsLegacyBytes() throws Exception {
for (int round = 0; round < 6; round++) {
SavedTerrainChunk chunk = chunk(round % 2 == 0);
String epoch = "epoch-" + round;
assertArrayEquals(legacyEncode(chunk, round, epoch), NativeTerrainReceipt.encode(chunk, round, epoch));
}
}
@Test
public void saturatedStringCachesPreserveModifiedUtfBytes() throws Exception {
for (int padding : new int[]{0, 300}) {
@@ -60,6 +60,16 @@ public class SavedBiomeStoreWriteTest {
assertArrayEquals(expectedRegion(), Files.readAllBytes(regionPath(root)));
}
@Test
public void consecutiveRecordsKeepIndependentlyCompressedBytes() throws Exception {
Path root = temporaryFolder.newFolder().toPath();
SavedBiomeStore store = SavedBiomeStore.open(root);
for (int x = 0; x < 4; x++) {
store.claimAndPersist(chunk(x, 3L));
}
assertArrayEquals(expectedRegion(4), Files.readAllBytes(regionPath(root)));
}
@Test
public void relaxedDurabilityPreservesRecordsWithoutForcingEachAppend() throws Exception {
String previousMode = System.getProperty(Durability.MODE_PROPERTY);
@@ -379,6 +389,10 @@ public class SavedBiomeStoreWriteTest {
}
private static byte[] expectedRegion() throws IOException {
return expectedRegion(1);
}
private static byte[] expectedRegion(int records) throws IOException {
ByteArrayOutputStream raw = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(raw);
data.writeLong(3L);
@@ -392,17 +406,6 @@ public class SavedBiomeStoreWriteTest {
data.writeInt(1);
data.write(new byte[]{0, 0, 1, (byte) 0x80, 3, 0});
data.write(new byte[256]);
ByteArrayOutputStream body = new ByteArrayOutputStream();
DataOutputStream coordinates = new DataOutputStream(body);
coordinates.writeInt(0);
coordinates.writeInt(0);
coordinates.writeInt(raw.size());
Deflater deflater = new Deflater(Deflater.BEST_SPEED);
try (DeflaterOutputStream compressed = new DeflaterOutputStream(coordinates, deflater)) {
raw.writeTo(compressed);
} finally {
deflater.end();
}
ByteArrayOutputStream region = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(region);
output.writeInt(0x4942494F);
@@ -410,9 +413,22 @@ public class SavedBiomeStoreWriteTest {
output.writeInt(0);
output.writeInt(0);
output.writeInt(checksum(region.toByteArray()));
output.writeInt(body.size());
output.write(body.toByteArray());
output.writeInt(checksum(body.toByteArray()));
for (int x = 0; x < records; x++) {
ByteArrayOutputStream body = new ByteArrayOutputStream();
DataOutputStream coordinates = new DataOutputStream(body);
coordinates.writeInt(x);
coordinates.writeInt(0);
coordinates.writeInt(raw.size());
Deflater deflater = new Deflater(Deflater.BEST_SPEED);
try (DeflaterOutputStream compressed = new DeflaterOutputStream(coordinates, deflater)) {
raw.writeTo(compressed);
} finally {
deflater.end();
}
output.writeInt(body.size());
output.write(body.toByteArray());
output.writeInt(checksum(body.toByteArray()));
}
return region.toByteArray();
}