Remove wall-time / unused skip tick protection (#11412)

Spigot still maintains some partial implementation of "tick skipping", a
practice in which the MinecraftServer.currentTick field is updated not
by an increment of one per actual tick, but instead set to
System.currentTimeMillis() / 50. This behaviour means that the tracked
tick may "skip" a tick value in case a previous tick took more than the
expected 50ms.

To compensate for this in important paths, spigot/craftbukkit
implements "wall-time". Instead of incrementing/decrementing ticks on
block entities/entities by one for each call to their tick() method,
they instead increment/decrement important values, like
an ItemEntity's age or pickupDelay, by the difference of
`currentTick - lastTick`, where `lastTick` is the value of
`currentTick` during the last tick() call.

These "fixes" however do not play nicely with minecraft's simulation
distance as entities/block entities implementing the above behaviour
would "catch up" their values when moving from a non-ticking chunk to a
ticking one as their `lastTick` value remains stuck on the last tick in
a ticking chunk and hence lead to a large "catch up" once ticked again.

Paper completely removes the "tick skipping" behaviour (See patch
"Further-improve-server-tick-loop"), making the above precautions
completely unnecessary, which also rids paper of the previous described
incompatibility with non-ticking chunks.
This commit is contained in:
Bjarne Koll 2024-09-19 16:36:07 +02:00 committed by GitHub
parent 5c82955733
commit c5a10665b8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
794 changed files with 402 additions and 282 deletions

View file

@ -714,7 +714,7 @@ index f7197f1347251a37dd0f6d9ffa2f09bc3a4e1233..d0d36a57ec4896bcb74970f8fb24d8f3
} catch (Exception exception) {
if (exception instanceof ReportedException) {
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 5a4cdbc4b92a48c614564e4e421f05a9eb5b072b..d76dae9ce9022308b316080ac48b7030d674cc6b 100644
index e880543e94189fea3ba62eb7fb05ff48bc425299..49de4625c57689a3624ed421c0b03512507c97c3 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -196,7 +196,7 @@ import org.bukkit.craftbukkit.Main;
@ -726,7 +726,7 @@ index 5a4cdbc4b92a48c614564e4e421f05a9eb5b072b..d76dae9ce9022308b316080ac48b7030
public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTask> implements ServerInfo, ChunkIOErrorReporter, CommandSource, AutoCloseable {
@@ -912,6 +912,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -911,6 +911,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
MinecraftServer.LOGGER.info("Stopping server");
@ -734,7 +734,7 @@ index 5a4cdbc4b92a48c614564e4e421f05a9eb5b072b..d76dae9ce9022308b316080ac48b7030
// CraftBukkit start
if (this.server != null) {
this.server.disablePlugins();
@@ -1189,9 +1190,21 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1187,9 +1188,21 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
private boolean haveTime() {
// CraftBukkit start
@ -756,7 +756,7 @@ index 5a4cdbc4b92a48c614564e4e421f05a9eb5b072b..d76dae9ce9022308b316080ac48b7030
private void executeModerately() {
this.runAllTasks();
java.util.concurrent.locks.LockSupport.parkNanos("executing tasks", 1000L);
@@ -1220,9 +1233,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1218,9 +1231,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
protected void waitUntilNextTick() {
@ -768,7 +768,7 @@ index 5a4cdbc4b92a48c614564e4e421f05a9eb5b072b..d76dae9ce9022308b316080ac48b7030
});
}
@@ -1323,9 +1336,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1321,9 +1334,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
public void tickServer(BooleanSupplier shouldKeepTicking) {
@ -787,7 +787,7 @@ index 5a4cdbc4b92a48c614564e4e421f05a9eb5b072b..d76dae9ce9022308b316080ac48b7030
++this.tickCount;
this.tickRateManager.tick();
this.tickChildren(shouldKeepTicking);
@@ -1339,14 +1360,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1337,14 +1358,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
if (this.autosavePeriod > 0 && this.ticksUntilAutosave <= 0) {
this.ticksUntilAutosave = this.autosavePeriod;
// CraftBukkit end
@ -807,7 +807,7 @@ index 5a4cdbc4b92a48c614564e4e421f05a9eb5b072b..d76dae9ce9022308b316080ac48b7030
this.profiler.push("tallying");
long j = Util.getNanos() - i;
int k = this.tickCount % 100;
@@ -1358,8 +1382,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1356,8 +1380,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.logTickMethodTime(i);
this.profiler.pop();
org.spigotmc.WatchdogThread.tick(); // Spigot
@ -817,7 +817,7 @@ index 5a4cdbc4b92a48c614564e4e421f05a9eb5b072b..d76dae9ce9022308b316080ac48b7030
}
private void logTickMethodTime(long tickStartTime) {
@@ -1430,26 +1453,26 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1428,26 +1451,26 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.getPlayerList().getPlayers().forEach((entityplayer) -> {
entityplayer.connection.suspendFlushing();
});
@ -851,7 +851,7 @@ index 5a4cdbc4b92a48c614564e4e421f05a9eb5b072b..d76dae9ce9022308b316080ac48b7030
// Send time updates to everyone, it will get the right time from the world the player is in.
if (this.tickCount % 20 == 0) {
for (int i = 0; i < this.getPlayerList().players.size(); ++i) {
@@ -1457,7 +1480,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1455,7 +1478,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
entityplayer.connection.send(new ClientboundSetTimePacket(entityplayer.level().getGameTime(), entityplayer.getPlayerTime(), entityplayer.level().getGameRules().getBoolean(GameRules.RULE_DAYLIGHT))); // Add support for per player time
}
}
@ -860,7 +860,7 @@ index 5a4cdbc4b92a48c614564e4e421f05a9eb5b072b..d76dae9ce9022308b316080ac48b7030
while (iterator.hasNext()) {
ServerLevel worldserver = (ServerLevel) iterator.next();
@@ -1493,24 +1516,24 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1491,24 +1514,24 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
this.profiler.popPush("connection");