From 1d74eea3efd32a528e310acc3879005072c5627b Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 20 Dec 2025 10:53:14 -0600 Subject: [PATCH] reduce stuttering at the cost of lighting quality --- .../common/wrappers/chunk/ChunkWrapper.java | 30 +++++++------ .../wrappers/world/ClientLevelWrapper.java | 17 -------- .../wrappers/world/ServerLevelWrapper.java | 42 ------------------- .../BatchGenerationEnvironment.java | 7 ++-- .../InternalServerGenerator.java | 1 + .../ChunkCompoundTagParser.java | 3 +- .../chunkFileHandling/ChunkFileReader.java | 2 +- coreSubProjects | 2 +- 8 files changed, 26 insertions(+), 78 deletions(-) diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/chunk/ChunkWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/chunk/ChunkWrapper.java index cd14bde5b..0d6b86b6c 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/chunk/ChunkWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/chunk/ChunkWrapper.java @@ -18,6 +18,7 @@ */ package com.seibel.distanthorizons.common.wrappers.chunk; +import com.seibel.distanthorizons.api.DhApi; import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper; import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper; import com.seibel.distanthorizons.common.wrappers.misc.MutableBlockPosWrapper; @@ -80,6 +81,8 @@ public class ChunkWrapper implements IChunkWrapper private static final ThreadLocal MUTABLE_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos()); private static final ThreadLocal MUTABLE_BLOCK_POS_WRAPPER_REF = ThreadLocal.withInitial(() -> new MutableBlockPosWrapper()); + private static boolean heightmapThreadWarningLogged = false; + private final ChunkAccess chunk; private final DhChunkPos chunkPos; @@ -107,22 +110,21 @@ public class ChunkWrapper implements IChunkWrapper // constructor // //=============// + /** + * Note: this constructor should be very + * fast since it will be called frequently on the MC + * server thread and a slow method will cause server lag. + */ public ChunkWrapper(ChunkAccess chunk, ILevelWrapper wrappedLevel) - { - this(chunk, wrappedLevel, true); - } - public ChunkWrapper(ChunkAccess chunk, ILevelWrapper wrappedLevel, boolean recreateHeightmaps) { this.chunk = chunk; this.wrappedLevel = wrappedLevel; this.chunkPos = new DhChunkPos(chunk.getPos().x, chunk.getPos().z); - - if (recreateHeightmaps) - { - this.createDhHeightMaps(); - } } + @Override + public ChunkWrapper copy() { return new ChunkWrapper(this.chunk, this.wrappedLevel); } + //=========// @@ -242,11 +244,15 @@ public class ChunkWrapper implements IChunkWrapper } private int getChunkSectionMinHeight(int index) { return (index * 16) + this.getInclusiveMinBuildHeight(); } + @Override public void createDhHeightMaps() { - // re-calculate the min/max heights for consistency (during world gen these may be wrong) - this.minNonEmptyHeight = Integer.MIN_VALUE; - this.maxNonEmptyHeight = Integer.MAX_VALUE; + if (heightmapThreadWarningLogged + && !DhApi.isDhThread()) + { + LOGGER.warn("ChunkWrapper Height maps created on non-DH thread ["+Thread.currentThread().getName()+"]. This may cause stuttering."); + } + this.solidHeightMap = new int[LodUtil.CHUNK_WIDTH][LodUtil.CHUNK_WIDTH]; diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java index 0e16df94e..758cb4473 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java @@ -295,23 +295,6 @@ public class ClientLevelWrapper implements IClientLevelWrapper #endif } - @Override - public IChunkWrapper tryGetChunk(DhChunkPos pos) - { - if (!this.level.hasChunk(pos.getX(), pos.getZ())) - { - return null; - } - - ChunkAccess chunk = this.level.getChunk(pos.getX(), pos.getZ(), ChunkStatus.EMPTY, false); - if (chunk == null) - { - return null; - } - - return new ChunkWrapper(chunk, this); - } - @Override public ClientLevel getWrappedMcObject() { return this.level; } diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ServerLevelWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ServerLevelWrapper.java index 5c8d69f0a..bf548285d 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ServerLevelWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ServerLevelWrapper.java @@ -49,12 +49,6 @@ import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.status.ChunkStatus; #endif -#if MC_VER <= MC_1_21_10 -#else -import net.minecraft.world.level.ChunkPos; -import net.minecraft.server.level.ChunkHolder; -#endif - import com.seibel.distanthorizons.core.logging.DhLogger; import org.jetbrains.annotations.Nullable; @@ -229,42 +223,6 @@ public class ServerLevelWrapper implements IServerLevelWrapper #endif } - @Override - public IChunkWrapper tryGetChunk(DhChunkPos pos) - { - #if MC_VER < MC_1_21_11 - if (!this.level.hasChunk(pos.getX(), pos.getZ())) - { - return null; - } - - ChunkAccess chunk = this.level.getChunk(pos.getX(), pos.getZ(), ChunkStatus.FULL, false); - if (chunk == null) - { - return null; - } - - return new ChunkWrapper(chunk, this); - #else - - // directly hitting the chunkMap is required otherwise MC will run this on the main server thread, - // causing lag - ChunkHolder chunkHolder = this.level.getChunkSource().chunkMap.getVisibleChunkIfPresent(new ChunkPos(pos.getX(), pos.getZ()).toLong()); - if (chunkHolder == null) - { - return null; - } - - ChunkAccess chunk = chunkHolder.getChunkIfPresent(ChunkStatus.FULL); - if (chunk == null) - { - return null; - } - - return new ChunkWrapper(chunk, this); - #endif - } - @Override public ServerLevel getWrappedMcObject() { return this.level; } diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/BatchGenerationEnvironment.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/BatchGenerationEnvironment.java index 6e81976ad..ee609e145 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/BatchGenerationEnvironment.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/BatchGenerationEnvironment.java @@ -448,10 +448,9 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm - //=============================// + //=========================// // process existing chunks // - // - //=============================// + //=========================// ArrayGridList chunkWrapperList = new ArrayGridList<>(regionChunks.gridSize); regionChunks.forEachPos((relX, relZ) -> @@ -467,8 +466,8 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm } else if (chunk != null) { - // ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, this.dhServerLevel.getLevelWrapper()); + chunkWrapper.createDhHeightMaps(); chunkWrapperList.set(relX, relZ, chunkWrapper); // try setting the wrapper's lighting diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/InternalServerGenerator.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/InternalServerGenerator.java index 58e75701d..154194bed 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/InternalServerGenerator.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/InternalServerGenerator.java @@ -156,6 +156,7 @@ public class InternalServerGenerator if (chunk != null) { ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, this.dhServerLevel.getLevelWrapper()); + chunkWrapper.createDhHeightMaps(); chunkWrappers.add(chunkWrapper); } } diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/chunkFileHandling/ChunkCompoundTagParser.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/chunkFileHandling/ChunkCompoundTagParser.java index 9ad4cabb3..4ffef0959 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/chunkFileHandling/ChunkCompoundTagParser.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/chunkFileHandling/ChunkCompoundTagParser.java @@ -222,7 +222,8 @@ public class ChunkCompoundTagParser boolean hasHeightmapData = readHeightmaps(chunk, chunkData); // chunk wrapper so we can pass along extra data more easily - ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, dhServerLevel.getServerLevelWrapper(), !hasHeightmapData); + ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, dhServerLevel.getServerLevelWrapper()); + chunkWrapper.createDhHeightMaps(); diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/chunkFileHandling/ChunkFileReader.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/chunkFileHandling/ChunkFileReader.java index cc51b392d..3ea80ceec 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/chunkFileHandling/ChunkFileReader.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/chunkFileHandling/ChunkFileReader.java @@ -293,7 +293,7 @@ public class ChunkFileReader implements AutoCloseable public ChunkWrapper CreateProtoChunkWrapper(ServerLevel level, ChunkPos chunkPos) { ProtoChunk chunk = CreateProtoChunk(level, chunkPos); - return new ChunkWrapper(chunk, this.params.dhServerLevel.getLevelWrapper(), false); + return new ChunkWrapper(chunk, this.params.dhServerLevel.getLevelWrapper()); } public static ProtoChunk CreateProtoChunk(ServerLevel level, ChunkPos chunkPos) { diff --git a/coreSubProjects b/coreSubProjects index 1c30213ac..bf92dea2e 160000 --- a/coreSubProjects +++ b/coreSubProjects @@ -1 +1 @@ -Subproject commit 1c30213aca4df8c60f42941789dfa7145ac6b512 +Subproject commit bf92dea2ebfff5b7043da0a676543cb2ca1c9c92