From dbea76a0d70ba4af9b8f49966f15e1f7c94c72a8 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Thu, 17 Jul 2025 21:02:58 +0300 Subject: [PATCH] The End Biome Cache --- .../0078-C2ME-The-End-Biome-Cache.patch | 54 +++++++++++++++++++ .../bxteam/divinemc/config/DivineConfig.java | 15 ++++-- 2 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 divinemc-server/minecraft-patches/features/0078-C2ME-The-End-Biome-Cache.patch diff --git a/divinemc-server/minecraft-patches/features/0078-C2ME-The-End-Biome-Cache.patch b/divinemc-server/minecraft-patches/features/0078-C2ME-The-End-Biome-Cache.patch new file mode 100644 index 0000000..da790b7 --- /dev/null +++ b/divinemc-server/minecraft-patches/features/0078-C2ME-The-End-Biome-Cache.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Thu, 17 Jul 2025 20:53:13 +0300 +Subject: [PATCH] C2ME: The End Biome Cache + +This patch is based on the following mixins: +* "com/ishland/c2me/opts/worldgen/vanilla/mixin/the_end_biome_cache/MixinTheEndBiomeSource.java" +By: ishland +As part of: C2ME (https://github.com/RelativityMC/C2ME-fabric) +Licensed under: MIT (https://opensource.org/licenses/MIT) + +diff --git a/net/minecraft/world/level/biome/TheEndBiomeSource.java b/net/minecraft/world/level/biome/TheEndBiomeSource.java +index cf3172be76fa4c7987ed569138439ff42f92fa7f..0545a0dd25917d75b511d507dc19a5ca7d45b9d9 100644 +--- a/net/minecraft/world/level/biome/TheEndBiomeSource.java ++++ b/net/minecraft/world/level/biome/TheEndBiomeSource.java +@@ -55,8 +55,37 @@ public class TheEndBiomeSource extends BiomeSource { + return CODEC; + } + ++ // DivineMC start - C2ME: The End Biome Cache ++ private final ThreadLocal>> cache = ThreadLocal.withInitial(it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap::new); ++ private final int cacheCapacity = org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.endBiomeCacheCapacity; ++ + @Override +- public Holder getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) { ++ public Holder getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler multiNoiseSampler) { ++ if (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.endBiomeCacheEnabled) { ++ return getVanillaNoiseBiome(biomeX, biomeY, biomeZ, multiNoiseSampler); ++ } ++ ++ final long key = net.minecraft.world.level.ChunkPos.asLong(biomeX, biomeZ); ++ final it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap> cacheThreadLocal = cache.get(); ++ final Holder biome = cacheThreadLocal.get(key); ++ ++ if (biome != null) { ++ return biome; ++ } else { ++ final Holder gennedBiome = getVanillaNoiseBiome(biomeX, biomeY, biomeZ, multiNoiseSampler); ++ cacheThreadLocal.put(key, gennedBiome); ++ if (cacheThreadLocal.size() > cacheCapacity) { ++ for (int i = 0; i < cacheCapacity / 16; i ++) { ++ cacheThreadLocal.removeFirst(); ++ } ++ } ++ ++ return gennedBiome; ++ } ++ } ++ // DivineMC end - C2ME: The End Biome Cache ++ ++ private Holder getVanillaNoiseBiome(int x, int y, int z, Climate.Sampler sampler) { // DivineMC - C2ME: The End Biome Cache + int blockPosX = QuartPos.toBlock(x); + int blockPosY = QuartPos.toBlock(y); + int blockPosZ = QuartPos.toBlock(z); diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java b/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java index 42077c2..d60289b 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java @@ -372,6 +372,8 @@ public class DivineConfig { public static long chunkDataCacheLimit = 32678L; public static int maxViewDistance = 32; public static int playerNearChunkDetectionRange = 128; + public static boolean endBiomeCacheEnabled = false; + public static int endBiomeCacheCapacity = 1024; public static boolean smoothBedrockLayer = false; public static boolean enableDensityFunctionCompiler = false; public static boolean enableStructureLayoutOptimizer = true; @@ -428,10 +430,10 @@ public class DivineConfig { "By default, this range is computed to 8, meaning a player must be within an 8 chunk radius of a chunk position to pass.", "Keep in mind the result is rounded to the nearest whole number."); - if (playerNearChunkDetectionRange < 0) { - LOGGER.warn("Invalid player near chunk detection range: {}, resetting to default (128)", playerNearChunkDetectionRange); - playerNearChunkDetectionRange = 128; - } + endBiomeCacheEnabled = getBoolean(ConfigCategory.PERFORMANCE.key("chunks.end-biome-cache-enabled"), endBiomeCacheEnabled, + "Enables the end biome cache, which can accelerate The End worldgen."); + endBiomeCacheCapacity = getInt(ConfigCategory.PERFORMANCE.key("chunks.end-biome-cache-capacity"), endBiomeCacheCapacity, + "The cache capacity for the end biome cache. Only used if end-biome-cache-enabled is true."); smoothBedrockLayer = getBoolean(ConfigCategory.PERFORMANCE.key("chunks.smooth-bedrock-layer"), smoothBedrockLayer, "Smoothens the bedrock layer at the bottom of overworld, and on the top of nether during the world generation."); @@ -455,6 +457,11 @@ public class DivineConfig { "This will not break the structure generation, but it will make the structure layout different than", "if this config was off (breaking vanilla seed parity). The cost of speed may be worth it in large", "modpacks where many structure mods are using very high weight values in their template pools."); + + if (playerNearChunkDetectionRange < 0) { + LOGGER.warn("Invalid player near chunk detection range: {}, resetting to default (128)", playerNearChunkDetectionRange); + playerNearChunkDetectionRange = 128; + } } private static void optimizationSettings() {