feat: get faster generation times

This commit is contained in:
Christian Bergschneider 2025-01-02 00:48:26 +01:00
parent d1f881ca2c
commit 23b846eca9
No known key found for this signature in database
GPG Key ID: 3991F97F5FA28D3E
5 changed files with 39 additions and 13 deletions

View File

@ -1,5 +1,6 @@
package com.dfsek.terra.minestom;
import com.dfsek.terra.minestom.world.TerraMinestomWorld;
import com.dfsek.terra.minestom.world.TerraMinestomWorldBuilder;
import net.minestom.server.MinecraftServer;
@ -12,6 +13,7 @@ import net.minestom.server.instance.Instance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Duration;
import java.util.concurrent.atomic.AtomicInteger;
@ -19,10 +21,12 @@ public class TerraMinestomExample {
private static final Logger logger = LoggerFactory.getLogger(TerraMinestomExample.class);
private final MinecraftServer server = MinecraftServer.init();
private final Instance instance = MinecraftServer.getInstanceManager().createInstanceContainer();
private TerraMinestomWorld world;
public void attachTerra() {
TerraMinestomWorldBuilder.from(instance)
world = TerraMinestomWorldBuilder.from(instance)
.defaultPack()
.seed(0)
.attach();
}
@ -37,7 +41,7 @@ public class TerraMinestomExample {
}
public void preloadWorldAndMeasure() {
int radius = 6;
int radius = 12;
int chunksLoading = (radius * 2 + 1) * (radius * 2 + 1);
AtomicInteger chunksLeft = new AtomicInteger(chunksLoading);
@ -56,6 +60,8 @@ public class TerraMinestomExample {
(end - start) / 1000000.0,
chunksPerSecond
);
world.displayStats();
} else if (left % 20 == 0) {
sendProgressBar(chunksLoading - left, chunksLoading);
}
@ -75,6 +81,12 @@ public class TerraMinestomExample {
});
}
public void addScheduler() {
MinecraftServer.getSchedulerManager().buildTask(() -> world.displayStats())
.repeat(Duration.ofSeconds(10))
.schedule();
}
public void bind() {
logger.info("Starting server on port 25565");
server.start("localhost", 25565);
@ -84,6 +96,7 @@ public class TerraMinestomExample {
TerraMinestomExample example = new TerraMinestomExample();
example.attachTerra();
example.preloadWorldAndMeasure();
example.addScheduler();
example.addListeners();
example.bind();
}

View File

@ -8,10 +8,14 @@ import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.github.benmanes.caffeine.cache.stats.CacheStats;
import net.minestom.server.world.DimensionType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GeneratedChunkCache {
private static final Logger log = LoggerFactory.getLogger(GeneratedChunkCache.class);
private final LoadingCache<Pair<Integer, Integer>, CachedChunk> cache;
private final DimensionType dimensionType;
private final ChunkGenerator generator;
@ -24,7 +28,8 @@ public class GeneratedChunkCache {
this.world = world;
this.biomeProvider = world.getBiomeProvider();
this.cache = Caffeine.newBuilder()
.maximumSize(32)
.maximumSize(128)
.recordStats()
.build((Pair<Integer, Integer> key) -> generateChunk(key.getLeft(), key.getRight()));
}
@ -39,6 +44,11 @@ public class GeneratedChunkCache {
return chunk;
}
public void displayStats() {
CacheStats stats = cache.stats();
log.info("Avg load time: {}ms | Hit rate: {}% | Load Count: {}", stats.averageLoadPenalty(), stats.hitRate() * 100, stats.loadCount());
}
public CachedChunk at(int x, int z) {
return cache.get(Pair.of(x, z));
}

View File

@ -31,13 +31,7 @@ public class MinestomChunkGeneratorWrapper implements Generator {
public void generate(@NotNull GenerationUnit unit) {
Point start = unit.absoluteStart();
CachedChunk chunk = cache.at(start.chunkX(), start.chunkZ());
chunk.writeRelative(unit.modifier());
//if (start.chunkX() % 2 == 0 && start.chunkZ() % 2 == 0) {
//chunk.writeRelative(unit.modifier());
//}
unit.fork(setter -> {
MinestomProtoWorld protoWorld = new MinestomProtoWorld(
cache,
@ -52,4 +46,8 @@ public class MinestomChunkGeneratorWrapper implements Generator {
}
});
}
public void displayStats() {
cache.displayStats();
}
}

View File

@ -9,6 +9,7 @@ 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;
import com.dfsek.terra.api.world.chunk.generation.ProtoWorld;
import com.dfsek.terra.minestom.chunk.CachedChunk;
import com.dfsek.terra.minestom.chunk.GeneratedChunkCache;
import com.dfsek.terra.minestom.entity.DeferredMinestomEntity;
@ -21,14 +22,14 @@ public class MinestomProtoWorld implements ProtoWorld {
private final GeneratedChunkCache cache;
private final int x;
private final int z;
private final ServerWorld world;
private final TerraMinestomWorld world;
private final Setter modifier;
public MinestomProtoWorld(
GeneratedChunkCache cache,
int x,
int z,
ServerWorld world,
TerraMinestomWorld world,
Setter modifier
) {
this.cache = cache;
@ -74,8 +75,8 @@ public class MinestomProtoWorld implements ProtoWorld {
public BlockState getBlockState(int x, int y, int z) {
int chunkX = x >> 4;
int chunkZ = z >> 4;
return cache.at(chunkX, chunkZ)
.getBlock(x & 15, y, z & 15);
CachedChunk chunk = cache.at(chunkX, chunkZ);
return chunk.getBlock(x & 15, y, z & 15);
}
@Override

View File

@ -67,6 +67,10 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties {
return MinestomEntity.spawn(x, y, z, entityType, this);
}
public void displayStats() {
wrapper.displayStats();
}
@Override
public BlockState getBlockState(int x, int y, int z) {
return new MinestomBlockState(instance.getBlock(x, y, z));