9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2026-01-06 15:51:31 +00:00
Files
Leaf/leaf-server/minecraft-patches/features/0293-fast-bit-radix-sort.patch
Dreeam 35ac5d48ed Cleanup PWT (#533)
* Unify comment format
* More configurable
* Remove one extra execute mid-tick task call in level tick when PWT is disabled

This may cause extremely rare, weird, strange, magic, mysterious issues with plugins, or potentially more.

One example is that it may cause boss mob duplication issue when `ONE MOB ONLY` was enabled in plugin SupremeBosses
2025-10-25 07:41:43 -04:00

105 lines
7.5 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: hayanesuru <hayanesuru@outlook.jp>
Date: Thu, 28 Aug 2025 17:10:34 +0900
Subject: [PATCH] fast bit radix sort
Co-authored-by: Taiyou06 <kaandindar21@gmail.com>
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index fb9623d89376fc42fd5892e9c395439f55fa5ac5..739c16ecda34b1ee8cf59806cb13c80115377f1c 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -1106,6 +1106,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
public final org.dreeam.leaf.world.NatureSpawnChunkMap natureSpawnChunkMap = new org.dreeam.leaf.world.NatureSpawnChunkMap(); // Leaf - optimize mob spawning
public final org.dreeam.leaf.world.RandomTickSystem randomTickSystem = new org.dreeam.leaf.world.RandomTickSystem(); // Leaf - optimize random tick
public final org.dreeam.leaf.world.EntityCollisionCache entityCollisionCache = new org.dreeam.leaf.world.EntityCollisionCache(); // Leaf - cache collision list
+ public final org.dreeam.leaf.util.FastBitRadixSort fastBitRadixSort = new org.dreeam.leaf.util.FastBitRadixSort(); // Leaf - fast bit radix sort
public void tickChunk(LevelChunk chunk, int randomTickSpeed) {
final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Paper - optimise random ticking // Leaf - Faster random generator - upcasting
diff --git a/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java b/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java
index 09fd13e2d958da8326276c4dadf25bf488aff5ac..063cab1fbd8dd3a483346242659fe273d3000cc6 100644
--- a/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java
+++ b/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java
@@ -15,6 +15,7 @@ public class NearestItemSensor extends Sensor<Mob> {
private static final long XZ_RANGE = 32L;
private static final long Y_RANGE = 16L;
public static final int MAX_DISTANCE_TO_WANTED_ITEM = 32;
+ private static final double MAX_DIST_SQ = (double) MAX_DISTANCE_TO_WANTED_ITEM * MAX_DISTANCE_TO_WANTED_ITEM; // Leaf - quick sort
@Override
public Set<MemoryModuleType<?>> requires() {
@@ -24,8 +25,16 @@ public class NearestItemSensor extends Sensor<Mob> {
@Override
protected void doTick(ServerLevel level, Mob entity) {
Brain<?> brain = entity.getBrain();
- List<ItemEntity> entitiesOfClass = level.getEntitiesOfClass(ItemEntity.class, entity.getBoundingBox().inflate(32.0, 16.0, 32.0), itemEntity -> itemEntity.closerThan(entity, MAX_DISTANCE_TO_WANTED_ITEM) && entity.wantsToPickUp(level, itemEntity.getItem())); // Paper - Perf: Move predicate into getEntities
- entitiesOfClass.sort(Comparator.comparingDouble(entity::distanceToSqr));
+ // Leaf start - fast bit radix sort
+ net.minecraft.core.Position pos = entity.position();
+ double x = pos.x();
+ double y = pos.y();
+ double z = pos.z();
+ net.minecraft.world.phys.AABB boundingBox = entity.getBoundingBox().inflate(32.0, 16.0, 32.0);
+ it.unimi.dsi.fastutil.objects.ObjectArrayList<ItemEntity> entitiesOfClass = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel) level).moonrise$getEntityLookup().getEntities(ItemEntity.class, null, boundingBox, entitiesOfClass, (ItemEntity itemEntity) -> itemEntity.distanceToSqr(x, y, z) < MAX_DIST_SQ && entity.wantsToPickUp(level, itemEntity.getItem())); // Paper - Perf: Move predicate into getEntities
+ level.fastBitRadixSort.sort(entitiesOfClass.elements(), entitiesOfClass.size(), pos);
+ // Leaf end - fast bit radix sort
// Paper start - Perf: remove streams from hot code
ItemEntity nearest = null;
for (final ItemEntity itemEntity : entitiesOfClass) {
diff --git a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..51a6302ed5daf512acc6bed915f954ac76559270 100644
--- a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
+++ b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
@@ -17,10 +17,11 @@ public class NearestLivingEntitySensor<T extends LivingEntity> extends Sensor<T>
protected void doTick(ServerLevel level, T entity) {
double attributeValue = entity.getAttributeValue(Attributes.FOLLOW_RANGE);
AABB aabb = entity.getBoundingBox().inflate(attributeValue, attributeValue, attributeValue);
- List<LivingEntity> entitiesOfClass = level.getEntitiesOfClass(
- LivingEntity.class, aabb, matchableEntity -> matchableEntity != entity && matchableEntity.isAlive()
- );
- entitiesOfClass.sort(Comparator.comparingDouble(entity::distanceToSqr));
+ // Leaf start - fast bit radix sort
+ it.unimi.dsi.fastutil.objects.ObjectArrayList<LivingEntity> entitiesOfClass = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel) level).moonrise$getEntityLookup().getEntities(LivingEntity.class, entity, aabb, entitiesOfClass, LivingEntity::isAlive);
+ level.fastBitRadixSort.sort(entitiesOfClass.elements(), entitiesOfClass.size(), entity.position());
+ // Leaf end - fast bit radix sort
Brain<?> brain = entity.getBrain();
brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, entitiesOfClass);
brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(level, entity, entitiesOfClass));
diff --git a/net/minecraft/world/entity/ai/sensing/PlayerSensor.java b/net/minecraft/world/entity/ai/sensing/PlayerSensor.java
index fa438315b4ed8e9394383b82b89ecb04bac3399f..44942f1fa1f543e81b1553e51c057de437f10e93 100644
--- a/net/minecraft/world/entity/ai/sensing/PlayerSensor.java
+++ b/net/minecraft/world/entity/ai/sensing/PlayerSensor.java
@@ -27,18 +27,26 @@ public class PlayerSensor extends Sensor<LivingEntity> {
@Override
protected void doTick(ServerLevel level, LivingEntity entity) {
// Leaf start - Remove stream in PlayerSensor
- List<Player> list = new java.util.ArrayList<>();
+ // Leaf start - fast bit radix sort
+ it.unimi.dsi.fastutil.objects.ObjectArrayList<Player> list = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
+ double distance = this.getFollowDistance(entity);
+ double distSq = distance * distance;
+ net.minecraft.world.phys.Vec3 vec3 = entity.position();
+ double tx = vec3.x();
+ double ty = vec3.y();
+ double tz = vec3.z();
for (Player serverPlayer : level.players()) {
if (!EntitySelector.NO_SPECTATORS.test(serverPlayer)) {
continue;
}
- if (!entity.closerThan(serverPlayer, this.getFollowDistance(entity))) {
+ if (serverPlayer.distanceToSqr(tx, ty, tz) >= distSq) {
continue;
}
list.add(serverPlayer);
}
- list.sort(Comparator.comparingDouble(entity::distanceToSqr));
+ level.fastBitRadixSort.sort(list.elements(), list.size(), vec3);
+ // Leaf end - fast bit radix sort
// Leaf end - Remove stream in PlayerSensor
Brain<?> brain = entity.getBrain();
brain.setMemory(MemoryModuleType.NEAREST_PLAYERS, list);