aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0641-Rate-options-and-timings-for-sensors-and-behaviors.patch
blob: 297c6b3a06e674058d871146a754b0939fff9748 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Phoenix616 <max@themoep.de>
Date: Mon, 28 Jun 2021 22:38:29 +0100
Subject: [PATCH] Rate options and timings for sensors and behaviors

This adds config options to specify the tick rate for sensors
 and behaviors of different entity types as well as timings
 for those in order to be able to have some metrics as to which
 ones might need tweaking.

diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java
index 59affb62cb487d60e8c3e32decf89d6cb7d22f8d..4d861f9a58f8ea238471af22f387854d855b1801 100644
--- a/src/main/java/co/aikar/timings/MinecraftTimings.java
+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java
@@ -115,6 +115,14 @@ public final class MinecraftTimings {
         return Timings.ofSafe("Minecraft", "## tickEntity - " + entityType + " - " + type, tickEntityTimer);
     }
 
+    public static Timing getBehaviorTimings(String type) {
+        return Timings.ofSafe("## Behavior - " + type);
+    }
+
+    public static Timing getSensorTimings(String type, int rate) {
+        return Timings.ofSafe("## Sensor - " + type + " (Default rate: " + rate + ")");
+    }
+
     /**
      * Get a named timer for the specified tile entity type to track type specific timings.
      * @param entity
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java
index 4ea437253539e3ee533ca9da77a337cbf4d1e807..57ef7fbba3028c28231abf7b7ae78aa019323536 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java
@@ -13,6 +13,10 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
     private long endTimestamp;
     private final int minDuration;
     private final int maxDuration;
+    // Paper start - configurable behavior tick rate and timings
+    private final String configKey;
+    private final co.aikar.timings.Timing timing;
+    // Paper end
 
     public Behavior(Map<MemoryModuleType<?>, MemoryStatus> requiredMemoryState) {
         this(requiredMemoryState, 60);
@@ -26,6 +30,15 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
         this.minDuration = minRunTime;
         this.maxDuration = maxRunTime;
         this.entryCondition = requiredMemoryState;
+        // Paper start - configurable behavior tick rate and timings
+        String key = io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName());
+        int lastSeparator = key.lastIndexOf('.');
+        if (lastSeparator != -1) {
+            key = key.substring(lastSeparator + 1);
+        }
+        this.configKey = key.toLowerCase(java.util.Locale.ROOT);
+        this.timing = co.aikar.timings.MinecraftTimings.getBehaviorTimings(configKey);
+        // Paper end
     }
 
     @Override
@@ -35,11 +48,19 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
 
     @Override
     public final boolean tryStart(ServerLevel world, E entity, long time) {
+        // Paper start - behavior tick rate
+        int tickRate = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.behavior.get(entity.getType(), this.configKey), -1);
+        if (tickRate > -1 && time < this.endTimestamp + tickRate) {
+            return false;
+        }
+        // Paper end
         if (this.hasRequiredMemories(entity) && this.checkExtraStartConditions(world, entity)) {
             this.status = Behavior.Status.RUNNING;
             int i = this.minDuration + world.getRandom().nextInt(this.maxDuration + 1 - this.minDuration);
             this.endTimestamp = time + (long)i;
+            this.timing.startTiming(); // Paper - behavior timings
             this.start(world, entity, time);
+            this.timing.stopTiming(); // Paper - behavior timings
             return true;
         } else {
             return false;
@@ -51,11 +72,13 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
 
     @Override
     public final void tickOrStop(ServerLevel world, E entity, long time) {
+        this.timing.startTiming(); // Paper - behavior timings
         if (!this.timedOut(time) && this.canStillUse(world, entity, time)) {
             this.tick(world, entity, time);
         } else {
             this.doStop(world, entity, time);
         }
+        this.timing.stopTiming(); // Paper - behavior timings
 
     }
 
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java
index 7970eebbd6935402223e6bba962bb8ba7d861dfd..fcdb9bde8e1605e30dde3e580491522d4b62cdc0 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java
@@ -19,8 +19,21 @@ public abstract class Sensor<E extends LivingEntity> {
     private static final TargetingConditions ATTACK_TARGET_CONDITIONS_IGNORE_INVISIBILITY_AND_LINE_OF_SIGHT = TargetingConditions.forCombat().range(16.0D).ignoreLineOfSight().ignoreInvisibilityTesting();
     private final int scanRate;
     private long timeToTick;
+    // Paper start - configurable sensor tick rate and timings
+    private final String configKey;
+    private final co.aikar.timings.Timing timing;
+    // Paper end
 
     public Sensor(int senseInterval) {
+        // Paper start - configurable sensor tick rate and timings
+        String key = io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName());
+        int lastSeparator = key.lastIndexOf('.');
+        if (lastSeparator != -1) {
+            key = key.substring(lastSeparator + 1);
+        }
+        this.configKey = key.toLowerCase(java.util.Locale.ROOT);
+        this.timing = co.aikar.timings.MinecraftTimings.getSensorTimings(configKey, senseInterval);
+        // Paper end
         this.scanRate = senseInterval;
         this.timeToTick = (long)RANDOM.nextInt(senseInterval);
     }
@@ -31,8 +44,12 @@ public abstract class Sensor<E extends LivingEntity> {
 
     public final void tick(ServerLevel world, E entity) {
         if (--this.timeToTick <= 0L) {
-            this.timeToTick = (long)this.scanRate;
+            // Paper start - configurable sensor tick rate and timings
+            this.timeToTick = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.sensor.get(entity.getType(), this.configKey), this.scanRate);
+            this.timing.startTiming();
+            // Paper end
             this.doTick(world, entity);
+            this.timing.stopTiming(); // Paper - sensor timings
         }
 
     }