135 lines
6.6 KiB
Diff
135 lines
6.6 KiB
Diff
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 3f540dc05315103ef97fd53628f681c67f7e7c2d..23e564b05ba438924180c91f9b19a60731eedd1b 100644
|
|
--- a/src/main/java/co/aikar/timings/MinecraftTimings.java
|
|
+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java
|
|
@@ -114,6 +114,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 ea5dea8fc6af73afb3b9f79bcb254e1644a3b302..eb5a332f0705dd2e5568749a22f2f318d68010d1 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> {
|
|
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> {
|
|
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
|
|
}
|
|
|
|
public Behavior.Status getStatus() {
|
|
@@ -33,11 +46,19 @@ public abstract class Behavior<E extends LivingEntity> {
|
|
}
|
|
|
|
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;
|
|
@@ -48,11 +69,13 @@ public abstract class Behavior<E extends LivingEntity> {
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
}
|