Yatopia/patches/Tuinity/patches/server/0072-Optimise-snow-ice-in-c...

140 lines
8.9 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Fri, 19 Feb 2021 19:27:34 -0800
Subject: [PATCH] Optimise snow & ice in chunk ticking
Avoid the biome lookups most of the time by
hiding them behind the snow/air checks. The biome
checks take up the most here, followed by the block gets.
Soften some of the block gets by passing the chunk to
the biome methods, removing the need to invoke a chunk
lookup.
diff --git a/src/main/java/net/minecraft/server/level/WorldServer.java b/src/main/java/net/minecraft/server/level/WorldServer.java
index a65a79abf8b6a5ddb128ebec066dbb46050053d8..aaf6ada41ba00f891027ca46883a23c06c295c2b 100644
--- a/src/main/java/net/minecraft/server/level/WorldServer.java
+++ b/src/main/java/net/minecraft/server/level/WorldServer.java
@@ -1198,6 +1198,9 @@ public class WorldServer extends World implements GeneratorAccessSeed {
private final BlockPosition.MutableBlockPosition chunkTickMutablePosition = new BlockPosition.MutableBlockPosition();
private final com.destroystokyo.paper.util.math.ThreadUnsafeRandom randomTickRandom = new com.destroystokyo.paper.util.math.ThreadUnsafeRandom();
// Paper end
+ // Tuinity start - optimise chunk ice snow ticking
+ private final BiomeBase[] biomeBaseCache = new BiomeBase[1];
+ // Tuinity end - optimise chunk ice snow ticking
public void a(Chunk chunk, int i) { final int randomTickSpeed = i; // Paper
ChunkCoordIntPair chunkcoordintpair = chunk.getPos();
@@ -1235,28 +1238,32 @@ public class WorldServer extends World implements GeneratorAccessSeed {
gameprofilerfiller.exitEnter("iceandsnow");
if (!this.paperConfig.disableIceAndSnow && this.randomTickRandom.nextInt(16) == 0) { // Paper - Disable ice and snow // Paper - optimise random ticking
// Paper start - optimise chunk ticking
+ // Tuinity start - optimise chunk ice snow ticking
+ BiomeBase[] biomeCache = this.biomeBaseCache;
+ biomeCache[0] = null;
+ // Tuinity start - optimise chunk ice snow ticking
this.getRandomBlockPosition(j, 0, k, 15, blockposition);
int normalY = chunk.getHighestBlockY(HeightMap.Type.MOTION_BLOCKING, blockposition.getX() & 15, blockposition.getZ() & 15);
int downY = normalY - 1;
blockposition.setY(normalY);
// Paper end
- BiomeBase biomebase = this.getBiome(blockposition);
+ //BiomeBase biomebase = this.getBiome(blockposition); // Tuinity - lazily-get biome
// Paper start - optimise chunk ticking
blockposition.setY(downY);
- if (biomebase.a(this, blockposition)) {
+ if (BiomeBase.canTurnWaterIntoIce(this, blockposition, true, chunk, biomeCache)) { // Tuinity - add chunk parameter, avoid biome lookup
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.ICE.getBlockData(), null); // CraftBukkit
// Paper end
}
blockposition.setY(normalY); // Paper
- if (flag && biomebase.b(this, blockposition)) {
+ if (flag && BiomeBase.canTurnAirIntoSnow(this, blockposition, chunk, biomeCache)) {
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.SNOW.getBlockData(), null); // CraftBukkit
}
// Paper start - optimise chunk ticking
blockposition.setY(downY);
- if (flag && this.getBiome(blockposition).c() == BiomeBase.Precipitation.RAIN) {
+ if (flag && chunk.getType(blockposition).getBlock() instanceof net.minecraft.world.level.block.BlockCauldron && this.getBiome(blockposition).c() == BiomeBase.Precipitation.RAIN) { // Tuinity - only cauldron uses that method, and it's not likely to hit. So, avoid the expensive biome lookup and replace it with a block lookup TODO check on update for overrides
chunk.getType(blockposition).getBlock().c((World) this, blockposition);
// Paper end
}
diff --git a/src/main/java/net/minecraft/world/level/biome/BiomeBase.java b/src/main/java/net/minecraft/world/level/biome/BiomeBase.java
index 15096a9c2719b8b4c099f62d0a1c808e56b63a8e..9bbd175f7e20591bbefdbddcb5e998e7098c5adb 100644
--- a/src/main/java/net/minecraft/world/level/biome/BiomeBase.java
+++ b/src/main/java/net/minecraft/world/level/biome/BiomeBase.java
@@ -175,14 +175,33 @@ public final class BiomeBase {
}
public boolean a(IWorldReader iworldreader, BlockPosition blockposition, boolean flag) {
- if (this.getAdjustedTemperature(blockposition) >= 0.15F) {
+ // Tuinity start - add chunk parameter and lazily get biome
+ return canTurnWaterIntoIce(iworldreader, blockposition, flag, null, new BiomeBase[] { this });
+ }
+ public static boolean canTurnWaterIntoIce(IWorldReader iworldreader, BlockPosition blockposition, boolean flag, IChunkAccess chunk, BiomeBase[] biomeAbove) {
+ // Tuinity end - add chunk parameter and lazily get biome
+ if (false && biomeAbove[0].getAdjustedTemperature(blockposition) >= 0.15F) { // Tuinity - move this down, this check is expensive
return false;
} else {
if (blockposition.getY() >= 0 && blockposition.getY() < 256 && iworldreader.getBrightness(EnumSkyBlock.BLOCK, blockposition) < 10) {
- IBlockData iblockdata = iworldreader.getType(blockposition);
- Fluid fluid = iworldreader.getFluid(blockposition);
+ // Tuinity start - add chunk parameter
+ if (chunk == null) {
+ chunk = iworldreader.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4);
+ }
+ // Tuinity end - add chunk parameter
+ IBlockData iblockdata = chunk.getType(blockposition); // Tuinity - skip chunk lookup, we got the chunk
+ Fluid fluid = iblockdata.getFluid(); // Tuinity - skip another block lookup, we have the blockdata
if (fluid.getType() == FluidTypes.WATER && iblockdata.getBlock() instanceof BlockFluids) {
+ // Tuinity start - moved down from top, only run when we actually encounter water
+ if (biomeAbove[0] == null) {
+ // lazily-get biome
+ biomeAbove[0] = iworldreader.getBiome(blockposition.up()); // TODO - avoid blockpos alloc
+ }
+ if (biomeAbove[0].getAdjustedTemperature(blockposition) >= 0.15F) {
+ return false;
+ }
+ // Tuinity end - moved down from top, only run when we actually encounter water
if (!flag) {
return true;
}
@@ -200,13 +219,32 @@ public final class BiomeBase {
}
public boolean b(IWorldReader iworldreader, BlockPosition blockposition) {
- if (this.getAdjustedTemperature(blockposition) >= 0.15F) {
+ // Tuinity start - add chunk parameter and lazily get biome
+ return canTurnAirIntoSnow(iworldreader, blockposition, null, new BiomeBase[]{ this });
+ }
+ public static boolean canTurnAirIntoSnow(IWorldReader iworldreader, BlockPosition blockposition, IChunkAccess chunk, BiomeBase[] biomeAbove) {
+ // Tuinity end - add chunk parameter and lazily get biome
+ if (false && biomeAbove[0].getAdjustedTemperature(blockposition) >= 0.15F) { // Tuinity - move this down, this check is expensive
return false;
} else {
if (blockposition.getY() >= 0 && blockposition.getY() < 256 && iworldreader.getBrightness(EnumSkyBlock.BLOCK, blockposition) < 10) {
- IBlockData iblockdata = iworldreader.getType(blockposition);
+ // Tuinity start - add chunk parameter
+ if (chunk == null) {
+ chunk = iworldreader.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4);
+ }
+ // Tuinity end - add chunk parameter
+ IBlockData iblockdata = chunk.getType(blockposition); // Tuinity - skip chunk lookup, we got the chunk
if (iblockdata.isAir() && Blocks.SNOW.getBlockData().canPlace(iworldreader, blockposition)) {
+ // Tuinity start - moved down from top, only run when we actually encounter water
+ if (biomeAbove[0] == null) {
+ // lazily-get biome
+ biomeAbove[0] = iworldreader.getBiome(blockposition.up()); // TODO - avoid blockpos alloc
+ }
+ if (biomeAbove[0].getAdjustedTemperature(blockposition) >= 0.15F) {
+ return false;
+ }
+ // Tuinity end - moved down from top, only run when we actually encounter water
return true;
}
}