Files
Shiroha/shiroha-server/minecraft-patches/features/0058-Pufferfish-Reduce-projectile-chunk-loading.patch
T
NanaChiyo0721 1bb895c165
Shiroha CI / build (push) Canceled after 0s
Shiroha CI / Event File (push) Canceled after 0s
Fix incorrect ticket lock size computing
Yeah this would fully solve the issue of chunk unloading race condition

The same fix was already initially added at "Force clamp grid-exponent to 1~6"
2026-08-09 14:57:32 +08:00

69 lines
3.8 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <mrhua269@gmail.com>
Date: Fri, 1 May 2026 21:47:48 +0800
Subject: [PATCH] Pufferfish: Reduce projectile chunk loading
A part of Pufferfish(https://github.com/Pufferfish-gg/Pufferfish)
Co-authored-by: Paul Sauve <paul@technove.co>
Original patch: https://github.com/pufferfish-gg/Pufferfish/blob/ver/1.21/pufferfish-server/minecraft-patches/features/0006-Reduce-projectile-chunk-loading.patch
Original license(GPL-3.0): https://github.com/pufferfish-gg/Pufferfish/blob/ver/1.21/PATCH-LICENSE
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
index 53970fff0c119b190195e07823d5796a99de9c3b..08e4adac3425a94f9bcf5191883d333cfe5bf5c9 100644
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
@@ -402,6 +402,10 @@ public final class RegionizedWorldData {
private RegionizedServer.WorldLevelData tickData;
+ // Shiroha start - Pufferfish - Reduce projectile chunk loading
+ public long pufferfish$loadedThisTick = 0L;
+ public long pufferfish$loadedTick = 0L;
+ // Shiroha end
// connections
private static final Connection[] EMPTY_CONNECTION_ARRAY = new Connection[0];
private final ReferenceList<Connection> connections = new ReferenceList<>(EMPTY_CONNECTION_ARRAY);
diff --git a/net/minecraft/world/entity/projectile/Projectile.java b/net/minecraft/world/entity/projectile/Projectile.java
index 721e3b083846fd363a31311196bc4c681969215c..cc3aebbd42a876fcc982a9bf1c3dc1bd11f3a4e0 100644
--- a/net/minecraft/world/entity/projectile/Projectile.java
+++ b/net/minecraft/world/entity/projectile/Projectile.java
@@ -58,6 +58,38 @@ public abstract class Projectile extends Entity implements TraceableEntity {
this.setOwner(EntityReference.of(owner));
}
+ // Pufferfish start
+ private int loadedLifetime = 0;
+ @Override
+ public void setPos(double x, double y, double z) {
+ var currRegionData = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegionizedWorldData();
+ // we might run this on a chunk system worker(chunk gen), so skip this check if no world data was fetched
+ if (currRegionData == null || currRegionData.world != this.level()) {
+ return;
+ }
+ long currentTick = currRegionData.getRedstoneGameTime();
+ if (currRegionData.pufferfish$loadedTick != currentTick) {
+ currRegionData.pufferfish$loadedTick = currentTick;
+ currRegionData.pufferfish$loadedThisTick = 0L;
+ }
+ int previousX = Mth.floor(this.getX()) >> 4, previousZ = Mth.floor(this.getZ()) >> 4;
+ int newX = Mth.floor(x) >> 4, newZ = Mth.floor(z) >> 4;
+ if (previousX != newX || previousZ != newZ) {
+ boolean isLoaded = ((net.minecraft.server.level.ServerChunkCache) this.level().getChunkSource()).getChunkAtIfLoadedImmediately(newX, newZ) != null;
+ if (!isLoaded) {
+ if (currRegionData.pufferfish$loadedThisTick > io.nanachiyo0721.shiroha.config.modules.optimizations.ProjectileChunkReduceConfig.maxProjectileLoadsPerTick) {
+ if (++this.loadedLifetime > io.nanachiyo0721.shiroha.config.modules.optimizations.ProjectileChunkReduceConfig.maxProjectileLoadsPerProjectile) {
+ this.discard();
+ }
+ return;
+ }
+ currRegionData.pufferfish$loadedThisTick++;
+ }
+ }
+ super.setPos(x, y, z);
+ }
+ // Pufferfish end
+
// Folia start - region threading
// In general, this is an entire mess. At the time of writing, there are fifty usages of getOwner.
// Usage of this function is to avoid concurrency issues, even if it sacrifices behavior.