diff --git a/core/src/main/java/art/arcane/iris/generation/context/ChunkContext.java b/core/src/main/java/art/arcane/iris/generation/context/ChunkContext.java index b3e7509f4..8135a3c9c 100644 --- a/core/src/main/java/art/arcane/iris/generation/context/ChunkContext.java +++ b/core/src/main/java/art/arcane/iris/generation/context/ChunkContext.java @@ -230,6 +230,10 @@ public class ChunkContext { return region; } + public boolean hasDimensionStack() { + return dimensionStackContext != null; + } + public DimensionStackLayout getDimensionStackLayout(int localX, int localZ) { if (dimensionStackContext == null) { return null; diff --git a/core/src/main/java/art/arcane/iris/generation/runtime/EngineMode.java b/core/src/main/java/art/arcane/iris/generation/runtime/EngineMode.java index 5e3d27b61..5c5c9bda4 100644 --- a/core/src/main/java/art/arcane/iris/generation/runtime/EngineMode.java +++ b/core/src/main/java/art/arcane/iris/generation/runtime/EngineMode.java @@ -23,7 +23,7 @@ import art.arcane.iris.generation.concurrent.MultiBurst; import art.arcane.iris.generation.context.ChunkContext; import art.arcane.iris.generation.context.IrisContext; import art.arcane.iris.generation.mantle.EngineMantle; -import art.arcane.iris.generation.stage.IrisBiomeActuator; +import art.arcane.iris.generation.stage.IrisDimensionStackActuator; import art.arcane.iris.generation.stage.IrisTransitionGeometryActuator; import art.arcane.iris.integration.Identifier; import art.arcane.iris.generation.decoration.tree.TreeBlockMaterial; @@ -215,7 +215,7 @@ public interface EngineMode extends Staged { try (IrisContext.Scope chunkScope = IrisContext.open(getEngine(), generationSessionId, ctx)) { generateTerrain(x, z, blocks, biomes, multicore, ctx); recordNaturalTerrain(x, z, blocks, biomes, ctx); - IrisBiomeActuator.publishNaturalMetadata(getEngine(), x, z, biomes, ctx); + IrisDimensionStackActuator.clearHostNaturalMetadata(getEngine(), x, z, biomes.getHeight(), ctx); ctx.beginContent(); List continuations = restoreObjectContinuations(x, z); for (EngineStage i : stages) { diff --git a/core/src/main/java/art/arcane/iris/generation/stage/IrisBiomeActuator.java b/core/src/main/java/art/arcane/iris/generation/stage/IrisBiomeActuator.java index 351a35ff8..0410ac36d 100644 --- a/core/src/main/java/art/arcane/iris/generation/stage/IrisBiomeActuator.java +++ b/core/src/main/java/art/arcane/iris/generation/stage/IrisBiomeActuator.java @@ -27,7 +27,6 @@ import art.arcane.iris.world.history.TransitionGenerationPlan; import art.arcane.iris.generation.biome.IrisBiome; import art.arcane.iris.generation.biome.IrisBiomeCustom; import art.arcane.iris.generation.terrain.IrisDimension; -import art.arcane.iris.spi.IrisPlatform; import art.arcane.iris.spi.IrisPlatforms; import art.arcane.volmlib.nativelib.terrain.NativeBiome; import art.arcane.iris.generation.context.ChunkContext; @@ -35,12 +34,7 @@ import art.arcane.iris.generation.context.ChunkedDataCache; import art.arcane.volmlib.util.hunk.Hunk; import art.arcane.volmlib.util.collection.KMap; import art.arcane.volmlib.util.documentation.BlockCoordinates; -import art.arcane.volmlib.util.mantle.runtime.Mantle; -import art.arcane.volmlib.util.mantle.runtime.MantleChunk; import art.arcane.volmlib.util.math.RNG; -import art.arcane.volmlib.util.matter.Matter; -import art.arcane.volmlib.util.matter.MatterBiomeInject; -import art.arcane.volmlib.util.matter.slices.BiomeInjectMatter; import art.arcane.volmlib.util.scheduling.PrecisionStopwatch; import java.util.List; @@ -48,8 +42,8 @@ import java.util.Objects; public class IrisBiomeActuator extends EngineAssignedActuator { private final RNG rng; - private final KMap resolvedBiomes = new KMap<>(); - private final KMap resolvedPhysicalBiomes = new KMap<>(); + private final KMap resolvedBiomes = new KMap<>(); + private final KMap resolvedPhysicalBiomes = new KMap<>(); public IrisBiomeActuator(Engine engine) { super(engine, "Biome"); @@ -64,7 +58,6 @@ public class IrisBiomeActuator extends EngineAssignedActuator { int depth = h.getDepth(); int height = h.getHeight(); Engine engine = getEngine(); - Mantle mantle = engine.getMantle().getMantle(); ChunkedDataCache biomeCache = context.getBiome(); IrisComplex complex = context.getComplex(); DimensionStackContext dimensionStackContext = engine.getDimensionStackContext(); @@ -74,7 +67,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator { int worldX = x + xf; int worldZ = z + zf; IrisBiome biome = biomeCache.get(xf, zf); - ResolvedBiome resolved = resolve(biomeKey( + NativeBiome platformBiome = resolve(biomeKey( biome, getDimension(), engine, @@ -82,8 +75,9 @@ public class IrisBiomeActuator extends EngineAssignedActuator { 0, worldZ )); - NativeBiome platformBiome = resolved.biome(); - writeColumn(h, mantle, xf, zf, worldX, worldZ, height, resolved); + if (platformBiome != null) { + h.set(xf, 0, zf, xf, height - 1, zf, platformBiome); + } if (dimensionStackContext != null) { NativeBiome bottomBiome = platformBiome == null @@ -95,48 +89,19 @@ public class IrisBiomeActuator extends EngineAssignedActuator { worldX, worldZ, h, - mantle, engine, - new ResolvedBiome(bottomBiome, resolved.matter()), + bottomBiome, context.getDimensionStackLayout(xf, zf) ); } - writeHistoricalColumn(h, mantle, xf, zf, worldX, worldZ, height, engine, complex); + writeHistoricalColumn(h, xf, zf, worldX, worldZ, height, engine, complex); } } engine.getMetrics().getBiome().put(p.getMilliseconds()); } - public static void publishNaturalMetadata(Engine engine, int x, int z, Hunk biomes, - ChunkContext context) { - if (!context.getComplex().allowsMantleChunkWrite(x >> 4, z >> 4)) { - return; - } - Mantle mantle = engine.getMantle().getMantle(); - MantleChunk chunk = mantle.getChunk(x >> 4, z >> 4).use(); - try { - synchronized (chunk) { - IrisDimensionStackActuator.clearNaturalMetadata(chunk, context, biomes.getHeight()); - chunk.deleteSlices(MatterBiomeInject.class); - for (int localX = 0; localX < biomes.getWidth(); localX += 4) { - for (int localZ = 0; localZ < biomes.getDepth(); localZ += 4) { - for (int y = 0; y < biomes.getHeight(); y += 4) { - NativeBiome biome = biomes.getRaw(localX, y, localZ); - if (biome != null) { - mantle.set(x + localX, y, z + localZ, BiomeInjectMatter.get(biome.key())); - } - } - } - } - } - } finally { - chunk.release(); - } - } - private void writeHistoricalColumn( Hunk output, - Mantle mantle, int localX, int localZ, int worldX, @@ -167,12 +132,9 @@ public class IrisBiomeActuator extends EngineAssignedActuator { applyBiomeRange( localX, localZ, - worldX, - worldZ, rangeStart, internalY - 1, output, - mantle, resolvePhysicalKey(activeKey) ); } @@ -181,33 +143,14 @@ public class IrisBiomeActuator extends EngineAssignedActuator { } } - private void writeColumn( - Hunk output, - Mantle mantle, - int localX, - int localZ, - int worldX, - int worldZ, - int height, - ResolvedBiome resolved - ) { - if (resolved.biome() != null) { - output.set(localX, 0, localZ, localX, height - 1, localZ, resolved.biome()); - } - if (mantle != null) { - mantle.set(worldX, 0, worldZ, resolved.matter()); - } - } - private void applyDimensionStackBiomes( int localX, int localZ, int worldX, int worldZ, Hunk output, - Mantle mantle, Engine engine, - ResolvedBiome bottom, + NativeBiome bottom, DimensionStackLayout layout ) { List layers = layout.layersBottomToTop(); @@ -222,18 +165,15 @@ public class IrisBiomeActuator extends EngineAssignedActuator { applyBiomeRange( localX, localZ, - worldX, - worldZ, gapMinY, gapMaxY, output, - mantle, bottom ); if (!layer.visible()) { continue; } - ResolvedBiome resolved = bottom; + NativeBiome resolved = bottom; if (layer.biome() != null) { IrisDimension dimension = layer.terrainContext().getDimension(); resolved = resolve(biomeKey( @@ -248,12 +188,9 @@ public class IrisBiomeActuator extends EngineAssignedActuator { applyBiomeRange( localX, localZ, - worldX, - worldZ, layer.renderMinY(), layer.renderMaxY(), output, - mantle, resolved ); } @@ -262,46 +199,15 @@ public class IrisBiomeActuator extends EngineAssignedActuator { private void applyBiomeRange( int localX, int localZ, - int worldX, - int worldZ, int minimumY, int maximumY, Hunk output, - Mantle mantle, - ResolvedBiome resolved + NativeBiome biome ) { - if (minimumY > maximumY) { + if (minimumY > maximumY || biome == null) { return; } - if (mantle != null) { - clearBiomeMatterRange(mantle, worldX, worldZ, minimumY, maximumY); - } - if (resolved.biome() != null) { - output.set( - localX, - minimumY, - localZ, - localX, - maximumY, - localZ, - resolved.biome() - ); - } - if (mantle != null && resolved.matter() != null) { - mantle.set(worldX, minimumY, worldZ, resolved.matter()); - } - } - - static void clearBiomeMatterRange( - Mantle mantle, - int worldX, - int worldZ, - int minimumY, - int maximumY - ) { - for (int y = minimumY; y <= maximumY; y++) { - mantle.remove(worldX, y, worldZ, MatterBiomeInject.class); - } + output.set(localX, minimumY, localZ, localX, maximumY, localZ, biome); } private String biomeKey( @@ -319,37 +225,28 @@ public class IrisBiomeActuator extends EngineAssignedActuator { return biome.getSkyBiomeKey(rng, engine, x, y, z); } - private ResolvedBiome resolve(String key) { - ResolvedBiome cached = key == null ? null : resolvedBiomes.get(key); + private NativeBiome resolve(String key) { + NativeBiome cached = key == null ? null : resolvedBiomes.get(key); if (cached != null) { return cached; } - IrisPlatform platform = IrisPlatforms.get(); - NativeBiome biome = platform.registries().biome(key); - ResolvedBiome resolved = new ResolvedBiome( - biome, - BiomeInjectMatter.get(platform.biomeWriter().biomeIdFor(key)) - ); + NativeBiome biome = IrisPlatforms.get().registries().biome(key); if (key != null && biome != null) { - resolvedBiomes.put(key, resolved); + resolvedBiomes.put(key, biome); } - return resolved; + return biome; } - private ResolvedBiome resolvePhysicalKey(String key) { - ResolvedBiome cached = resolvedPhysicalBiomes.get(key); + private NativeBiome resolvePhysicalKey(String key) { + NativeBiome cached = resolvedPhysicalBiomes.get(key); if (cached != null) { return cached; } NativeBiome biome = IrisPlatforms.get().registries().biome(key); - ResolvedBiome resolved = new ResolvedBiome(biome, BiomeInjectMatter.get(key)); if (biome != null) { - resolvedPhysicalBiomes.put(key, resolved); + resolvedPhysicalBiomes.put(key, biome); } - return resolved; - } - - private record ResolvedBiome(NativeBiome biome, MatterBiomeInject matter) { + return biome; } } diff --git a/core/src/main/java/art/arcane/iris/generation/stage/IrisDimensionStackActuator.java b/core/src/main/java/art/arcane/iris/generation/stage/IrisDimensionStackActuator.java index 2df4baf8b..041a2af5d 100644 --- a/core/src/main/java/art/arcane/iris/generation/stage/IrisDimensionStackActuator.java +++ b/core/src/main/java/art/arcane/iris/generation/stage/IrisDimensionStackActuator.java @@ -106,7 +106,21 @@ public final class IrisDimensionStackActuator extends EngineAssignedActuator chunk, ChunkContext context, int height) { + public static void clearHostNaturalMetadata(Engine engine, int x, int z, int height, ChunkContext context) { + if (!context.hasDimensionStack() || !context.getComplex().allowsMantleChunkWrite(x >> 4, z >> 4)) { + return; + } + MantleChunk chunk = engine.getMantle().getMantle().getChunk(x >> 4, z >> 4).use(); + try { + synchronized (chunk) { + clearNaturalMetadata(chunk, context, height); + } + } finally { + chunk.release(); + } + } + + static void clearNaturalMetadata(MantleChunk chunk, ChunkContext context, int height) { MetadataCleaner metadata = new MetadataCleaner(chunk, height); for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { diff --git a/core/src/main/java/art/arcane/iris/generation/stage/IrisFloatingChildBiomeModifier.java b/core/src/main/java/art/arcane/iris/generation/stage/IrisFloatingChildBiomeModifier.java index 1d43804fc..de24fa14d 100644 --- a/core/src/main/java/art/arcane/iris/generation/stage/IrisFloatingChildBiomeModifier.java +++ b/core/src/main/java/art/arcane/iris/generation/stage/IrisFloatingChildBiomeModifier.java @@ -44,7 +44,6 @@ import art.arcane.volmlib.util.hunk.Hunk; import art.arcane.volmlib.util.noise.CNG; import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.math.RNG; -import art.arcane.volmlib.util.matter.slices.BiomeInjectMatter; import art.arcane.volmlib.util.scheduling.PrecisionStopwatch; import art.arcane.iris.spi.IrisPlatforms; import art.arcane.volmlib.nativelib.terrain.NativeBlockState; @@ -431,7 +430,6 @@ public class IrisFloatingChildBiomeModifier extends EngineAssignedModifier output = mock(Hunk.class); + when(output.getWidth()).thenReturn(2); + when(output.getDepth()).thenReturn(2); + when(output.getHeight()).thenReturn(8); + ChunkedDataCache biomeCache = currentBiomeCache(engine); + ChunkContext context = mock(ChunkContext.class); + when(context.getComplex()).thenReturn(complex); + when(context.getBiome()).thenReturn(biomeCache); + + actuator.onActuate(100, -200, output, false, context); + + NativeBiome plains = IrisPlatforms.get().registries().biome("minecraft:plains"); + for (int x = 0; x < 2; x++) { + for (int z = 0; z < 2; z++) { + verify(output).set(x, 0, z, x, 7, z, plains); + } + } + verifyNoInteractions(engine.getMantle().getMantle()); + verify(IrisPlatforms.get().biomeWriter(), never()).biomeIdFor(anyString()); + } + @Test @SuppressWarnings("unchecked") public void derivativeScatterUsesEachWorldColumnCoordinate() { @@ -101,19 +139,6 @@ public class IrisBiomeActuatorCoordinateTest { assertEquals(List.of("100,-200", "100,-199", "101,-200", "101,-199"), samples); } - @Test - @SuppressWarnings("unchecked") - public void stackedBiomeReplacementRemovesEveryExistingMarkerWithItsTypedSlice() { - Mantle mantle = mock(Mantle.class); - - IrisBiomeActuator.clearBiomeMatterRange(mantle, 100, -200, 4, 6); - - verify(mantle).remove(100, 4, -200, MatterBiomeInject.class); - verify(mantle).remove(100, 5, -200, MatterBiomeInject.class); - verify(mantle).remove(100, 6, -200, MatterBiomeInject.class); - verifyNoMoreInteractions(mantle); - } - @Test @SuppressWarnings("unchecked") public void transitionColumnOverlaysFrozenPhysicalKeyAfterCurrentBiome() { @@ -143,11 +168,8 @@ public class IrisBiomeActuatorCoordinateTest { verify(biomeCache).get(0, 0); verify(IrisPlatforms.get().registries()).biome("iris:old-physical"); verify(IrisPlatforms.get().biomeWriter(), never()).biomeIdFor("iris:old-physical"); - Mantle mantle = engine.getMantle().getMantle(); - verify(mantle).set(eq(100), eq(0), eq(-200), argThat(value -> { - MatterBiomeInject injection = (MatterBiomeInject) value; - return !injection.isCustom() && "iris:old-physical".equals(injection.getBiomeKey()); - })); + verify(output, times(2)).set(0, 0, 0, 0, 0, 0, IrisPlatforms.get().registries().biome("iris:old-physical")); + verifyNoInteractions(engine.getMantle().getMantle()); } @Test @@ -184,15 +206,9 @@ public class IrisBiomeActuatorCoordinateTest { verify(transitionPlan, never()).historicalPhysicalBiomeKeyAt(anyInt(), anyInt(), anyInt()); verify(output).set(eq(0), eq(0), eq(0), eq(0), eq(3), eq(0), any(NativeBiome.class)); verify(output).set(eq(0), eq(4), eq(0), eq(0), eq(7), eq(0), any(NativeBiome.class)); - Mantle mantle = engine.getMantle().getMantle(); - verify(mantle).set(eq(100), eq(0), eq(-200), argThat(value -> { - MatterBiomeInject injection = (MatterBiomeInject) value; - return "iris:old-bottom".equals(injection.getBiomeKey()); - })); - verify(mantle).set(eq(100), eq(4), eq(-200), argThat(value -> { - MatterBiomeInject injection = (MatterBiomeInject) value; - return "iris:old-top".equals(injection.getBiomeKey()); - })); + verify(IrisPlatforms.get().registries()).biome("iris:old-bottom"); + verify(IrisPlatforms.get().registries()).biome("iris:old-top"); + verifyNoInteractions(engine.getMantle().getMantle()); } @SuppressWarnings("unchecked")