From 404bffa0107aee6aaaba716c4beaf4fcf36d3f73 Mon Sep 17 00:00:00 2001 From: hayanesuru Date: Thu, 2 Oct 2025 21:48:27 +0900 Subject: [PATCH] Fix cache biome chunk pos (#514) * fix cache biome chunk pos * move up --- ...e-for-mob-spawning-and-advancements.patch} | 126 ++++++------------ 1 file changed, 40 insertions(+), 86 deletions(-) rename leaf-server/minecraft-patches/features/{0244-cache-getBiome.patch => 0244-cache-biome-for-mob-spawning-and-advancements.patch} (60%) diff --git a/leaf-server/minecraft-patches/features/0244-cache-getBiome.patch b/leaf-server/minecraft-patches/features/0244-cache-biome-for-mob-spawning-and-advancements.patch similarity index 60% rename from leaf-server/minecraft-patches/features/0244-cache-getBiome.patch rename to leaf-server/minecraft-patches/features/0244-cache-biome-for-mob-spawning-and-advancements.patch index 1b5a645d..e7a67b41 100644 --- a/leaf-server/minecraft-patches/features/0244-cache-getBiome.patch +++ b/leaf-server/minecraft-patches/features/0244-cache-biome-for-mob-spawning-and-advancements.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: hayanesuru Date: Tue, 3 Jun 2025 15:20:40 +0900 -Subject: [PATCH] cache getBiome +Subject: [PATCH] cache biome for mob spawning and advancements diff --git a/net/minecraft/advancements/critereon/LocationPredicate.java b/net/minecraft/advancements/critereon/LocationPredicate.java @@ -57,7 +57,7 @@ index 838146e997a2033c3d2a96602a252178093d263e..bb655318f49242858e2c25d5469705c0 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..b8a0fa20101fa3831e34494fd56690343ff8d57e 100644 +index a48175a7ebb1788ace46395621ed78d910178a53..66084a596ecbfb47902ee0a779a811410d01513f 100644 --- a/net/minecraft/world/level/biome/BiomeManager.java +++ b/net/minecraft/world/level/biome/BiomeManager.java @@ -15,10 +15,23 @@ public class BiomeManager { @@ -84,113 +84,67 @@ index a48175a7ebb1788ace46395621ed78d910178a53..b8a0fa20101fa3831e34494fd5669034 } public static long obfuscateSeed(long seed) { -@@ -29,6 +42,105 @@ public class BiomeManager { - return new BiomeManager(newSource, this.biomeZoomSeed); +@@ -30,10 +43,36 @@ public class BiomeManager { } + public Holder getBiome(BlockPos pos) { +- // Leaf start - Carpet-Fixes - Optimized getBiome method ++ return getBiome(null, pos.getX() - 2, pos.getY() - 2, pos.getZ() - 2); // Leaf - cache getBiome ++ } ++ + // Leaf start - cache getBiome + public Holder getBiomeCached(@org.jetbrains.annotations.Nullable net.minecraft.world.level.chunk.LevelChunk chunk, BlockPos pos) { + if (biomeCache == null) { + return getBiome(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; -+ -+ long pos1 = biomeCachePos[(int) hash]; -+ if (pos1 == packedPos) { -+ Holder biome = biomeCache[(int) hash]; + int xMinus2 = pos.getX() - 2; + int yMinus2 = pos.getY() - 2; + int zMinus2 = pos.getZ() - 2; ++ long packedPos = BlockPos.asLong(xMinus2 >> 2, yMinus2 >> 2, zMinus2 >> 2); ++ int hash = (int) (it.unimi.dsi.fastutil.HashCommon.mix(packedPos) & 65535L); ++ if (biomeCachePos[hash] == packedPos) { ++ Holder biome = biomeCache[hash]; + if (biome != null) { + return biome; + } + } + -+ Holder biome = getBiomeCachedChunk(chunk, pos); ++ Holder biome = getBiome(chunk, xMinus2, yMinus2, zMinus2); + -+ biomeCache[(int) hash] = biome; -+ biomeCachePos[(int) hash] = packedPos; ++ biomeCache[hash] = biome; ++ biomeCachePos[hash] = packedPos; + + return biome; + } -+ private Holder getBiomeCachedChunk(@org.jetbrains.annotations.Nullable net.minecraft.world.level.chunk.LevelChunk chunk, BlockPos pos) { ++ ++ private Holder getBiome(@org.jetbrains.annotations.Nullable net.minecraft.world.level.chunk.LevelChunk chunk, int xMinus2, int yMinus2, int zMinus2) { + // Leaf start - Carpet-Fixes - Optimized getBiome method -+ int xMinus2 = pos.getX() - 2; -+ int yMinus2 = pos.getY() - 2; -+ int zMinus2 = pos.getZ() - 2; -+ int x = xMinus2 >> 2; // BlockPos to BiomePos -+ int y = yMinus2 >> 2; -+ int z = zMinus2 >> 2; -+ double quartX = (double) (xMinus2 & 3) / 4.0; // quartLocal divided by 4 -+ double quartY = (double) (yMinus2 & 3) / 4.0; // 0/4, 1/4, 2/4, 3/4 -+ double quartZ = (double) (zMinus2 & 3) / 4.0; // [0, 0.25, 0.5, 0.75] -+ int smallestX = 0; -+ double smallestDist = Double.POSITIVE_INFINITY; -+ for (int biomeX = 0; biomeX < 8; ++biomeX) { -+ boolean everyOtherQuad = (biomeX & 4) == 0; // 1 1 1 1 0 0 0 0 -+ boolean everyOtherPair = (biomeX & 2) == 0; // 1 1 0 0 1 1 0 0 -+ boolean everyOther = (biomeX & 1) == 0; // 1 0 1 0 1 0 1 0 -+ double quartXX = everyOtherQuad ? quartX : quartX - 1.0; //[-1.0,-0.75,-0.5,-0.25,0.0,0.25,0.5,0.75] -+ double quartYY = everyOtherPair ? quartY : quartY - 1.0; -+ double quartZZ = everyOther ? quartZ : quartZ - 1.0; -+ -+ //This code block is new -+ double maxQuartYY = 0.0, maxQuartZZ = 0.0; -+ if (biomeX != 0) { -+ maxQuartYY = Mth.square(Math.max(quartYY + maxOffset, Math.abs(quartYY - maxOffset))); -+ maxQuartZZ = Mth.square(Math.max(quartZZ + maxOffset, Math.abs(quartZZ - maxOffset))); -+ double maxQuartXX = Mth.square(Math.max(quartXX + maxOffset, Math.abs(quartXX - maxOffset))); -+ if (smallestDist < maxQuartXX + maxQuartYY + maxQuartZZ) continue; -+ } -+ int xx = everyOtherQuad ? x : x + 1; -+ int yy = everyOtherPair ? y : y + 1; -+ int zz = everyOther ? z : z + 1; -+ -+ //I transferred the code from method_38106 to here, so I could call continue halfway through -+ long seed = LinearCongruentialGenerator.next(this.biomeZoomSeed, xx); -+ seed = LinearCongruentialGenerator.next(seed, yy); -+ seed = LinearCongruentialGenerator.next(seed, zz); -+ seed = LinearCongruentialGenerator.next(seed, xx); -+ seed = LinearCongruentialGenerator.next(seed, yy); -+ seed = LinearCongruentialGenerator.next(seed, zz); -+ double offsetX = getFiddle(seed); -+ double sqrX = Mth.square(quartXX + offsetX); -+ if (biomeX != 0 && smallestDist < sqrX + maxQuartYY + maxQuartZZ) continue; //skip the rest of the loop -+ seed = LinearCongruentialGenerator.next(seed, this.biomeZoomSeed); -+ double offsetY = getFiddle(seed); -+ double sqrY = Mth.square(quartYY + offsetY); -+ if (biomeX != 0 && smallestDist < sqrX + sqrY + maxQuartZZ) continue; // skip the rest of the loop -+ seed = LinearCongruentialGenerator.next(seed, this.biomeZoomSeed); -+ double offsetZ = getFiddle(seed); -+ double biomeDist = sqrX + sqrY + Mth.square(quartZZ + offsetZ); -+ -+ if (smallestDist > biomeDist) { -+ smallestX = biomeX; -+ smallestDist = biomeDist; -+ } -+ } + int x = xMinus2 >> 2; // BlockPos to BiomePos + int y = yMinus2 >> 2; + int z = zMinus2 >> 2; +@@ -85,13 +124,16 @@ public class BiomeManager { + smallestDist = biomeDist; + } + } +- return this.noiseBiomeSource.getNoiseBiome( +- (smallestX & 4) == 0 ? x : x + 1, +- (smallestX & 2) == 0 ? y : y + 1, +- (smallestX & 1) == 0 ? z : z + 1 +- ); + int x1 = (smallestX & 4) == 0 ? x : x + 1; + int y1 = (smallestX & 2) == 0 ? y : y + 1; -+ int z1 = (smallestX & 1) == 0 ? z : z + 1; -+ if (chunk != null && chunk.locX == x >> 2 && chunk.locZ == z >> 2) { ++ int z1 = (smallestX & 1) == 0 ? z : z + 1; ++ if (chunk != null && chunk.locX == x1 >> 2 && chunk.locZ == z1 >> 2) { + return chunk.getNoiseBiome(x1, y1, z1); + } + return this.noiseBiomeSource.getNoiseBiome(x1, y1, z1); -+ // Leaf end - Carpet-Fixes - Optimized getBiome method -+ } + // Leaf end - Carpet-Fixes - Optimized getBiome method + } + // Leaf end - cache getBiome -+ - public Holder getBiome(BlockPos pos) { - // Leaf start - Carpet-Fixes - Optimized getBiome method - int xMinus2 = pos.getX() - 2; -@@ -126,9 +238,18 @@ public class BiomeManager { + + public Holder getNoiseBiomeAtPosition(double x, double y, double z) { + int quartPosCoord = QuartPos.fromBlock(Mth.floor(x)); +@@ -126,9 +168,18 @@ public class BiomeManager { return Mth.square(zNoise + fiddle2) + Mth.square(yNoise + fiddle1) + Mth.square(xNoise + fiddle); }