mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-21 07:59:26 +00:00
139 lines
8.5 KiB
Diff
139 lines
8.5 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: froobynooby <froobynooby@froobworld.com>
|
|
Date: Wed, 17 Jul 2024 18:46:11 +0930
|
|
Subject: [PATCH] Paper PR: Throttle failed spawn attempts
|
|
|
|
Original license: GPLv3
|
|
Original project: https://github.com/PaperMC/Paper
|
|
Paper pull request: https://github.com/PaperMC/Paper/pull/11099
|
|
|
|
For example config in paper-world-defaults.yml
|
|
```
|
|
spawning-throttle:
|
|
failed-attempts-threshold: 1200
|
|
throttled-ticks-per-spawn:
|
|
ambient: 10 # default value in bukkit.yml tickers-per * 10
|
|
axolotls: 10
|
|
creature: 4000
|
|
monster: 10
|
|
underground_water_creature: 10
|
|
water_ambient: 10
|
|
water_creature: 10
|
|
```
|
|
|
|
This patch adds the option to use longer ticks-per-spawn for a given
|
|
mob type in chunks where spawn attempts are consecutively failing.
|
|
|
|
This behaviour is particularly useful on servers where players build
|
|
mob farms. Mob farm designs often require making surrounding chunks
|
|
spawnproof, which causes the server to waste CPU cycles trying to spawn mobs in
|
|
vain. Throttling spawn attempts in suspected spawnproof chunks improves
|
|
performance without noticeably advantaging or disadvantaging the mob farm.
|
|
|
|
diff --git a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
|
|
index 95e96fe8aa93efbbb2e0a7dd98377fdc4fe0e6dd..b6728bb0c1974eb236a7e8429b936492ff490bdd 100644
|
|
--- a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
|
|
+++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
|
|
@@ -188,6 +188,15 @@ public class WorldConfiguration extends ConfigurationPart {
|
|
@MergeMap
|
|
public Reference2IntMap<MobCategory> ticksPerSpawn = Util.make(new Reference2IntOpenHashMap<>(NaturalSpawner.SPAWNING_CATEGORIES.length), map -> Arrays.stream(NaturalSpawner.SPAWNING_CATEGORIES).forEach(mobCategory -> map.put(mobCategory, -1)));
|
|
|
|
+ public SpawningThrottle spawningThrottle;
|
|
+
|
|
+ public class SpawningThrottle extends ConfigurationPart {
|
|
+ public IntOr.Disabled failedAttemptsThreshold = IntOr.Disabled.DISABLED;
|
|
+
|
|
+ @MergeMap
|
|
+ public Reference2IntMap<MobCategory> throttledTicksPerSpawn = Util.make(new Reference2IntOpenHashMap<>(NaturalSpawner.SPAWNING_CATEGORIES.length), map -> Arrays.stream(NaturalSpawner.SPAWNING_CATEGORIES).forEach(mobCategory -> map.put(mobCategory, -1)));
|
|
+ }
|
|
+
|
|
@ConfigSerializable
|
|
public record DespawnRangePair(@Required DespawnRange hard, @Required DespawnRange soft) {
|
|
public static DespawnRangePair createDefault() {
|
|
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
|
index 7e1a007ed2f2c625f01fea210c9935cb02d119e0..8e9ada03e5134d2f776bbbf872087121f649c19d 100644
|
|
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
|
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
|
@@ -138,8 +138,14 @@ public final class NaturalSpawner {
|
|
boolean spawnThisTick = true;
|
|
int limit = enumcreaturetype.getMaxInstancesPerChunk();
|
|
SpawnCategory spawnCategory = CraftSpawnCategory.toBukkit(enumcreaturetype);
|
|
+ // Paper start - throttle failed spawn attempts
|
|
+ long ticksPerSpawn = world.ticksPerSpawnCategory.getLong(spawnCategory);
|
|
+ if (world.paperConfig().entities.spawning.spawningThrottle.failedAttemptsThreshold.test(threshold -> chunk.failedSpawnAttempts[enumcreaturetype.ordinal()] > threshold)) {
|
|
+ ticksPerSpawn = Math.max(ticksPerSpawn, world.paperConfig().entities.spawning.spawningThrottle.throttledTicksPerSpawn.getOrDefault(enumcreaturetype, -1));
|
|
+ }
|
|
+ // Paper end - throttle failed spawn attempts
|
|
if (CraftSpawnCategory.isValidForLimits(spawnCategory)) {
|
|
- spawnThisTick = world.ticksPerSpawnCategory.getLong(spawnCategory) != 0 && worlddata.getGameTime() % world.ticksPerSpawnCategory.getLong(spawnCategory) == 0;
|
|
+ spawnThisTick = world.ticksPerSpawnCategory.getLong(spawnCategory) != 0 && worlddata.getGameTime() % ticksPerSpawn == 0; // Paper - throttle failed spawn attempts
|
|
limit = world.getWorld().getSpawnLimit(spawnCategory);
|
|
}
|
|
|
|
@@ -176,6 +182,13 @@ public final class NaturalSpawner {
|
|
difference, world.paperConfig().entities.spawning.perPlayerMobSpawns ? world.getChunkSource().chunkMap::updatePlayerMobTypeMap : null);
|
|
info.mobCategoryCounts.mergeInt(enumcreaturetype, spawnCount, Integer::sum);
|
|
// Paper end - Optional per player mob spawns
|
|
+ // Paper start - throttle failed spawn attempts
|
|
+ if (spawnCount == 0) {
|
|
+ chunk.failedSpawnAttempts[enumcreaturetype.ordinal()]++;
|
|
+ } else {
|
|
+ chunk.failedSpawnAttempts[enumcreaturetype.ordinal()] = 0;
|
|
+ }
|
|
+ // Paper end - throttle failed spawn attempts
|
|
}
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
|
index 5bb8fe022f580a626a99324f53515890a99b798d..5cee82d3d17739858e47f24ec5340233f09d0713 100644
|
|
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
|
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
|
@@ -84,6 +84,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
|
|
public final Map<BlockPos, BlockEntity> blockEntities = new Object2ObjectOpenHashMap();
|
|
protected final LevelHeightAccessor levelHeightAccessor;
|
|
protected final LevelChunkSection[] sections;
|
|
+ public final long[] failedSpawnAttempts = new long[net.minecraft.world.entity.MobCategory.values().length]; // Paper - throttle failed spawn attempts
|
|
|
|
// Leaf start - Matter - Feature Secure Seed
|
|
private boolean slimeChunk;
|
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
|
index 4bd048387651250135f963303c78c17f8473cfee..8257177404b23e131143017f3a7d835ad447f9fb 100644
|
|
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
|
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
|
@@ -302,6 +302,16 @@ public class ChunkSerializer {
|
|
((ChunkAccess) object1).addPackedPostProcess(nbttaglist2.getShort(i1), j1);
|
|
}
|
|
}
|
|
+ // Paper start - throttle failed spawn attempts
|
|
+ if (nbt.contains("Paper.FailedSpawnAttempts", Tag.TAG_COMPOUND)) {
|
|
+ CompoundTag failedSpawnAttemptsTag = nbt.getCompound("Paper.FailedSpawnAttempts");
|
|
+ for (net.minecraft.world.entity.MobCategory mobCategory : net.minecraft.world.level.NaturalSpawner.SPAWNING_CATEGORIES) {
|
|
+ if (failedSpawnAttemptsTag.contains(mobCategory.getSerializedName(), Tag.TAG_LONG)) {
|
|
+ ((ChunkAccess) object1).failedSpawnAttempts[mobCategory.ordinal()] = failedSpawnAttemptsTag.getLong(mobCategory.getSerializedName());
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Paper end - throttle failed spawn attempts
|
|
|
|
ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.loadLightHook(world, chunkPos, nbt, (ChunkAccess)object1); // Paper - rewrite chunk system - note: it's ok to pass the raw value instead of wrapped
|
|
|
|
@@ -545,6 +555,18 @@ public class ChunkSerializer {
|
|
nbttagcompound.put("ChunkBukkitValues", chunk.persistentDataContainer.toTagCompound());
|
|
}
|
|
// CraftBukkit end
|
|
+ // Paper start - throttle failed spawn attempts
|
|
+ CompoundTag failedSpawnAttemptsTag = new CompoundTag();
|
|
+ for (net.minecraft.world.entity.MobCategory mobCategory : net.minecraft.world.entity.MobCategory.values()) {
|
|
+ long failedSpawnAttempts = chunk.failedSpawnAttempts[mobCategory.ordinal()];
|
|
+ if (failedSpawnAttempts > 0) {
|
|
+ failedSpawnAttemptsTag.putLong(mobCategory.getSerializedName(), failedSpawnAttempts);
|
|
+ }
|
|
+ }
|
|
+ if (!failedSpawnAttemptsTag.isEmpty()) {
|
|
+ nbttagcompound.put("Paper.FailedSpawnAttempts", failedSpawnAttemptsTag);
|
|
+ }
|
|
+ // Paper end - throttle failed spawn attempts
|
|
ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.saveLightHook(world, chunk, nbttagcompound); // Paper - rewrite chunk system
|
|
return nbttagcompound;
|
|
}
|