mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-19 15:09:25 +00:00
optimize get biome
This commit is contained in:
@@ -4,20 +4,72 @@ Date: Tue, 3 Jun 2025 15:20:40 +0900
|
||||
Subject: [PATCH] optimise getBiome
|
||||
|
||||
|
||||
diff --git a/net/minecraft/advancements/critereon/LocationPredicate.java b/net/minecraft/advancements/critereon/LocationPredicate.java
|
||||
index a26a5311f87873e0d4d26fda9cb8956a32ee81e8..9405f1f211db3fa2d313429866de454ede64d95b 100644
|
||||
--- a/net/minecraft/advancements/critereon/LocationPredicate.java
|
||||
+++ b/net/minecraft/advancements/critereon/LocationPredicate.java
|
||||
@@ -49,7 +49,7 @@ public record LocationPredicate(
|
||||
} else {
|
||||
BlockPos blockPos = BlockPos.containing(x, y, z);
|
||||
boolean isLoaded = level.isLoaded(blockPos);
|
||||
- return (!this.biomes.isPresent() || isLoaded && this.biomes.get().contains(level.getBiome(blockPos)))
|
||||
+ return (!this.biomes.isPresent() || isLoaded && this.biomes.get().contains(level.getBiomeCached(blockPos))) // Leaf - cache getBiome
|
||||
&& (!this.structures.isPresent() || isLoaded && level.structureManager().getStructureWithPieceAt(blockPos, this.structures.get()).isValid())
|
||||
&& (!this.smokey.isPresent() || isLoaded && this.smokey.get() == CampfireBlock.isSmokeyPos(level, blockPos))
|
||||
&& (!this.light.isPresent() || this.light.get().matches(level, blockPos))
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index eb849c57992658005e0f514c6f7923f8ca43bebf..c706f0dacd9c322d9b09d6ee073872c4229818b0 100644
|
||||
index eb849c57992658005e0f514c6f7923f8ca43bebf..29dc898b2586868da961616524eaad824f0a24b3 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -899,6 +899,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.advanceWeatherCycle();
|
||||
}
|
||||
|
||||
+ if (runsNormally && (getGameTime() & 7L) == 7L) this.getBiomeManager().recomputeCache(); // Leaf - cache getBiome
|
||||
+ if (runsNormally && (random.nextInt(32) == 0)) this.getBiomeManager().clearCache(); // Leaf - cache getBiome
|
||||
// Leaf start - SparklyPaper - parallel world ticking
|
||||
if (!org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) {
|
||||
this.moonrise$midTickTasks();
|
||||
diff --git a/net/minecraft/world/level/LevelReader.java b/net/minecraft/world/level/LevelReader.java
|
||||
index 26c8c1e5598daf3550aef05b12218c47bda6618b..91b2fc5b2da6566b05fef1111665b895cadad343 100644
|
||||
--- a/net/minecraft/world/level/LevelReader.java
|
||||
+++ b/net/minecraft/world/level/LevelReader.java
|
||||
@@ -53,6 +53,12 @@ public interface LevelReader extends ca.spottedleaf.moonrise.patches.chunk_syste
|
||||
return this.getBiomeManager().getBiome(pos);
|
||||
}
|
||||
|
||||
+ // Leaf start - cache getBiome
|
||||
+ default Holder<Biome> getBiomeCached(BlockPos pos) {
|
||||
+ return this.getBiomeManager().getBiomeCached(pos);
|
||||
+ }
|
||||
+ // Leaf end - cache getBiome
|
||||
+
|
||||
default Stream<BlockState> getBlockStatesIfLoaded(AABB aabb) {
|
||||
int floor = Mth.floor(aabb.minX);
|
||||
int floor1 = Mth.floor(aabb.maxX);
|
||||
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
|
||||
index ce2621a87dec1befb016b3437ceb2d02ed6d0b75..c0d941af10ffe8c158dab9db40c7c5767b6cfd6e 100644
|
||||
--- a/net/minecraft/world/level/NaturalSpawner.java
|
||||
+++ b/net/minecraft/world/level/NaturalSpawner.java
|
||||
@@ -445,7 +445,7 @@ public final class NaturalSpawner {
|
||||
private static Optional<MobSpawnSettings.SpawnerData> getRandomSpawnMobAt(
|
||||
ServerLevel level, StructureManager structureManager, ChunkGenerator generator, MobCategory category, RandomSource random, BlockPos pos
|
||||
) {
|
||||
- Holder<Biome> biome = level.getBiome(pos);
|
||||
+ Holder<Biome> biome = level.getBiomeCached(pos); // Leaf - cache getBiome
|
||||
return category == MobCategory.WATER_AMBIENT && biome.is(BiomeTags.REDUCED_WATER_AMBIENT_SPAWNS) && random.nextFloat() < 0.98F
|
||||
? Optional.empty()
|
||||
: mobsAt(level, structureManager, generator, category, pos, biome).getRandom(random);
|
||||
@@ -462,7 +462,7 @@ public final class NaturalSpawner {
|
||||
) {
|
||||
return isInNetherFortressBounds(pos, level, category, structureManager)
|
||||
? NetherFortressStructure.FORTRESS_ENEMIES
|
||||
- : generator.getMobsAt(biome != null ? biome : level.getBiome(pos), structureManager, category, pos);
|
||||
+ : generator.getMobsAt(biome != null ? biome : level.getBiomeCached(pos), structureManager, category, pos); // Leaf - cache getBiome
|
||||
}
|
||||
|
||||
public static boolean isInNetherFortressBounds(BlockPos pos, ServerLevel level, MobCategory category, StructureManager structureManager) {
|
||||
diff --git a/net/minecraft/world/level/biome/BiomeManager.java b/net/minecraft/world/level/biome/BiomeManager.java
|
||||
index a48175a7ebb1788ace46395621ed78d910178a53..2ce1754e0cf854468791688752a7d16c76917d3b 100644
|
||||
index a48175a7ebb1788ace46395621ed78d910178a53..c9e3011ff873ace4d25727a5d82e249b8f028de0 100644
|
||||
--- a/net/minecraft/world/level/biome/BiomeManager.java
|
||||
+++ b/net/minecraft/world/level/biome/BiomeManager.java
|
||||
@@ -15,6 +15,10 @@ public class BiomeManager {
|
||||
@@ -31,56 +83,48 @@ index a48175a7ebb1788ace46395621ed78d910178a53..2ce1754e0cf854468791688752a7d16c
|
||||
|
||||
public BiomeManager(BiomeManager.NoiseBiomeSource noiseBiomeSource, long biomeZoomSeed) {
|
||||
this.noiseBiomeSource = noiseBiomeSource;
|
||||
@@ -29,7 +33,28 @@ public class BiomeManager {
|
||||
@@ -29,6 +33,40 @@ public class BiomeManager {
|
||||
return new BiomeManager(newSource, this.biomeZoomSeed);
|
||||
}
|
||||
|
||||
+ // Leaf start - cache getBiome
|
||||
+ public synchronized void recomputeCache() {
|
||||
+ public void clearCache() {
|
||||
+ java.util.Arrays.fill(this.biomeCache, null);
|
||||
+ }
|
||||
+ // Leaf end - cache getBiome
|
||||
+
|
||||
public Holder<Biome> getBiome(BlockPos pos) {
|
||||
+ // Leaf start - cache getBiome
|
||||
+ long packedPos = pos.asLong();
|
||||
+ public Holder<Biome> getBiomeCached(BlockPos pos) {
|
||||
+ int xMinus2 = pos.getX() - 2;
|
||||
+ int yMinus2 = pos.getY() - 2;
|
||||
+ int zMinus2 = pos.getZ() - 2;
|
||||
+ int x = xMinus2 >> 2;
|
||||
+ int y = yMinus2 >> 2;
|
||||
+ int z = zMinus2 >> 2;
|
||||
+ long packedPos = BlockPos.asLong(x, y, z);
|
||||
+ long hash = packedPos;
|
||||
+ hash = (hash ^ (hash >>> 32)) * 0xff51afd7ed558ccdL;
|
||||
+ hash = (hash ^ (hash >>> 32)) * 0xc4ceb9fe1a85ec53L;
|
||||
+ hash = (hash ^ (hash >>> 32)) & 65535L;
|
||||
+ synchronized (this) {
|
||||
+ if (biomeCachePos[(int) hash] == packedPos) {
|
||||
+ Holder<Biome> biome = biomeCache[(int) hash];
|
||||
+ if (biome != null) {
|
||||
+ return biome;
|
||||
+ }
|
||||
+
|
||||
+ long pos1 = biomeCachePos[(int) hash];
|
||||
+ if (pos1 == packedPos) {
|
||||
+ Holder<Biome> biome = biomeCache[(int) hash];
|
||||
+ if (biome != null) {
|
||||
+ return biome;
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaf end - cache getBiome
|
||||
+
|
||||
+ Holder<Biome> biome = getBiome(pos);
|
||||
+
|
||||
+ biomeCache[(int) hash] = biome;
|
||||
+ biomeCachePos[(int) hash] = packedPos;
|
||||
+
|
||||
+ return biome;
|
||||
+ }
|
||||
+ // Leaf end - cache getBiome
|
||||
+
|
||||
public Holder<Biome> getBiome(BlockPos pos) {
|
||||
// Leaf start - Carpet-Fixes - Optimized getBiome method
|
||||
int xMinus2 = pos.getX() - 2;
|
||||
int yMinus2 = pos.getY() - 2;
|
||||
@@ -85,11 +110,18 @@ public class BiomeManager {
|
||||
smallestDist = biomeDist;
|
||||
}
|
||||
}
|
||||
- return this.noiseBiomeSource.getNoiseBiome(
|
||||
+ // Leaf start - cache getBiome
|
||||
+ Holder<Biome> biome = this.noiseBiomeSource.getNoiseBiome(
|
||||
(smallestX & 4) == 0 ? x : x + 1,
|
||||
(smallestX & 2) == 0 ? y : y + 1,
|
||||
(smallestX & 1) == 0 ? z : z + 1
|
||||
);
|
||||
+ synchronized (this) {
|
||||
+ biomeCache[(int) hash] = biome;
|
||||
+ biomeCachePos[(int) hash] = packedPos;
|
||||
+ }
|
||||
+ return biome;
|
||||
+ // Leaf end - cache getBiome
|
||||
// Leaf end - Carpet-Fixes - Optimized getBiome method
|
||||
}
|
||||
|
||||
@@ -126,9 +158,18 @@ public class BiomeManager {
|
||||
@@ -126,9 +164,18 @@ public class BiomeManager {
|
||||
return Mth.square(zNoise + fiddle2) + Mth.square(yNoise + fiddle1) + Mth.square(xNoise + fiddle);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ Subject: [PATCH] optimise NaturalSpawner#spawnForChunk
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
|
||||
index ce2621a87dec1befb016b3437ceb2d02ed6d0b75..a6831e701a0ffbc91ea947c09c39ac7d919d1870 100644
|
||||
index c0d941af10ffe8c158dab9db40c7c5767b6cfd6e..bbbb1b1f37406d86d15dca107e8b4f3e614a280d 100644
|
||||
--- a/net/minecraft/world/level/NaturalSpawner.java
|
||||
+++ b/net/minecraft/world/level/NaturalSpawner.java
|
||||
@@ -156,8 +156,15 @@ public final class NaturalSpawner {
|
||||
@@ -43,14 +43,20 @@ index ce2621a87dec1befb016b3437ceb2d02ed6d0b75..a6831e701a0ffbc91ea947c09c39ac7d
|
||||
if (spawnCount == 0) {
|
||||
chunk.failedSpawnAttempts[mobCategory.ordinal()]++;
|
||||
} else {
|
||||
@@ -275,24 +289,48 @@ public final class NaturalSpawner {
|
||||
@@ -275,24 +289,53 @@ public final class NaturalSpawner {
|
||||
StructureManager structureManager = level.structureManager();
|
||||
ChunkGenerator generator = level.getChunkSource().getGenerator();
|
||||
int y = pos.getY();
|
||||
+ int posX = pos.getX(); // Leaf
|
||||
+ int posZ = pos.getZ(); // Leaf
|
||||
int i = 0; // Paper - throttle failed spawn attempts
|
||||
BlockState blockState = level.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn
|
||||
- BlockState blockState = level.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn
|
||||
+ // Leaf start
|
||||
+ if (!level.getWorldBorder().isWithinBounds(pos) || level.isOutsideBuildHeight(pos)) {
|
||||
+ return i;
|
||||
+ }
|
||||
+ BlockState blockState = chunk.getPos().longKey == ChunkPos.asLong(pos) ? chunk.getBlockState(posX, y, posZ) : level.getBlockStateIfLoaded(pos);
|
||||
+ // Leaf end
|
||||
if (blockState != null && !blockState.isRedstoneConductor(chunk, pos)) { // Paper - don't load chunks for mob spawn
|
||||
- BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
|
||||
+ BlockPos.MutableBlockPos mutableBlockPos = pos instanceof BlockPos.MutableBlockPos pos2 ? pos2 : new BlockPos.MutableBlockPos(); // Leaf
|
||||
@@ -99,7 +105,7 @@ index ce2621a87dec1befb016b3437ceb2d02ed6d0b75..a6831e701a0ffbc91ea947c09c39ac7d
|
||||
mutableBlockPos.set(x, y, z);
|
||||
double d = x + 0.5;
|
||||
double d1 = z + 0.5;
|
||||
@@ -368,8 +406,8 @@ public final class NaturalSpawner {
|
||||
@@ -368,8 +411,8 @@ public final class NaturalSpawner {
|
||||
|
||||
private static boolean isRightDistanceToPlayerAndSpawnPoint(ServerLevel level, ChunkAccess chunk, BlockPos.MutableBlockPos pos, double distance) {
|
||||
return !(distance <= 576.0)
|
||||
@@ -110,7 +116,7 @@ index ce2621a87dec1befb016b3437ceb2d02ed6d0b75..a6831e701a0ffbc91ea947c09c39ac7d
|
||||
}
|
||||
|
||||
// Paper start - PreCreatureSpawnEvent
|
||||
@@ -474,6 +512,17 @@ public final class NaturalSpawner {
|
||||
@@ -474,6 +517,17 @@ public final class NaturalSpawner {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
24
leaf-server/paper-patches/features/0039-cache-getBiome.patch
Normal file
24
leaf-server/paper-patches/features/0039-cache-getBiome.patch
Normal file
@@ -0,0 +1,24 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: hayanesuru <hayanesuru@outlook.jp>
|
||||
Date: Tue, 3 Jun 2025 18:51:44 +0900
|
||||
Subject: [PATCH] cache getBiome
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
|
||||
index 09e87552159e24603aa9a4f658ab4449d7eaeb0a..cfe6d74fa06e19c33e6342c76ca99e473840a65b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
|
||||
@@ -302,6 +302,13 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel {
|
||||
return this.handle.getBiome(pos);
|
||||
}
|
||||
|
||||
+ // Leaf start - cache getBiome
|
||||
+ @Override
|
||||
+ public Holder<Biome> getBiomeCached(BlockPos pos) {
|
||||
+ return this.handle.getBiomeCached(pos);
|
||||
+ }
|
||||
+ // Leaf end - cache getBiome
|
||||
+
|
||||
@Override
|
||||
public Stream<BlockState> getBlockStatesIfLoaded(AABB box) {
|
||||
return this.handle.getBlockStatesIfLoaded(box);
|
||||
Reference in New Issue
Block a user