Skip to content

Commit 2d1834b

Browse files
authored
optimize bounds check for mob spawning (#515)
* some tiny optimize for mob spawning * rebuild patches * Revert "rebuild patches" This reverts commit 760baa7.
1 parent 1c9e032 commit 2d1834b

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

leaf-server/minecraft-patches/features/0242-optimise-ChunkGenerator-getMobsAt.patch

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,15 @@ index 3399922d79a713484e16beb6e4e9985c284ddfb5..fbe93098ce0366054a6da857cd808af1
3030

3131
public StructureCheckResult checkStructurePresence(ChunkPos chunkPos, Structure structure, StructurePlacement placement, boolean skipKnownStructures) {
3232
diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java
33-
index a95a4b39604e3200b69093165a2c48efa3f165ab..fb77cd58542c1a690cbeaa6ed3a4d657de6e619d 100644
33+
index a95a4b39604e3200b69093165a2c48efa3f165ab..2fbf3069cfee45b19276891a21a05d5849ddb70e 100644
3434
--- a/net/minecraft/world/level/chunk/ChunkGenerator.java
3535
+++ b/net/minecraft/world/level/chunk/ChunkGenerator.java
36-
@@ -496,18 +496,20 @@ public abstract class ChunkGenerator {
36+
@@ -492,22 +492,24 @@ public abstract class ChunkGenerator {
37+
public WeightedList<MobSpawnSettings.SpawnerData> getMobsAt(Holder<Biome> biome, StructureManager structureManager, MobCategory category, BlockPos pos) {
38+
Map<Structure, LongSet> allStructuresAt = structureManager.getAllStructuresAt(pos);
39+
40+
- for (Entry<Structure, LongSet> entry : allStructuresAt.entrySet()) {
41+
+ if (!allStructuresAt.isEmpty()) for (Entry<Structure, LongSet> entry : allStructuresAt.entrySet()) { // Leaf - optimise ChunkGenerator#getMobsAt
3742
Structure structure = entry.getKey();
3843
StructureSpawnOverride structureSpawnOverride = structure.spawnOverrides().get(category);
3944
if (structureSpawnOverride != null) {

leaf-server/minecraft-patches/features/0244-optimize-mob-spawning.patch

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ index 641875899b839d4c0012bd49a3f058258a06d99a..9b3863a7456d3d226a2d53eefdfc109b
200200
final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Paper - optimise random ticking // Leaf - Faster random generator - upcasting
201201
ChunkPos pos = chunk.getPos();
202202
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
203-
index bb655318f49242858e2c25d5469705c0c314ed85..a015f0bbff3bb58fd4d28c59620f75dbb125f869 100644
203+
index bb655318f49242858e2c25d5469705c0c314ed85..97a2c3f56dcf1c85cbab6cb3ce2a1fead4f448b1 100644
204204
--- a/net/minecraft/world/level/NaturalSpawner.java
205205
+++ b/net/minecraft/world/level/NaturalSpawner.java
206206
@@ -68,6 +68,7 @@ public final class NaturalSpawner {
@@ -284,7 +284,7 @@ index bb655318f49242858e2c25d5469705c0c314ed85..a015f0bbff3bb58fd4d28c59620f75db
284284
static Biome getRoughBiome(BlockPos pos, ChunkAccess chunk) {
285285
return chunk.getNoiseBiome(QuartPos.fromBlock(pos.getX()), QuartPos.fromBlock(pos.getY()), QuartPos.fromBlock(pos.getZ())).value();
286286
}
287-
@@ -265,28 +328,68 @@ public final class NaturalSpawner {
287+
@@ -265,38 +328,78 @@ public final class NaturalSpawner {
288288
MobCategory category, ServerLevel level, ChunkAccess chunk, BlockPos pos, NaturalSpawner.SpawnPredicate filter, NaturalSpawner.AfterSpawnCallback callback, final int maxSpawns, final @Nullable Consumer<Entity> trackEntity, final boolean nothing
289289
// Paper PR end - throttle failed spawn attempts
290290
) {
@@ -303,7 +303,7 @@ index bb655318f49242858e2c25d5469705c0c314ed85..a015f0bbff3bb58fd4d28c59620f75db
303303
+ int posZ = pos.getZ();
304304
int i = 0; // Paper PR - throttle failed spawn attempts
305305
- BlockState blockState = level.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn
306-
+ BlockState blockState = level.getWorldBorder().isWithinBounds(pos) ? (ChunkPos.asLong(pos) == levelChunk.getPos().longKey ? levelChunk.getBlockStateFinal(posX, y, posZ) : level.getBlockStateIfLoaded(pos)) : null; // Paper - don't load chunks for mob spawn // Leaf
306+
+ BlockState blockState = ChunkPos.asLong(pos) == chunk.coordinateKey ? levelChunk.getBlockStateFinal(posX, y, posZ) : level.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn // Leaf
307307
if (blockState != null && !blockState.isRedstoneConductor(chunk, pos)) { // Paper - don't load chunks for mob spawn
308308
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
309309
//int i = 0; // Paper PR - throttle failed spawn attempts - move up
@@ -360,9 +360,11 @@ index bb655318f49242858e2c25d5469705c0c314ed85..a015f0bbff3bb58fd4d28c59620f75db
360360
mutableBlockPos.set(x, y, z);
361361
double d = x + 0.5;
362362
double d1 = z + 0.5;
363-
@@ -295,8 +398,8 @@ public final class NaturalSpawner {
363+
Player nearestPlayer = level.getNearestPlayer(d, y, d1, -1.0, level.purpurConfig.mobSpawningIgnoreCreativePlayers); // Purpur - mob spawning option to ignore creative players
364+
if (nearestPlayer != null) {
364365
double d2 = nearestPlayer.distanceToSqr(d, y, d1);
365-
if (level.isLoadedAndInBounds(mutableBlockPos) && isRightDistanceToPlayerAndSpawnPoint(level, chunk, mutableBlockPos, d2)) { // Paper - don't load chunks for mob spawn
366+
- if (level.isLoadedAndInBounds(mutableBlockPos) && isRightDistanceToPlayerAndSpawnPoint(level, chunk, mutableBlockPos, d2)) { // Paper - don't load chunks for mob spawn
367+
+ if ((ChunkPos.asLong(mutableBlockPos) == chunk.coordinateKey || level.isLoadedAndInBounds(mutableBlockPos)) && isRightDistanceToPlayerAndSpawnPoint(level, chunk, mutableBlockPos, d2)) { // Paper - don't load chunks for mob spawn // Leaf - optimize mob spawning
366368
if (spawnerData == null) {
367369
- Optional<MobSpawnSettings.SpawnerData> randomSpawnMobAt = getRandomSpawnMobAt(
368370
- level, structureManager, generator, category, level.random, mutableBlockPos
@@ -474,7 +476,7 @@ index bb655318f49242858e2c25d5469705c0c314ed85..a015f0bbff3bb58fd4d28c59620f75db
474476
+ // Leaf start - optimize mob spawning
475477
+ public static boolean isInNetherFortressBoundsChunk(BlockPos pos, ServerLevel level, MobCategory category, StructureManager structureManager, LevelChunk chunk) {
476478
+ if (category == MobCategory.MONSTER) {
477-
+ @Nullable BlockState blockState = chunk.getPos().longKey == ChunkPos.asLong(pos) ? chunk.getBlockStateFinal(pos.getX(), pos.getY() - 1, pos.getZ()) : level.getBlockStateIfLoaded(pos.below());
479+
+ @Nullable BlockState blockState = chunk.coordinateKey == ChunkPos.asLong(pos) ? chunk.getBlockStateFinal(pos.getX(), pos.getY() - 1, pos.getZ()) : level.getBlockStateIfLoaded(pos.below());
478480
+ if (blockState == null || !blockState.is(Blocks.NETHER_BRICKS)) return false;
479481
+ Structure structure = structureManager.registryAccess().lookupOrThrow(Registries.STRUCTURE).getValue(BuiltinStructures.FORTRESS);
480482
+ return structure != null && structureManager.getStructureAt(pos, structure).isValid();
@@ -582,7 +584,7 @@ index db3b8a237d63255aa9ffd70c88a093002a6bd770..4a69f404eee00d8972e9501a76031d43
582584
}
583585

584586
diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java
585-
index fb77cd58542c1a690cbeaa6ed3a4d657de6e619d..e0267e84c8fd2267b047590d712728e963d165f2 100644
587+
index 2fbf3069cfee45b19276891a21a05d5849ddb70e..0720fe1a1112519dcbfc9f2f0ce123d86d66fc58 100644
586588
--- a/net/minecraft/world/level/chunk/ChunkGenerator.java
587589
+++ b/net/minecraft/world/level/chunk/ChunkGenerator.java
588590
@@ -516,6 +516,35 @@ public abstract class ChunkGenerator {
@@ -591,16 +593,16 @@ index fb77cd58542c1a690cbeaa6ed3a4d657de6e619d..e0267e84c8fd2267b047590d712728e9
591593

592594
+ // Leaf start - optimize mob spawning
593595
+ public WeightedList<MobSpawnSettings.SpawnerData> getMobsAtChunk(Holder<Biome> biome, StructureManager structureManager, MobCategory category, BlockPos pos, ChunkAccess chunk) {
594-
+ Map<Structure, LongSet> allStructuresAt = ChunkPos.asLong(pos) == chunk.getPos().longKey ? structureManager.getAllStructuresAtChunk(chunk) : structureManager.getAllStructuresAt(pos);
596+
+ Map<Structure, LongSet> allStructuresAt = ChunkPos.asLong(pos) == chunk.coordinateKey ? structureManager.getAllStructuresAtChunk(chunk) : structureManager.getAllStructuresAt(pos);
595597
+
596-
+ for (Entry<Structure, LongSet> entry : allStructuresAt.entrySet()) {
598+
+ if (!allStructuresAt.isEmpty()) for (Entry<Structure, LongSet> entry : allStructuresAt.entrySet()) {
597599
+ Structure structure = entry.getKey();
598600
+ StructureSpawnOverride structureSpawnOverride = structure.spawnOverrides().get(category);
599601
+ if (structureSpawnOverride != null) {
600602
+ // Leaf start - optimise ChunkGenerator#getMobsAt
601603
+ for (long l : entry.getValue()) {
602604
+ StructureStart startForStructure = structureManager.getStartForStructure(
603-
+ null, structure, chunk.getPos().longKey == l ? chunk : structureManager.level.getChunk(ChunkPos.getX(l), ChunkPos.getZ(l), ChunkStatus.STRUCTURE_STARTS)
605+
+ null, structure, chunk.coordinateKey == l ? chunk : structureManager.level.getChunk(ChunkPos.getX(l), ChunkPos.getZ(l), ChunkStatus.STRUCTURE_STARTS)
604606
+ );
605607
+ if (startForStructure != null && startForStructure.isValid()) {
606608
+ if (structureSpawnOverride.boundingBox() == StructureSpawnOverride.BoundingBoxType.PIECE

0 commit comments

Comments
 (0)