spigot/CraftBukkit-Patches/0105-Allow-Capping-Tile-Entity-Tick-Time.patch

131 lines
6.4 KiB
Diff
Raw Normal View History

2019-04-23 09:33:25 +10:00
From caafc3b8af865d9a3c0c12ea9a25375cf178b912 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Fri, 20 Feb 2015 21:39:31 +1100
Subject: [PATCH] Allow Capping (Tile)Entity Tick Time.
This patch adds world configuration options for max-tick-time.entity / max-tick-time.tile which allows setting a hard cap on the amount of time (in milliseconds) that a tick can consume. The default values of 50ms each are very conservative and mean this feature will not activate until the server is well below 15tps (minimum). Values of 20ms each have been reported to provide a good performance increase, however I personally think 25ms for entities and 10-15ms for tiles would give even more significant gains, assuming that these things are not a large priority on your server.
For tiles there is very little tradeoff for this option, as tile ticks are based on wall time for most things, however for entities setting this option too low could lead to jerkiness / lag. The gain however is a faster and more responsive server to other actions such as blocks, chat, combat etc.
This feature was commisioned by Chunkr.
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
2019-04-23 09:33:25 +10:00
index f73d979f..a84a182b 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -133,6 +133,9 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
public final SpigotTimings.WorldTimingsHandler timings; // Spigot
2016-03-01 08:33:06 +11:00
private boolean guardEntityList; // Spigot
public static BlockPosition lastPhysicsProblem; // Spigot
+ private org.spigotmc.TickLimiter entityLimiter;
+ private org.spigotmc.TickLimiter tileLimiter;
+ private int tileTickPosition;
2016-03-01 08:33:06 +11:00
public CraftWorld getWorld() {
return this.world;
@@ -195,6 +198,8 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
2016-03-01 11:23:45 +11:00
this.getServer().addWorld(this.world);
// CraftBukkit end
2016-03-01 08:33:06 +11:00
timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings
+ this.entityLimiter = new org.spigotmc.TickLimiter(spigotConfig.entityMaxTickTime);
+ this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime);
}
2018-08-26 12:00:00 +10:00
public BiomeBase getBiome(BlockPosition blockposition) {
@@ -1102,7 +1107,12 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
timings.entityTick.startTiming(); // Spigot
guardEntityList = true; // Spigot
// CraftBukkit start - Use field for loop variable
- for (this.tickPosition = 0; this.tickPosition < this.entityList.size(); ++this.tickPosition) {
+ int entitiesThisCycle = 0;
2015-02-27 21:14:00 +01:00
+ if (tickPosition < 0) tickPosition = 0;
+ for (entityLimiter.initTick();
+ entitiesThisCycle < entityList.size() && (entitiesThisCycle % 10 != 0 || entityLimiter.shouldContinue());
+ tickPosition++, entitiesThisCycle++) {
+ tickPosition = (tickPosition < entityList.size()) ? tickPosition : 0;
entity = (Entity) this.entityList.get(this.tickPosition);
// CraftBukkit end
2018-07-15 10:00:00 +10:00
Entity entity1 = entity.getVehicle();
@@ -1159,14 +1169,19 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
2015-02-28 11:36:22 +00:00
}
2018-07-15 10:00:00 +10:00
this.J = true;
2017-09-18 20:00:00 +10:00
- Iterator iterator = this.tileEntityListTick.iterator();
-
- while (iterator.hasNext()) {
- TileEntity tileentity = (TileEntity) iterator.next();
+ // Spigot start
2016-03-01 08:33:06 +11:00
+ // Iterator iterator = this.tileEntityListTick.iterator();
+ int tilesThisCycle = 0;
+ for (tileLimiter.initTick();
2016-03-01 08:33:06 +11:00
+ tilesThisCycle < tileEntityListTick.size() && (tilesThisCycle % 10 != 0 || tileLimiter.shouldContinue());
+ tileTickPosition++, tilesThisCycle++) {
2016-03-01 08:33:06 +11:00
+ tileTickPosition = (tileTickPosition < tileEntityListTick.size()) ? tileTickPosition : 0;
+ TileEntity tileentity = (TileEntity) this.tileEntityListTick.get(tileTickPosition);
// Spigot start
if (tileentity == null) {
getServer().getLogger().severe("Spigot has detected a null entity and has removed it, preventing a crash");
- iterator.remove();
+ tilesThisCycle--;
2016-03-01 08:33:06 +11:00
+ this.tileEntityListTick.remove(tileTickPosition--);
continue;
}
// Spigot end
@@ -1197,7 +1212,8 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
}
2018-07-15 10:00:00 +10:00
if (tileentity.x()) {
- iterator.remove();
+ tilesThisCycle--;
2016-03-01 08:33:06 +11:00
+ this.tileEntityListTick.remove(tileTickPosition--);
this.tileEntityList.remove(tileentity);
if (this.isLoaded(tileentity.getPosition())) {
2016-03-01 08:33:06 +11:00
this.getChunkAtWorldCoords(tileentity.getPosition()).d(tileentity.getPosition());
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
2019-04-23 09:33:25 +10:00
index 3e714be7..29a7c48e 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -303,4 +303,13 @@ public class SpigotWorldConfig
{
hangingTickFrequency = getInt( "hanging-tick-frequency", 100 );
}
+
+ public int tileMaxTickTime;
+ public int entityMaxTickTime;
+ private void maxTickTimes()
+ {
+ tileMaxTickTime = getInt("max-tick-time.tile", 50);
+ entityMaxTickTime = getInt("max-tick-time.entity", 50);
+ log("Tile Max Tick Time: " + tileMaxTickTime + "ms Entity max Tick Time: " + entityMaxTickTime + "ms");
+ }
}
diff --git a/src/main/java/org/spigotmc/TickLimiter.java b/src/main/java/org/spigotmc/TickLimiter.java
new file mode 100644
2019-04-23 09:33:25 +10:00
index 00000000..23a39382
--- /dev/null
+++ b/src/main/java/org/spigotmc/TickLimiter.java
@@ -0,0 +1,20 @@
+package org.spigotmc;
+
+public class TickLimiter {
+
+ private final int maxTime;
+ private long startTime;
+
+ public TickLimiter(int maxtime) {
+ this.maxTime = maxtime;
+ }
+
+ public void initTick() {
+ startTime = System.currentTimeMillis();
+ }
+
+ public boolean shouldContinue() {
+ long remaining = System.currentTimeMillis() - startTime;
+ return remaining < maxTime;
+ }
+}
--
2019-04-23 09:33:25 +10:00
2.20.1