From 5e1c9d8ebe15d6885c295cd145d716fab02a4d78 Mon Sep 17 00:00:00 2001 From: Christian Bergschneider Date: Mon, 2 Jun 2025 00:34:48 +0200 Subject: [PATCH] fix: generation stages not being able to reference eachother --- .../terra/minestom/TerraMinestomExample.java | 3 ++ .../terra/minestom/biome/MinestomBiome.java | 7 ++-- .../minestom/biome/MinestomBiomeLoader.java | 10 ++--- .../terra/minestom/chunk/CachedChunk.java | 6 +++ .../minestom/chunk/GeneratedChunkCache.java | 19 ++++++--- .../world/MinestomChunkGeneratorWrapper.java | 39 +++++++++++++++++-- .../minestom/world/MinestomProtoWorld.java | 10 +++++ .../minestom/world/TerraMinestomWorld.java | 13 +++++-- .../world/TerraMinestomWorldBuilder.java | 2 +- 9 files changed, 86 insertions(+), 23 deletions(-) diff --git a/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java b/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java index 0130347df..792dbb195 100644 --- a/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java +++ b/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java @@ -122,12 +122,15 @@ public class TerraMinestomExample { private void regenerate() { instance.sendMessage(Component.text("Regenerating world")); + Instance oldInstance = instance; createNewInstance(); attachTerra(); preloadWorldAndMeasure(); MinecraftServer.getConnectionManager().getOnlinePlayers().forEach(player -> player.setInstance(instance, new Pos(0, 100, 0)) ); + + MinecraftServer.getInstanceManager().unregisterInstance(oldInstance); } } } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiome.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiome.java index a4c146359..a050978d6 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiome.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiome.java @@ -2,16 +2,17 @@ package com.dfsek.terra.minestom.biome; import com.dfsek.terra.api.world.biome.PlatformBiome; +import net.minestom.server.registry.DynamicRegistry; import net.minestom.server.world.biome.Biome; public class MinestomBiome implements PlatformBiome { - private final Biome biome; + private final DynamicRegistry.Key biome; - public MinestomBiome(Biome biome) { this.biome = biome; } + public MinestomBiome(DynamicRegistry.Key biome) { this.biome = biome; } @Override - public Biome getHandle() { + public DynamicRegistry.Key getHandle() { return biome; } } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiomeLoader.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiomeLoader.java index edaf49a50..ccd1176c5 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiomeLoader.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiomeLoader.java @@ -8,23 +8,19 @@ import com.dfsek.tectonic.api.loader.type.TypeLoader; import com.dfsek.terra.api.world.biome.PlatformBiome; import net.kyori.adventure.key.Key; -import net.minestom.server.MinecraftServer; import net.minestom.server.registry.DynamicRegistry; -import net.minestom.server.world.biome.Biome; +import org.intellij.lang.annotations.Subst; import org.jetbrains.annotations.NotNull; import java.lang.reflect.AnnotatedType; public class MinestomBiomeLoader implements TypeLoader { - private final DynamicRegistry biomeRegistry = MinecraftServer.getBiomeRegistry(); - @Override public PlatformBiome load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader, DepthTracker depthTracker) throws LoadException { + @Subst("name:value") String id = (String) o; Key key = Key.key(id); - Biome biome = biomeRegistry.get(key); - if(biome == null) throw new LoadException("Biome %s does not exist in registry".formatted(id), depthTracker); - return new MinestomBiome(biome); + return new MinestomBiome(DynamicRegistry.Key.of(key)); } } \ No newline at end of file diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/CachedChunk.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/CachedChunk.java index 04f7f52d8..c56336b20 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/CachedChunk.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/CachedChunk.java @@ -3,10 +3,16 @@ package com.dfsek.terra.minestom.chunk; import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.util.Column; +import com.dfsek.terra.api.world.biome.Biome; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.chunk.generation.ProtoChunk; +import com.dfsek.terra.minestom.biome.MinestomBiome; import com.dfsek.terra.minestom.block.MinestomBlockState; +import net.minestom.server.coordinate.Point; import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.generator.GenerationUnit; import net.minestom.server.instance.generator.UnitModifier; import org.jetbrains.annotations.NotNull; diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/GeneratedChunkCache.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/GeneratedChunkCache.java index 018c82c72..38064b86f 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/GeneratedChunkCache.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/GeneratedChunkCache.java @@ -22,13 +22,15 @@ public class GeneratedChunkCache { private final ServerWorld world; private final BiomeProvider biomeProvider; - public GeneratedChunkCache(DimensionType dimensionType, ChunkGenerator generator, ServerWorld world) { + public GeneratedChunkCache(DimensionType dimensionType, ChunkGenerator generator, ServerWorld world, BiomeProvider biomeProvider) { this.dimensionType = dimensionType; this.generator = generator; this.world = world; - this.biomeProvider = world.getBiomeProvider(); - this.cache = Caffeine.newBuilder().maximumSize(128).recordStats().build( - (Pair key) -> generateChunk(key.getLeft(), key.getRight())); + this.biomeProvider = biomeProvider; + this.cache = Caffeine.newBuilder() + .maximumSize(128) + .recordStats() + .build((Pair key) -> generateChunk(key.getLeft(), key.getRight())); } private CachedChunk generateChunk(int x, int z) { @@ -39,8 +41,13 @@ public class GeneratedChunkCache { public void displayStats() { CacheStats stats = cache.stats(); - log.info("Avg load time: {}ms | Hit rate: {}% | Load Count: {}", stats.averageLoadPenalty(), stats.hitRate() * 100, - stats.loadCount()); + log.info("Avg load time: %.4fms | Hit rate: %3.4f%% | Load Count: %d" + .formatted( + stats.averageLoadPenalty() / 1000000f, + stats.hitRate() * 100, + stats.loadCount() + ) + ); } public CachedChunk at(int x, int z) { diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java index 81529db48..f3829a65a 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java @@ -1,30 +1,41 @@ package com.dfsek.terra.minestom.world; +import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.world.biome.PlatformBiome; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage; import com.dfsek.terra.api.world.chunk.generation.util.GeneratorWrapper; +import com.dfsek.terra.minestom.biome.MinestomBiome; import com.dfsek.terra.minestom.chunk.CachedChunk; import com.dfsek.terra.minestom.chunk.GeneratedChunkCache; import net.minestom.server.coordinate.Point; import net.minestom.server.instance.generator.GenerationUnit; import net.minestom.server.instance.generator.Generator; +import net.minestom.server.instance.generator.UnitModifier; +import net.minestom.server.registry.DynamicRegistry; import org.jetbrains.annotations.NotNull; +import java.util.Objects; + public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrapper { private final GeneratedChunkCache cache; private ChunkGenerator generator; private final TerraMinestomWorld world; + private final BiomeProvider biomeProvider; private ConfigPack pack; - public MinestomChunkGeneratorWrapper(ChunkGenerator generator, TerraMinestomWorld world, ConfigPack pack) { + public MinestomChunkGeneratorWrapper(Platform platform, ChunkGenerator generator, TerraMinestomWorld world, ConfigPack pack) { this.generator = generator; this.world = world; this.pack = pack; - this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world); + + biomeProvider = pack.getBiomeProvider().caching(platform); + this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world, biomeProvider); } public ChunkGenerator getGenerator() { @@ -36,14 +47,36 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe Point start = unit.absoluteStart(); int x = start.chunkX(); int z = start.chunkZ(); + int blockX = start.blockX(); + int blockZ = start.blockZ(); CachedChunk chunk = cache.at(x, z); - chunk.writeRelative(unit.modifier()); + UnitModifier modifier = unit.modifier(); + chunk.writeRelative(modifier); + +// for(int dx = 0; dx < 16; dx++) { +// for(int dz = 0; dz < 16; dz++) { +// int globalX = dx + blockX; +// int globalZ = dz + blockZ; +// biomeProvider.getColumn(globalX, globalZ, world).forEach((y, biome) -> { +// MinestomBiome platformBiome = (MinestomBiome) biome.getPlatformBiome(); +// modifier.setBiome(globalX, 0, globalZ, DynamicRegistry.Key.of("minecraft:the_void")); +// }); +// } +// } unit.fork(setter -> { MinestomProtoWorld protoWorld = new MinestomProtoWorld(cache, x, z, world, setter); + var stages = world.getPack().getStages(); + + if(x==0 && z==0) { + System.out.println(stages); + System.out.println(protoWorld.getBlockState(-4, 73, -6).getAsString()); + } + for(GenerationStage stage : world.getPack().getStages()) { stage.populate(protoWorld); + if(x==0 && z==0) System.out.println(protoWorld.getBlockState(-4, 73, -6).getAsString()); } }); } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomProtoWorld.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomProtoWorld.java index 65ec22654..e29cc5d76 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomProtoWorld.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomProtoWorld.java @@ -5,6 +5,7 @@ import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.entity.Entity; import com.dfsek.terra.api.entity.EntityType; +import com.dfsek.terra.api.util.generic.pair.Pair; import com.dfsek.terra.api.world.ServerWorld; import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; @@ -17,6 +18,11 @@ import com.dfsek.terra.minestom.entity.DeferredMinestomEntity; import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block.Setter; +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.HashSet; +import java.util.WeakHashMap; + public class MinestomProtoWorld implements ProtoWorld { private final GeneratedChunkCache cache; @@ -51,6 +57,10 @@ public class MinestomProtoWorld implements ProtoWorld { @Override public void setBlockState(int x, int y, int z, BlockState data, boolean physics) { modifier.setBlock(x, y, z, (Block) data.getHandle()); + int chunkX = x >> 4; + int chunkZ = z >> 4; + CachedChunk chunk = cache.at(chunkX, chunkZ); + chunk.setBlock(x & 15, y, z & 15, data); } @Override diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java index 4f4aef091..692f96b64 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java @@ -13,6 +13,7 @@ import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; import com.dfsek.terra.api.world.info.WorldProperties; +import com.dfsek.terra.minestom.TerraMinestomPlatform; import com.dfsek.terra.minestom.api.BlockEntityFactory; import com.dfsek.terra.minestom.api.EntityFactory; import com.dfsek.terra.minestom.block.MinestomBlockState; @@ -37,8 +38,14 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties { private final EntityFactory entityFactory; private final BlockEntityFactory blockEntityFactory; - public TerraMinestomWorld(Instance instance, ConfigPack pack, long seed, EntityFactory entityFactory, - BlockEntityFactory blockEntityFactory) { + public TerraMinestomWorld( + TerraMinestomPlatform platform, + Instance instance, + ConfigPack pack, + long seed, + EntityFactory entityFactory, + BlockEntityFactory blockEntityFactory + ) { this.instance = instance; this.pack = pack; this.seed = seed; @@ -46,7 +53,7 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties { this.dimensionType = MinecraftServer.getDimensionTypeRegistry().get(instance.getDimensionType()); this.blockEntityFactory = blockEntityFactory; - this.wrapper = new MinestomChunkGeneratorWrapper(pack.getGeneratorProvider().newInstance(pack), this, pack); + this.wrapper = new MinestomChunkGeneratorWrapper(platform, pack.getGeneratorProvider().newInstance(pack), this, pack); this.entityFactory = entityFactory; instance.setGenerator(this.wrapper); diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java index 3c77c372b..c68b4b72f 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java @@ -66,6 +66,6 @@ public class TerraMinestomWorldBuilder { } public TerraMinestomWorld attach() { - return new TerraMinestomWorld(instance, pack, seed, entityFactory, blockEntityFactory); + return new TerraMinestomWorld(platform, instance, pack, seed, entityFactory, blockEntityFactory); } }