Add rate options and timings for sensors and behaviors (#6027)
This commit is contained in:
parent
d6c81c8189
commit
12942dc94b
|
@ -0,0 +1,217 @@
|
|||
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 b9cdbf8acccfd6b207a0116f068168f3b8c8e17d..fe225310e4b62e7bded3521d3ddf4092c25a3645 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) {
|
||||
+ return Timings.ofSafe("Sensor - " + type);
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Get a named timer for the specified tile entity type to track type specific timings.
|
||||
* @param entity
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 171321d4f1b73a25266175dfb5529dfc5cb8a5ca..eb99eed57d45e680f2ae3eea62e5eee72e4dffaa 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -3,14 +3,19 @@ package com.destroystokyo.paper;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
+import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
+
|
||||
+import com.google.common.collect.HashBasedTable;
|
||||
+import com.google.common.collect.Table;
|
||||
import net.minecraft.world.Difficulty;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.monster.Vindicator;
|
||||
import net.minecraft.world.entity.monster.Zombie;
|
||||
import com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray.EngineMode;
|
||||
import org.bukkit.Bukkit;
|
||||
+import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.spigotmc.SpigotWorldConfig;
|
||||
|
||||
@@ -845,5 +850,58 @@ public class PaperWorldConfig {
|
||||
private void playerCrammingDamage() {
|
||||
allowPlayerCrammingDamage = getBoolean("allow-player-cramming-damage", allowPlayerCrammingDamage);
|
||||
}
|
||||
+
|
||||
+ private Table<String, String, Integer> sensorTickRates;
|
||||
+ private Table<String, String, Integer> behaviorTickRates;
|
||||
+ private void tickRates() {
|
||||
+ config.addDefault("world-settings.default.tick-rates.sensor.villager.secondaryplaces", 40);
|
||||
+ config.addDefault("world-settings.default.tick-rates.behavior.villager.positionvalidate", 20);
|
||||
+ log("Tick rates:");
|
||||
+ sensorTickRates = loadTickRates("sensor");
|
||||
+ behaviorTickRates = loadTickRates("behavior");
|
||||
+ }
|
||||
+
|
||||
+ private Table<String, String, Integer> loadTickRates(String type) {
|
||||
+ log(" " + type + ":");
|
||||
+ Table<String, String, Integer> table = HashBasedTable.create();
|
||||
+
|
||||
+ ConfigurationSection typeSection = config.getConfigurationSection("world-settings." + worldName + ".tick-rates." + type);
|
||||
+ if (typeSection == null) {
|
||||
+ typeSection = config.getConfigurationSection("world-settings.default.tick-rates." + type);
|
||||
+ }
|
||||
+ if (typeSection != null) {
|
||||
+ for (String entity : typeSection.getKeys(false)) {
|
||||
+ ConfigurationSection entitySection = typeSection.getConfigurationSection(entity);
|
||||
+ if (entitySection != null) {
|
||||
+ log(" " + entity + ":");
|
||||
+ for (String typeName : entitySection.getKeys(false)) {
|
||||
+ if (entitySection.isInt(typeName)) {
|
||||
+ int tickRate = entitySection.getInt(typeName);
|
||||
+ table.put(entity.toUpperCase(Locale.ROOT), typeName.toUpperCase(Locale.ROOT), tickRate);
|
||||
+ log(" " + typeName + ": " + tickRate);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (table.isEmpty()) {
|
||||
+ log(" None configured");
|
||||
+ }
|
||||
+ return table;
|
||||
+ }
|
||||
+
|
||||
+ public int getBehaviorTickRate(String typeName, String entityType, int def) {
|
||||
+ return getIntOrDefault(behaviorTickRates, typeName, entityType, def);
|
||||
+ }
|
||||
+
|
||||
+ public int getSensorTickRate(String typeName, String entityType, int def) {
|
||||
+ return getIntOrDefault(sensorTickRates, typeName, entityType, def);
|
||||
+ }
|
||||
+
|
||||
+ private int getIntOrDefault(Table<String, String, Integer> table, String rowKey, String columnKey, int def) {
|
||||
+ Integer rate = table.get(columnKey, rowKey);
|
||||
+ return rate != null && rate > -1 ? rate : def;
|
||||
+ }
|
||||
}
|
||||
|
||||
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 b1212e162ba938b3abe0df747a633ba9cbbe57c8..fe2aa0165be6b9d9a82a799b7096a570a70c4cf2 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
|
||||
@@ -14,6 +14,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);
|
||||
@@ -27,6 +31,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 = getClass().getName().startsWith("net.minecraft.") ? getClass().getSimpleName() : getClass().getName();
|
||||
+ key = key.toLowerCase(java.util.Locale.ROOT);
|
||||
+ if (key.startsWith("behavior")) {
|
||||
+ key = key.substring("behavior".length());
|
||||
+ }
|
||||
+ this.configKey = key;
|
||||
+ this.timing = co.aikar.timings.MinecraftTimings.getBehaviorTimings(configKey);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public Behavior.Status getStatus() {
|
||||
@@ -34,11 +47,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 = world.paperConfig.getBehaviorTickRate(this.configKey, entity.getType().id, -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;
|
||||
@@ -49,11 +70,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 f94aa5147c52d2e36d6018f51b85e9dac7a6208a..d9fc867c6414d36d76411ad012d1aff9a6cf6772 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 = getClass().getName().startsWith("net.minecraft.") ? getClass().getSimpleName() : getClass().getName();
|
||||
+ key = key.toLowerCase(java.util.Locale.ROOT);
|
||||
+ if (key.startsWith("sensor")) {
|
||||
+ key = key.substring("sensor".length());
|
||||
+ }
|
||||
+ this.configKey = key;
|
||||
+ this.timing = co.aikar.timings.MinecraftTimings.getSensorTimings(configKey);
|
||||
+ // 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 = world.paperConfig.getSensorTickRate(this.configKey, entity.getType().id, this.scanRate);
|
||||
+ this.timing.startTiming();
|
||||
+ // Paper end
|
||||
this.doTick(world, entity);
|
||||
+ this.timing.stopTiming(); // Paper - sensor timings
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue