From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paul Sauve Date: Fri, 15 Jan 2021 19:05:01 -0600 Subject: [PATCH] Pufferfish: Dynamic Activation of Brain Dreeam TODO: waiting Paper dealing with the newGoalRate Original license: GPL v3 Original project: https://github.com/pufferfish-gg/Pufferfish This replaces the current method of ticking an inactive entity's pathfinder 1/4 times with a new method that's dynamic based off how far away it is from a player. If an entity is within 32 blocks, it gets ticked every tick. If it's within 45 blocks, it gets ticked every other tick. If it's within 55 blocks, it gets ticked once every three ticks. (these numbers have since been changed, but the idea is the same.) Airplane Copyright (C) 2020 Technove LLC This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index d27be346b91f390e06702d654058cab4d3f39b8c..e3fdd0677b3029be0ddc5f59489f66e28f5c2853 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -886,6 +886,7 @@ public class ServerLevel extends Level implements WorldGenLevel { org.spigotmc.ActivationRange.activateEntities(this); // Spigot this.timings.entityTick.startTiming(); // Spigot this.entityTickList.forEach((entity) -> { + entity.activatedPriorityReset = false; // Pufferfish - DAB if (!entity.isRemoved()) { if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed entity.discard(); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 5613659b44f83d07a253882e227ee1e604695417..9a87e5cb9708dc0879e4fd70d7cecbfea50c730e 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -427,6 +427,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess private UUID originWorld; public boolean freezeLocked = false; // Paper - Freeze Tick Lock API public boolean fixedPose = false; // Paper - Expand Pose API + public boolean activatedPriorityReset = false; // Pufferfish - DAB + public int activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; // Pufferfish - DAB (golf score) public void setOrigin(@javax.annotation.Nonnull Location location) { this.origin = location.toVector(); diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java index a46bf73c608641bf1f00fd55242de71a0f2ee06e..58298a1f85f462abc4f07deffe913abb1bac9f99 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -316,6 +316,7 @@ public class EntityType implements FeatureElement, EntityTypeT private final boolean canSpawnFarFromPlayer; private final int clientTrackingRange; private final int updateInterval; + public boolean dabEnabled = false; // Pufferfish @Nullable private String descriptionId; @Nullable diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java index e0e7c35fa9c9395eec5b4504e250ee2d58f98e30..c9240785d65227b33f2b1cce28cb3de9d854ad8b 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -242,10 +242,10 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti @Override public void inactiveTick() { super.inactiveTick(); - if (this.goalSelector.inactiveTick()) { + if (this.goalSelector.inactiveTick(this.activatedPriority, true)) { // Pufferfish - pass activated priroity this.goalSelector.tick(); } - if (this.targetSelector.inactiveTick()) { + if (this.targetSelector.inactiveTick(this.activatedPriority, true)) { // Pufferfish - pass activated priority this.targetSelector.tick(); } } @@ -963,10 +963,14 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti int i = this.tickCount + this.getId(); if (i % 2 != 0 && this.tickCount > 1) { + if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.targetSelector.tickRunningGoals(false); + if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.goalSelector.tickRunningGoals(false); } else { + if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.targetSelector.tick(); + if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.goalSelector.tick(); } diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerPanicTrigger.java b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerPanicTrigger.java index 758f62416ca9c02351348ac0d41deeb4624abc0e..69130969c9a434ec2361e573c9a1ec9f462dfda2 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerPanicTrigger.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerPanicTrigger.java @@ -36,7 +36,11 @@ public class VillagerPanicTrigger extends Behavior { @Override protected void tick(ServerLevel world, Villager entity, long time) { - if (time % 100L == 0L) { + // Pufferfish start + if (entity.nextGolemPanic < 0) entity.nextGolemPanic = time + 100; + if (--entity.nextGolemPanic < time) { + entity.nextGolemPanic = -1; + // Pufferfish end entity.spawnGolemIfNeeded(world, time, 3); } } diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java index 8ac1a3b86bf0eee6a27985d6b9dbc98b6fedbb15..95d20cd10ef0b3da32a6168c5d4a9bc4abc63e22 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java @@ -39,9 +39,13 @@ public class GoalSelector { } // Paper start - public boolean inactiveTick() { + public boolean inactiveTick(int tickRate, boolean inactive) { // Pufferfish start + if (inactive && !org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.enabled) tickRate = 4; // reset to Paper's + tickRate = Math.min(tickRate, 3); // Dreeam TODO - Waiting Paper this.curRate++; - return this.curRate % 3 == 0; // TODO newGoalRate was already unused in 1.20.4, check if this is correct + //return this.curRate % 3 == 0; // TODO newGoalRate was already unused in 1.20.4, check if this is correct + return this.curRate % tickRate == 0; + // Pufferfish end } public boolean hasTasks() { for (WrappedGoal task : this.availableGoals) { diff --git a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java index 29802fa506042c80bd1a03cf88f4ab326dfb94b5..34c1df5bd7655bfbcba3ae872a8eec621ace5835 100644 --- a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java +++ b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java @@ -215,8 +215,10 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS return 0.4F; } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel) this.level(), this); AllayAi.updateActivity(this); super.customServerAiStep(); diff --git a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java index 8a14e3c2bd2162e36634f532fa86a7fba0548541..d339e9c0b81a50d20048375bd8b4141618fc1d2a 100644 --- a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java +++ b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java @@ -268,8 +268,10 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder> { .ifPresent(this::setVariant); } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel)this.level(), this); FrogAi.updateActivity(this); super.customServerAiStep(); diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java index 53dbe9d296a89d23b19f2551b20b464731ee800e..40dad395aabb04c21ac26fadce823ce8b4f79b3a 100644 --- a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java +++ b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java @@ -83,8 +83,10 @@ public class Tadpole extends AbstractFish { return SoundEvents.TADPOLE_FLOP; } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel) this.level(), this); TadpoleAi.updateActivity(this); super.customServerAiStep(); diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java index 55d2144af223a2813b784e6e249fe94f610ef079..1bf1e2714f210188202a97219765428f9cf2c956 100644 --- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java +++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java @@ -190,8 +190,10 @@ public class Goat extends Animal { return (Brain) super.getBrain(); // CraftBukkit - decompile error } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel) this.level(), this); GoatAi.updateActivity(this); super.customServerAiStep(); diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java index 910c3df3e8232db8b7140c51df010f0a9bdcad68..837ae63b1621a4fabba4a44145279d5f95f57f6b 100644 --- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java @@ -153,8 +153,10 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { return (Brain)super.getBrain(); } + private int behaviorTick; // Pufferfish @Override protected void customServerAiStep() { + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel)this.level(), this); HoglinAi.updateActivity(this); if (this.isConverting()) { diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java index 74ffc0c8ac95590c39e86893bb4f270eb63efd49..5ea7cc29c2f9c4e2ee7741b4cead8ea78c296c5d 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java @@ -294,8 +294,10 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento return !this.cannotHunt; } + private int behaviorTick; // Pufferfish @Override protected void customServerAiStep() { + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel) this.level(), this); PiglinAi.updateActivity(this); super.customServerAiStep(); diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java index f41898080a0cce6e1c2d50c3a7f1a0d67df5605a..7350e339c673c3c59bc36843f03f86ab1ef5e925 100644 --- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java +++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java @@ -271,10 +271,12 @@ public class Warden extends Monster implements VibrationSystem { } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { ServerLevel worldserver = (ServerLevel) this.level(); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick(worldserver, this); super.customServerAiStep(); if ((this.tickCount + this.getId()) % 120 == 0) { diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java index de41f5b57cb4220daf312cc8724cc32d3dd6f7a6..e32c928dc21def1df0f6d334405cff5dc8e999cd 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java @@ -145,6 +145,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler return holder.is(PoiTypes.MEETING); }); + public long nextGolemPanic = -1; // Pufferfish + public Villager(EntityType entityType, Level world) { this(entityType, world, VillagerType.PLAINS); } @@ -248,6 +250,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } // Spigot End + private int behaviorTick = 0; // Pufferfish @Override @Deprecated // Paper protected void customServerAiStep() { @@ -256,7 +259,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } protected void customServerAiStep(final boolean inactive) { // Paper end - if (!inactive) this.getBrain().tick((ServerLevel) this.level(), this); // Paper + // Pufferfish start + if (!inactive && this.behaviorTick++ % this.activatedPriority == 0) { + this.getBrain().tick((ServerLevel) this.level(), this); // Paper + } + // Pufferfish end if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; } diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/DynamicActivationofBrain.java b/src/main/java/org/dreeam/leaf/config/modules/opt/DynamicActivationofBrain.java new file mode 100644 index 0000000000000000000000000000000000000000..2769eba9841ec866265e814e16f930a5e76de810 --- /dev/null +++ b/src/main/java/org/dreeam/leaf/config/modules/opt/DynamicActivationofBrain.java @@ -0,0 +1,61 @@ +package org.dreeam.leaf.config.modules.opt; + +import com.electronwill.nightconfig.core.file.CommentedFileConfig; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.EntityType; +import org.dreeam.leaf.config.ConfigInfo; +import org.dreeam.leaf.config.DoNotLoad; +import org.dreeam.leaf.config.EnumConfigCategory; +import org.dreeam.leaf.config.IConfigModule; + +import java.util.Collections; +import java.util.List; + +public class DynamicActivationofBrain implements IConfigModule { + + @Override + public EnumConfigCategory getCategory() { + return EnumConfigCategory.PERFORMANCE; + } + + @Override + public String getBaseName() { + return "dab"; + } + + @ConfigInfo(baseName = "enabled") + public static boolean enabled = true; + @ConfigInfo(baseName = "start-distance", comments = """ + This value determines how far away an entity has to be + from the player to start being effected by DEAR.""") + public static int startDistance = 12; + @DoNotLoad + public static int startDistanceSquared; + @ConfigInfo(baseName = "max-tick-freq", comments = """ + This value defines how often in ticks, the furthest entity + will get their pathfinders and behaviors ticked. 20 = 1s""") + public static int maximumActivationPrio = 20; + @ConfigInfo(baseName = "activation-dist-mod", comments = """ + This value defines how much distance modifies an entity's + tick frequency. freq = (distanceToPlayer^2) / (2^value)", + If you want further away entities to tick less often, use 7. + If you want further away entities to tick more often, try 9.""") + public static int activationDistanceMod = 8; + @ConfigInfo(baseName = "blacklisted-entities", comments = "A list of entities to ignore for activation") + public static List blackedEntities = Collections.emptyList(); + + @Override + public void onLoaded(CommentedFileConfig config) { + config.setComment("performance.dab", """ + Optimizes entity brains when + they're far away from the player"""); + + startDistanceSquared = startDistance * startDistance; + for (EntityType entityType : BuiltInRegistries.ENTITY_TYPE) { + entityType.dabEnabled = true; // reset all, before setting the ones to true + } + blackedEntities.forEach(name -> EntityType.byString(name).ifPresentOrElse(entityType -> + entityType.dabEnabled = false, () -> MinecraftServer.LOGGER.warn("Unknown entity \"{}\"", name))); + } +} diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java index 5e24b70b102cbf4dce2dec748dab1949a77b0d4d..df50c32482067368b11d2928bd353f4fbe595afe 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -40,6 +40,9 @@ import net.minecraft.world.level.Level; import net.minecraft.world.phys.AABB; import org.galemc.gale.configuration.GaleGlobalConfiguration; import org.galemc.gale.configuration.GaleWorldConfiguration; +// Pufferfish start +import net.minecraft.world.phys.Vec3; +// Pufferfish end public class ActivationRange { @@ -238,6 +241,25 @@ public class ActivationRange } // Paper end - Configurable marker ticking ActivationRange.activateEntity(entity); + + // Pufferfish start + if (org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.enabled && entity.getType().dabEnabled) { + if (!entity.activatedPriorityReset) { + entity.activatedPriorityReset = true; + entity.activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; + } + Vec3 playerVec = player.position(); + Vec3 entityVec = entity.position(); + double diffX = playerVec.x - entityVec.x, diffY = playerVec.y - entityVec.y, diffZ = playerVec.z - entityVec.z; + int squaredDistance = (int) (diffX * diffX + diffY * diffY + diffZ * diffZ); + entity.activatedPriority = squaredDistance > org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.startDistanceSquared ? + Math.max(1, Math.min(squaredDistance >> org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.activationDistanceMod, entity.activatedPriority)) : + 1; + } else { + entity.activatedPriority = 1; + } + // Pufferfish end + } // Paper end } @@ -254,12 +276,12 @@ public class ActivationRange if ( MinecraftServer.currentTick > entity.activatedTick ) { if ( entity.defaultActivationState ) - { + { // Pufferfish - diff on change entity.activatedTick = MinecraftServer.currentTick; return; } if ( entity.activationType.boundingBox.intersects( entity.getBoundingBox() ) ) - { + { // Pufferfish - diff on change entity.activatedTick = MinecraftServer.currentTick; } }