From 7c9f88e4f84063463530fb276f779b6776ad6132 Mon Sep 17 00:00:00 2001 From: hayanesuru Date: Thu, 26 Jun 2025 23:28:32 +0900 Subject: [PATCH] [ci skip] cleanup --- .../features/0263-optimize-mob-spawning.patch | 122 +++++++++--------- .../features/0270-optimize-random-tick.patch | 6 +- .../features/0273-Paw-optimization.patch | 4 +- .../dreeam/leaf/world/RandomTickSystem.java | 7 +- 4 files changed, 69 insertions(+), 70 deletions(-) diff --git a/leaf-server/minecraft-patches/features/0263-optimize-mob-spawning.patch b/leaf-server/minecraft-patches/features/0263-optimize-mob-spawning.patch index 045df112..e449a90e 100644 --- a/leaf-server/minecraft-patches/features/0263-optimize-mob-spawning.patch +++ b/leaf-server/minecraft-patches/features/0263-optimize-mob-spawning.patch @@ -17,7 +17,7 @@ index 79674f4bd7a12c42dec19a4175012d7a2dc88b84..9f4ba5b7e054bbe70a820068f22fe8a6 } // Paper end - Optional per player mob spawns diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index 46e171ca454253c32e22c0c18587e9a7ba19f331..51b4a043c09eef84bf926ea02bf588e9ce900788 100644 +index 46e171ca454253c32e22c0c18587e9a7ba19f331..1c23d82a2034bc4ae61ee9bc6c74b39940d4fc2b 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -70,11 +70,11 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -25,12 +25,12 @@ index 46e171ca454253c32e22c0c18587e9a7ba19f331..51b4a043c09eef84bf926ea02bf588e9 private final ChunkStatus[] lastChunkStatus = new ChunkStatus[4]; private final ChunkAccess[] lastChunk = new ChunkAccess[4]; - private final List spawningChunks = new ObjectArrayList<>(); -+ private final List spawningChunks = it.unimi.dsi.fastutil.objects.ReferenceArrayList.wrap(new LevelChunk[0]); // Leaf ++ private final List spawningChunks = it.unimi.dsi.fastutil.objects.ReferenceArrayList.wrap(new LevelChunk[0]); // Leaf - optimize mob spawning private final Set chunkHoldersToBroadcast = new ReferenceOpenHashSet<>(); @Nullable @VisibleForDebug - private NaturalSpawner.SpawnState lastSpawnState; -+ private volatile NaturalSpawner.SpawnState lastSpawnState; // Leaf ++ private volatile NaturalSpawner.SpawnState lastSpawnState; // Leaf - optimize mob spawning // Paper start public final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>(); public int getFullChunksCount() { @@ -39,11 +39,11 @@ index 46e171ca454253c32e22c0c18587e9a7ba19f331..51b4a043c09eef84bf926ea02bf588e9 // This ensures the caps are properly enforced by using the correct calculator - lastSpawnState = NaturalSpawner.createState( -+ lastSpawnState = NaturalSpawner.createState1( ++ lastSpawnState = NaturalSpawner.createState1( // Leaf - optimize mob spawning mapped, wrappedIterator, - ServerChunkCache.this::getFullChunk, -+ this.level, ++ this.level, // Leaf - optimize mob spawning mobCapCalculator, // This is the key fix - was previously null level.paperConfig().entities.spawning.perPlayerMobSpawns ); @@ -53,7 +53,7 @@ index 46e171ca454253c32e22c0c18587e9a7ba19f331..51b4a043c09eef84bf926ea02bf588e9 - for (LevelChunk levelChunk : list) { - this.tickSpawningChunk(levelChunk, timeInhabited, filteredSpawningCategories, lastSpawnState); // Pufferfish -+ // Leaf start ++ // Leaf start - optimize mob spawning + var lastSpawnState1 = lastSpawnState; + if ((!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled || _pufferfish_spawnCountsReady.get()) && lastSpawnState1 != null) { + lastSpawnState1.applyPerPlayerMobCount(level); @@ -69,38 +69,31 @@ index 46e171ca454253c32e22c0c18587e9a7ba19f331..51b4a043c09eef84bf926ea02bf588e9 + } + } } -+ // Leaf end ++ // Leaf end - optimize mob spawning } finally { list.clear(); } diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java -index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe019645606a956 100644 +index f242941ce06d356a025e306efe78c688e9b755c4..5e4cea207d5a5b12d45cf73d59d254e775a7db1a 100644 --- a/net/minecraft/world/level/NaturalSpawner.java +++ b/net/minecraft/world/level/NaturalSpawner.java -@@ -1,5 +1,7 @@ - package net.minecraft.world.level; - -+import ca.spottedleaf.moonrise.common.list.ReferenceList; -+import ca.spottedleaf.moonrise.common.misc.NearbyPlayers; - import com.mojang.logging.LogUtils; - import it.unimi.dsi.fastutil.objects.Object2IntMap; - import it.unimi.dsi.fastutil.objects.Object2IntMaps; -@@ -68,6 +70,7 @@ public final class NaturalSpawner { +@@ -68,6 +68,7 @@ public final class NaturalSpawner { return createState(spawnableChunkCount, entities, chunkGetter, calculator, false); } -+ @Deprecated(forRemoval = true) ++ @Deprecated // Leaf - optimize mob spawning public static NaturalSpawner.SpawnState createState( int spawnableChunkCount, Iterable entities, NaturalSpawner.ChunkGetter chunkGetter, LocalMobCapCalculator calculator, final boolean countMobs ) { -@@ -108,7 +111,65 @@ public final class NaturalSpawner { +@@ -108,9 +109,69 @@ public final class NaturalSpawner { } } - return new NaturalSpawner.SpawnState(spawnableChunkCount, map, potentialCalculator, calculator); -+ return new NaturalSpawner.SpawnState(spawnableChunkCount, map, potentialCalculator, calculator, new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>()); // Leaf -+ } -+ ++ return new NaturalSpawner.SpawnState(spawnableChunkCount, map, potentialCalculator, calculator, new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>()); // Leaf - optimize mob spawning + } + ++ // Leaf start - optimize mob spawning + public static NaturalSpawner.SpawnState createState1( + int spawnableChunkCount, Iterable entities, ServerLevel level, LocalMobCapCalculator calculator, final boolean countMobs + ) { @@ -121,7 +114,7 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 + } + // Paper end - Only count natural spawns + BlockPos blockPos = entity.blockPosition(); -+ var chunk = level.chunkSource.fullChunks.get(ChunkPos.asLong(blockPos)); ++ LevelChunk chunk = level.chunkSource.fullChunks.get(ChunkPos.asLong(blockPos)); + MobSpawnSettings.MobSpawnCost mobSpawnCost = getRoughBiome(blockPos, chunk).getMobSettings().getMobSpawnCost(entity.getType()); + if (mobSpawnCost != null) { + potentialCalculator.addCharge(entity.blockPosition(), mobSpawnCost.charge()); @@ -157,24 +150,27 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 + } + + return new NaturalSpawner.SpawnState(spawnableChunkCount, map, potentialCalculator, calculator, chunkCap); - } - ++ } ++ // Leaf end - optimize mob spawning ++ static Biome getRoughBiome(BlockPos pos, ChunkAccess chunk) { + return chunk.getNoiseBiome(QuartPos.fromBlock(pos.getX()), QuartPos.fromBlock(pos.getY()), QuartPos.fromBlock(pos.getZ())).value(); + } @@ -265,28 +326,67 @@ public final class NaturalSpawner { MobCategory category, ServerLevel level, ChunkAccess chunk, BlockPos pos, NaturalSpawner.SpawnPredicate filter, NaturalSpawner.AfterSpawnCallback callback, final int maxSpawns, final @Nullable Consumer trackEntity, final boolean nothing // Paper end - throttle failed spawn attempts ) { -+ // Leaf start ++ // Leaf start - optimize mob spawning + if (!(chunk instanceof LevelChunk levelChunk)) { + // unreachable + return 0; + } -+ // Leaf end ++ // Leaf end - optimize mob spawning // Paper end - Optional per player mob spawns StructureManager structureManager = level.structureManager(); ChunkGenerator generator = level.getChunkSource().getGenerator(); int y = pos.getY(); -+ // Leaf start ++ // Leaf start - optimize mob spawning + int posX = pos.getX(); + int posZ = pos.getZ(); int i = 0; // Paper - throttle failed spawn attempts @@ -232,7 +228,7 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 + z += rand3 - rand4; + // x += level.random.nextInt(6) - level.random.nextInt(6); + // z += level.random.nextInt(6) - level.random.nextInt(6); -+ // Leaf end ++ // Leaf end - optimize mob spawning mutableBlockPos.set(x, y, z); double d = x + 0.5; double d1 = z + 0.5; @@ -242,8 +238,8 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 if (spawnerData == null) { - Optional randomSpawnMobAt = getRandomSpawnMobAt( - level, structureManager, generator, category, level.random, mutableBlockPos -+ Optional randomSpawnMobAt = getRandomSpawnMobAtWithChunk( // Leaf -+ level, structureManager, generator, category, level.random, mutableBlockPos, levelChunk // Leaf ++ Optional randomSpawnMobAt = getRandomSpawnMobAtWithChunk( // Leaf - optimize mob spawning ++ level, structureManager, generator, category, level.random, mutableBlockPos, levelChunk // Leaf - optimize mob spawning ); if (randomSpawnMobAt.isEmpty()) { break; @@ -260,7 +256,7 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 && level.noCollision(entityType.getSpawnAABB(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5)); return success ? PreSpawnStatus.SUCCESS : PreSpawnStatus.FAIL; // Paper - PreCreatureSpawnEvent } -+ // Leaf start ++ // Leaf start - optimize mob spawning + private static PreSpawnStatus isValidSpawnPostitionForTypeWithChunk( + // Paper end - PreCreatureSpawnEvent + ServerLevel level, @@ -297,7 +293,7 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 + && level.noCollision(entityType.getSpawnAABB(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5)); + return success ? PreSpawnStatus.SUCCESS : PreSpawnStatus.FAIL; // Paper - PreCreatureSpawnEvent + } -+ // Leaf end ++ // Leaf end - optimize mob spawning @Nullable private static Mob getMobForSpawn(ServerLevel level, EntityType entityType) { @@ -305,7 +301,7 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 : mobsAt(level, structureManager, generator, category, pos, biome).getRandom(random); } -+ // Leaf start ++ // Leaf start - optimize mob spawning + private static Optional getRandomSpawnMobAtWithChunk( + ServerLevel level, StructureManager structureManager, ChunkGenerator generator, MobCategory category, RandomSource random, BlockPos pos, LevelChunk chunk + ) { @@ -314,7 +310,7 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 + ? Optional.empty() + : mobsAtWithChunk(level, structureManager, generator, category, pos, biome, chunk).getRandom(random); + } -+ // Leaf end ++ // Leaf end - optimize mob spawning + private static boolean canSpawnMobAt( ServerLevel level, StructureManager structureManager, ChunkGenerator generator, MobCategory category, MobSpawnSettings.SpawnerData data, BlockPos pos @@ -323,7 +319,7 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 : generator.getMobsAt(biome != null ? biome : (org.dreeam.leaf.config.modules.opt.OptimizeBiome.mobSpawn ? level.getBiomeCached(pos) : level.getBiome(pos)), structureManager, cetagory, pos); // Leaf - cache getBiome } -+ // Leaf start ++ // Leaf start - optimize mob spawning + private static WeightedList mobsAtWithChunk( + ServerLevel level, StructureManager structureManager, ChunkGenerator generator, MobCategory cetagory, BlockPos pos, @Nullable Holder biome, LevelChunk chunk + ) { @@ -331,7 +327,7 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 + ? NetherFortressStructure.FORTRESS_ENEMIES + : generator.getMobsAtChunk(biome != null ? biome : (org.dreeam.leaf.config.modules.opt.OptimizeBiome.mobSpawn ? level.getBiomeCached(pos) : level.getBiome(pos)), structureManager, cetagory, pos, chunk); // Leaf - cache getBiome + } -+ // Leaf end ++ // Leaf end - optimize mob spawning + public static boolean isInNetherFortressBounds(BlockPos pos, ServerLevel level, MobCategory category, StructureManager structureManager) { if (category == MobCategory.MONSTER && level.getBlockState(pos.below()).is(Blocks.NETHER_BRICKS)) { @@ -340,7 +336,7 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 } } -+ // Leaf start ++ // Leaf start - optimize mob spawning + public static boolean isInNetherFortressBoundsChunk(BlockPos pos, ServerLevel level, MobCategory category, StructureManager structureManager, LevelChunk chunk) { + if (category == MobCategory.MONSTER && ((chunk.getPos().longKey == ChunkPos.asLong(pos) ? chunk.getBlockStateFinal(pos.getX(), pos.getY() - 1, pos.getZ()).is(Blocks.NETHER_BRICKS) : level.getBlockState(pos.below()).is(Blocks.NETHER_BRICKS)))) { + Structure structure = structureManager.registryAccess().lookupOrThrow(Registries.STRUCTURE).getValue(BuiltinStructures.FORTRESS); @@ -349,7 +345,7 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 + return false; + } + } -+ // Leaf end ++ // Leaf end - optimize mob spawning + + // Leaf start - optimize mob spawning + private static void mutableRandomPosWithin(BlockPos.MutableBlockPos pos1, Level level, LevelChunk chunk) { @@ -369,7 +365,7 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 @Nullable private EntityType lastCheckedType; private double lastCharge; -+ public final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap playerCap; // Leaf ++ public final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap chunkCap; // Leaf - optimize mob spawning SpawnState( int spawnableChunkCount, @@ -377,37 +373,39 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 PotentialCalculator spawnPotential, - LocalMobCapCalculator localMobCapCalculator + LocalMobCapCalculator localMobCapCalculator, -+ it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap playerCap // Leaf ++ it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap playerCap // Leaf - optimize mob spawning ) { this.spawnableChunkCount = spawnableChunkCount; this.mobCategoryCounts = mobCategoryCounts; this.spawnPotential = spawnPotential; this.localMobCapCalculator = localMobCapCalculator; this.unmodifiableMobCategoryCounts = Object2IntMaps.unmodifiable(mobCategoryCounts); -+ this.playerCap = playerCap; // Leaf ++ this.chunkCap = playerCap; // Leaf - optimize mob spawning } private boolean canSpawn(EntityType entityType, BlockPos pos, ChunkAccess chunk) { -@@ -680,5 +864,30 @@ public final class NaturalSpawner { +@@ -680,5 +864,32 @@ public final class NaturalSpawner { boolean canSpawnForCategoryLocal(MobCategory category, ChunkPos chunkPos) { return this.localMobCapCalculator.canSpawn(category, chunkPos); } + -+ // Leaf start ++ // Leaf start - optimize mob spawning + public void applyPerPlayerMobCount(ServerLevel level) { -+ if (playerCap.isEmpty()) { ++ if (chunkCap.isEmpty()) { + return; + } -+ final var iterator = playerCap.long2ObjectEntrySet().fastIterator(); -+ final var nearbyPlayers = level.moonrise$getNearbyPlayers(); ++ final var iterator = chunkCap.long2ObjectEntrySet().fastIterator(); ++ final ca.spottedleaf.moonrise.common.misc.NearbyPlayers nearbyPlayers = level.moonrise$getNearbyPlayers(); + while (iterator.hasNext()) { -+ final var entry = iterator.next(); -+ final long chunk = entry.getLongKey(); -+ final int[] cap = entry.getValue(); -+ var players = nearbyPlayers.getPlayersByChunk(ChunkPos.getX(chunk), ChunkPos.getZ(chunk), ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.TICK_VIEW_DISTANCE); -+ if (players == null) continue; ++ var entry = iterator.next(); ++ long chunk = entry.getLongKey(); ++ int[] cap = entry.getValue(); ++ ca.spottedleaf.moonrise.common.list.ReferenceList players = nearbyPlayers.getPlayersByChunk(ChunkPos.getX(chunk), ChunkPos.getZ(chunk), ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.TICK_VIEW_DISTANCE); ++ if (players == null) { ++ continue; ++ } + int playersSize = players.size(); -+ var playersRawDataUnchecked = players.getRawDataUnchecked(); ++ net.minecraft.server.level.ServerPlayer[] playersRawDataUnchecked = players.getRawDataUnchecked(); + for (int i = 0; i < playersSize; i++) { + int[] p = playersRawDataUnchecked[i].mobCounts; + for (int j = 0; j < net.minecraft.server.level.ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; j++) { @@ -416,28 +414,28 @@ index f242941ce06d356a025e306efe78c688e9b755c4..ee38a26fd1d9b8d8718a16af4fe01964 + } + } + } -+ // Leaf end ++ // Leaf end - optimize mob spawning } } diff --git a/net/minecraft/world/level/StructureManager.java b/net/minecraft/world/level/StructureManager.java -index fbe93098ce0366054a6da857cd808af1431b6612..a7cadf708bd79abb96fed0d41b4dbc00b265a9a6 100644 +index fbe93098ce0366054a6da857cd808af1431b6612..27a0d52f75f7356dfd9e680dd97c3a9ce87304c6 100644 --- a/net/minecraft/world/level/StructureManager.java +++ b/net/minecraft/world/level/StructureManager.java @@ -181,6 +181,12 @@ public class StructureManager { //SectionPos sectionPos = SectionPos.of(pos); // Leaf - optimise ChunkGenerator#getMobsAt return this.level.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); // Leaf - optimise ChunkGenerator#getMobsAt } -+ // Leaf start ++ // Leaf start - optimize mob spawning + public Map getAllStructuresAtChunk(net.minecraft.world.level.chunk.ChunkAccess chunk) { + //SectionPos sectionPos = SectionPos.of(pos); // Leaf - optimise ChunkGenerator#getMobsAt + return chunk.getAllReferences(); // Leaf - optimise ChunkGenerator#getMobsAt + } -+ // Leaf end ++ // Leaf end - optimize mob spawning public StructureCheckResult checkStructurePresence(ChunkPos chunkPos, Structure structure, StructurePlacement placement, boolean skipKnownStructures) { return this.structureCheck.checkStart(chunkPos, structure, placement, skipKnownStructures); diff --git a/net/minecraft/world/level/biome/MobSpawnSettings.java b/net/minecraft/world/level/biome/MobSpawnSettings.java -index db3b8a237d63255aa9ffd70c88a093002a6bd770..68e53989c13070c27c78abeda8d9dd94f155aa0b 100644 +index db3b8a237d63255aa9ffd70c88a093002a6bd770..4a69f404eee00d8972e9501a76031d4339136b6f 100644 --- a/net/minecraft/world/level/biome/MobSpawnSettings.java +++ b/net/minecraft/world/level/biome/MobSpawnSettings.java @@ -52,7 +52,7 @@ public class MobSpawnSettings { @@ -445,19 +443,19 @@ index db3b8a237d63255aa9ffd70c88a093002a6bd770..68e53989c13070c27c78abeda8d9dd94 ) { this.creatureGenerationProbability = creatureGenerationProbability; - this.spawners = ImmutableMap.copyOf(spawners); -+ this.spawners = com.google.common.collect.Maps.immutableEnumMap(spawners); // Leaf ++ this.spawners = com.google.common.collect.Maps.immutableEnumMap(spawners); // Leaf - optimize mob spawning this.mobSpawnCosts = ImmutableMap.copyOf(mobSpawnCosts); } diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java -index 11c7c299d4affb9e78488590e7db939efe6e3dd9..7ca5f1b09162daf5d588468da101bced9dad7e4e 100644 +index 11c7c299d4affb9e78488590e7db939efe6e3dd9..94192345a732f0341886f44d90f9b979ca1fa780 100644 --- a/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -516,6 +516,35 @@ public abstract class ChunkGenerator { return biome.value().getMobSettings().getMobs(category); } -+ // Leaf start ++ // Leaf start - optimize mob spawning + public WeightedList getMobsAtChunk(Holder biome, StructureManager structureManager, MobCategory category, BlockPos pos, LevelChunk chunk) { + Map allStructuresAt = structureManager.getAllStructuresAtChunk(ChunkPos.asLong(pos) == chunk.getPos().longKey ? chunk : structureManager.level.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.STRUCTURE_REFERENCES)); + @@ -484,7 +482,7 @@ index 11c7c299d4affb9e78488590e7db939efe6e3dd9..7ca5f1b09162daf5d588468da101bced + + return biome.value().getMobSettings().getMobs(category); + } -+ // Leaf end ++ // Leaf end - optimize mob spawning + public void createStructures( RegistryAccess registryAccess, diff --git a/leaf-server/minecraft-patches/features/0270-optimize-random-tick.patch b/leaf-server/minecraft-patches/features/0270-optimize-random-tick.patch index 38eb1d4d..73b08be4 100644 --- a/leaf-server/minecraft-patches/features/0270-optimize-random-tick.patch +++ b/leaf-server/minecraft-patches/features/0270-optimize-random-tick.patch @@ -5,7 +5,7 @@ Subject: [PATCH] optimize random tick diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index 51b4a043c09eef84bf926ea02bf588e9ce900788..8ca23e74011b70a8524fb62d1acd4344c3e71eb8 100644 +index 1c23d82a2034bc4ae61ee9bc6c74b39940d4fc2b..57f45e571b92ff0b4499a97da33c8be746d8abd5 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -648,7 +648,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -36,7 +36,7 @@ index 27da552e2542153a58d6177f592cf30d858c41a9..35fb0770eb385e3837cb29711905c41b final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Paper - optimise random ticking // Leaf - Faster random generator - upcasting ChunkPos pos = chunk.getPos(); diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index a3674ddb883eecb255279375a5e2eece7e016c0f..193009af4e477660ce36edda2658f09983941592 100644 +index a3674ddb883eecb255279375a5e2eece7e016c0f..9249041fb249539b8dffbc0d4d338dc79941650f 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java @@ -152,6 +152,61 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p @@ -58,7 +58,7 @@ index a3674ddb883eecb255279375a5e2eece7e016c0f..193009af4e477660ce36edda2658f099 + leaf$mostTickingSectionIndex = -1; + int most = 0; + for (int i = 0; i < sections.length; i++) { -+ var list = sections[i].moonrise$getTickingBlockList(); ++ ca.spottedleaf.moonrise.common.list.ShortList list = sections[i].moonrise$getTickingBlockList(); + int size = list.size(); + if (size != 0 && leaf$firstTickingSectionIndex == -1) { + leaf$firstTickingSectionIndex = i; diff --git a/leaf-server/minecraft-patches/features/0273-Paw-optimization.patch b/leaf-server/minecraft-patches/features/0273-Paw-optimization.patch index c35a3fac..c202152b 100644 --- a/leaf-server/minecraft-patches/features/0273-Paw-optimization.patch +++ b/leaf-server/minecraft-patches/features/0273-Paw-optimization.patch @@ -100,7 +100,7 @@ index 4535858701b2bb232b9d2feb2af6551526232ddc..e65c62dbe4c1560ae153e4c4344e9194 - // Paper end - detailed watchdog information } diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index f2fccba5ce54cfed9ac76555e8d2860a3070fe1c..2763eed217b65d75c59e8c9049e7225bcf5cca05 100644 +index 57f45e571b92ff0b4499a97da33c8be746d8abd5..c510dac9483d8e44118a29f5312e9876a9211e4e 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -623,8 +623,10 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -115,7 +115,7 @@ index f2fccba5ce54cfed9ac76555e8d2860a3070fe1c..2763eed217b65d75c59e8c9049e7225b + } // Paper end - chunk tick iteration optimisation - // Leaf start + // Leaf start - optimize mob spawning diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java index 35fb0770eb385e3837cb29711905c41b899bac8f..fd6fe51ccac5163e70569484239bebeb79348501 100644 --- a/net/minecraft/server/level/ServerLevel.java diff --git a/leaf-server/src/main/java/org/dreeam/leaf/world/RandomTickSystem.java b/leaf-server/src/main/java/org/dreeam/leaf/world/RandomTickSystem.java index 19e9f161..b9a6420b 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/world/RandomTickSystem.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/world/RandomTickSystem.java @@ -1,5 +1,6 @@ package org.dreeam.leaf.world; +import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; import ca.spottedleaf.moonrise.common.list.ReferenceList; import it.unimi.dsi.fastutil.longs.LongArrayList; import net.minecraft.core.BlockPos; @@ -25,7 +26,7 @@ public final class RandomTickSystem { private final LongArrayList weights = new LongArrayList(); public void tick(ServerLevel world) { - final var random = world.simpleRandom; + final BitRandomSource random = world.simpleRandom; final ReferenceList entityTickingChunks = world.moonrise$getEntityTickingChunks(); final int randomTickSpeed = world.getGameRules().getInt(GameRules.RULE_RANDOMTICKING); @@ -46,7 +47,7 @@ public final class RandomTickSystem { weights.clear(); samples.clear(); - final var fullChunks = world.chunkSource.fullChunks; + final ConcurrentLong2ReferenceChainedHashTable fullChunks = world.chunkSource.fullChunks; final long[] q = queue.elements(); final int l = queue.size(); LevelChunk a = null; @@ -108,7 +109,7 @@ public final class RandomTickSystem { if ((cacheRandom & (TICK_FILTER_MASK << bits)) != 0L) { continue; } - final var chunk = raw[i]; + final LevelChunk chunk = raw[i]; final long count = chunk.leaf$tickingBlocksCount(); if (count != 0L) { long weight = (randomTickSpeed * count * SCALE) / CHUNK_BLOCKS;