mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-19 15:09:25 +00:00
add queue and reuse block count
This commit is contained in:
@@ -5,26 +5,26 @@ Subject: [PATCH] optimize random tick
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||
index 15bbd1f7f2a90b4b5427026d622764bb1c92d465..0682e8b1708ed39e97b53548301c353ca8c42ce5 100644
|
||||
index 15bbd1f7f2a90b4b5427026d622764bb1c92d465..bc37fa20143eda45f9df07e382f2feca3909abce 100644
|
||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -693,6 +693,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
this.level.tickChunk(levelChunk, _int);
|
||||
}
|
||||
}
|
||||
+ this.level.randomTickSystem.tick(this.level); // Leaf - random tick
|
||||
+ this.level.randomTickSystem.tick(this.level); // Leaf - optimize random tick
|
||||
|
||||
if (flagAndHasNaturalSpawn) { // Gale - MultiPaper - skip unnecessary mob spawning computations
|
||||
this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies);
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index eb849c57992658005e0f514c6f7923f8ca43bebf..9f0313038693a1e571beba0c8ca027c29789a1ce 100644
|
||||
index eb849c57992658005e0f514c6f7923f8ca43bebf..cc6fd8533fce1839600488b996f9179d1399380d 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1128,6 +1128,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.simpleRandom.nextInt(16); } // Gale - Airplane - optimize random calls in chunk ticking
|
||||
|
||||
+ public org.dreeam.leaf.world.RandomTickSystem randomTickSystem = new org.dreeam.leaf.world.RandomTickSystem(); // Leaf
|
||||
+ public org.dreeam.leaf.world.RandomTickSystem randomTickSystem = new org.dreeam.leaf.world.RandomTickSystem(); // Leaf - optimize random tick
|
||||
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
|
||||
ChunkPos pos = chunk.getPos();
|
||||
@@ -39,28 +39,38 @@ index eb849c57992658005e0f514c6f7923f8ca43bebf..9f0313038693a1e571beba0c8ca027c2
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index a90bf0d80ae4dac9b19b8e467b402917cc19a271..6c74fcb364b9239131e7b5578af237ec783a221a 100644
|
||||
index a90bf0d80ae4dac9b19b8e467b402917cc19a271..44b672671e0bea6a5f91e9b8573f9a8225a20f6a 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -149,6 +149,36 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
||||
@@ -149,6 +149,48 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
||||
}
|
||||
// Gale end - Airplane - optimize random calls in chunk ticking - instead of using a random every time the chunk is ticked, define when lightning strikes preemptively
|
||||
|
||||
+ // Leaf start - random tick
|
||||
+ private int leaf$countTickingBlocks;
|
||||
+ public final int leaf$lastTickingBlocksCount() {
|
||||
+ return leaf$countTickingBlocks;
|
||||
+ }
|
||||
+ // Leaf start - optimize random tick
|
||||
+ private boolean leaf$tickingBlocksDirty = true;
|
||||
+ private int leaf$tickingBlocksCount;
|
||||
+ private int leaf$firstTickingSectionIndex = -1;
|
||||
+ public final int leaf$tickingBlocksCount() {
|
||||
+ int sum = 0;
|
||||
+ for (LevelChunkSection section : sections) {
|
||||
+ sum += section.moonrise$getTickingBlockList().size();
|
||||
+ if (!leaf$tickingBlocksDirty) {
|
||||
+ return leaf$tickingBlocksCount;
|
||||
+ }
|
||||
+ leaf$countTickingBlocks = sum;
|
||||
+ leaf$tickingBlocksDirty = false;
|
||||
+ int sum = 0;
|
||||
+ leaf$firstTickingSectionIndex = -1;
|
||||
+ for (int i = 0; i < sections.length; i++) {
|
||||
+ LevelChunkSection section = sections[i];
|
||||
+ int size = section.moonrise$getTickingBlockList().size();
|
||||
+ if (size != 0 && leaf$firstTickingSectionIndex == -1) {
|
||||
+ leaf$firstTickingSectionIndex = i;
|
||||
+ }
|
||||
+ sum += size;
|
||||
+ }
|
||||
+ leaf$tickingBlocksCount = sum;
|
||||
+ return sum;
|
||||
+ }
|
||||
+ public final java.util.OptionalLong leaf$getTickingPos(int idx) {
|
||||
+ for (int i = 0; i < sections.length; i++) {
|
||||
+ if (leaf$firstTickingSectionIndex != -1) {
|
||||
+ for (int i = leaf$firstTickingSectionIndex; i < sections.length; i++) {
|
||||
+ LevelChunkSection section = sections[i];
|
||||
+ var l = section.moonrise$getTickingBlockList();
|
||||
+ int size = l.size();
|
||||
@@ -73,9 +83,23 @@ index a90bf0d80ae4dac9b19b8e467b402917cc19a271..6c74fcb364b9239131e7b5578af237ec
|
||||
+ }
|
||||
+ idx -= size;
|
||||
+ }
|
||||
+ }
|
||||
+ leaf$tickingBlocksDirty = true;
|
||||
+ return java.util.OptionalLong.empty();
|
||||
+ }
|
||||
+ // Leaf end - random tick
|
||||
+ // Leaf end - optimize random tick
|
||||
public LevelChunk(Level level, ChunkPos pos) {
|
||||
this(level, pos, UpgradeData.EMPTY, new LevelChunkTicks<>(), new LevelChunkTicks<>(), 0L, null, null, null);
|
||||
}
|
||||
@@ -417,6 +459,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
||||
if (blockState == state) {
|
||||
return null;
|
||||
} else {
|
||||
+ // Leaf start - optimize random tick
|
||||
+ if (blockState.isRandomlyTicking() != state.isRandomlyTicking()) {
|
||||
+ leaf$tickingBlocksDirty = true;
|
||||
+ }
|
||||
+ // Leaf end - optimize random tick
|
||||
Block block = state.getBlock();
|
||||
this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING).update(i, y, i2, state);
|
||||
this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES).update(i, y, i2, state);
|
||||
|
||||
@@ -20,7 +20,7 @@ public final class RandomTickSystem {
|
||||
private static final int BITS_STEP = 2;
|
||||
private static final int BITS_MAX = 60;
|
||||
|
||||
private final LongArrayList edges = new LongArrayList();
|
||||
private final LongArrayList queue = new LongArrayList();
|
||||
private final LongArrayList samples = new LongArrayList();
|
||||
private final LongArrayList weights = new LongArrayList();
|
||||
private long weightsSum = 0L;
|
||||
@@ -33,123 +33,64 @@ public final class RandomTickSystem {
|
||||
return;
|
||||
}
|
||||
|
||||
var random = world.simpleRandom;
|
||||
long chosen = weightsSum / SCALE;
|
||||
final var random = world.simpleRandom;
|
||||
final long chosen;
|
||||
if (((weightsSum % SCALE) >= boundedNextLong(random, SCALE))) {
|
||||
chosen += 1L;
|
||||
chosen = weightsSum / SCALE + 1L;
|
||||
} else {
|
||||
chosen = weightsSum / SCALE;
|
||||
}
|
||||
if (chosen == 0L) {
|
||||
return;
|
||||
}
|
||||
|
||||
final long[] weightsRaw = weights.elements();
|
||||
final long[] samplesRaw = samples.elements();
|
||||
final long spoke = weightsSum / chosen;
|
||||
if (spoke == 0L) {
|
||||
return;
|
||||
}
|
||||
|
||||
final long[] weightsRaw = weights.elements();
|
||||
final long[] samplesRaw = samples.elements();
|
||||
|
||||
long accumulated = weightsRaw[0];
|
||||
long current = boundedNextLong(random, spoke);
|
||||
int i = 0;
|
||||
|
||||
long packed1 = 0L, packed2 = 0L, packed3 = 0L, packed4;
|
||||
int rest;
|
||||
long count = 0L;
|
||||
while (true) {
|
||||
if (current >= weightsSum) {
|
||||
rest = 0;
|
||||
break;
|
||||
}
|
||||
while (current < weightsSum) {
|
||||
while (accumulated < current) {
|
||||
i += 1;
|
||||
accumulated += weightsRaw[i];
|
||||
}
|
||||
packed1 = samplesRaw[i];
|
||||
queue.add(samplesRaw[i]);
|
||||
current += spoke;
|
||||
|
||||
if (current >= weightsSum) {
|
||||
rest = 1;
|
||||
break;
|
||||
}
|
||||
while (accumulated < current) {
|
||||
i += 1;
|
||||
accumulated += weightsRaw[i];
|
||||
}
|
||||
packed2 = samplesRaw[i];
|
||||
current += spoke;
|
||||
|
||||
if (current >= weightsSum) {
|
||||
rest = 2;
|
||||
break;
|
||||
}
|
||||
while (accumulated < current) {
|
||||
i += 1;
|
||||
accumulated += weightsRaw[i];
|
||||
}
|
||||
packed3 = samplesRaw[i];
|
||||
current += spoke;
|
||||
|
||||
if (current >= weightsSum) {
|
||||
rest = 3;
|
||||
break;
|
||||
}
|
||||
while (accumulated < current) {
|
||||
i += 1;
|
||||
accumulated += weightsRaw[i];
|
||||
}
|
||||
packed4 = samplesRaw[i];
|
||||
current += spoke;
|
||||
|
||||
final LevelChunk chunk1;
|
||||
final LevelChunk chunk2;
|
||||
final LevelChunk chunk3;
|
||||
final LevelChunk chunk4;
|
||||
chunk1 = getChunk(world, packed1);
|
||||
chunk2 = packed1 != packed2 ? getChunk(world, packed2) : chunk1;
|
||||
chunk3 = packed2 != packed3 ? getChunk(world, packed3) : chunk2;
|
||||
chunk4 = packed3 != packed4 ? getChunk(world, packed4) : chunk3;
|
||||
if (chunk1 != null) {
|
||||
tickBlock(world, chunk1, random);
|
||||
}
|
||||
if (chunk2 != null) {
|
||||
tickBlock(world, chunk2, random);
|
||||
}
|
||||
if (chunk3 != null) {
|
||||
tickBlock(world, chunk3, random);
|
||||
}
|
||||
if (chunk4 != null) {
|
||||
tickBlock(world, chunk4, random);
|
||||
while (queue.size() < chosen) {
|
||||
queue.add(samplesRaw[i]);
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if (rest >= 1) {
|
||||
edges.push(packed1);
|
||||
}
|
||||
if (rest >= 2) {
|
||||
edges.push(packed2);
|
||||
}
|
||||
if (rest == 3) {
|
||||
edges.push(packed3);
|
||||
}
|
||||
chosen -= rest;
|
||||
chosen -= count * 4L;
|
||||
while (edges.size() < chosen) {
|
||||
edges.push(samplesRaw[i]);
|
||||
}
|
||||
|
||||
long[] queueRaw = edges.elements();
|
||||
for (int k = 0, j = edges.size(); k < j; k++) {
|
||||
LevelChunk chunk = getChunk(world, queueRaw[k]);
|
||||
if (chunk != null) {
|
||||
tickBlock(world, chunk, random);
|
||||
long[] queueRaw = queue.elements();
|
||||
int j = 0;
|
||||
int k;
|
||||
for (k = queue.size() - 3; j < k; j += 4) {
|
||||
final long packed1 = queueRaw[j];
|
||||
final long packed2 = queueRaw[j + 1];
|
||||
final long packed3 = queueRaw[j + 2];
|
||||
final long packed4 = queueRaw[j + 3];
|
||||
final LevelChunk chunk1 = getChunk(world, packed1);
|
||||
final LevelChunk chunk2 = packed1 != packed2 ? getChunk(world, packed2) : chunk1;
|
||||
final LevelChunk chunk3 = packed2 != packed3 ? getChunk(world, packed3) : chunk2;
|
||||
final LevelChunk chunk4 = packed3 != packed4 ? getChunk(world, packed4) : chunk3;
|
||||
if (chunk1 != null) tickBlock(world, chunk1, random);
|
||||
if (chunk2 != null) tickBlock(world, chunk2, random);
|
||||
if (chunk3 != null) tickBlock(world, chunk3, random);
|
||||
if (chunk4 != null) tickBlock(world, chunk4, random);
|
||||
}
|
||||
for (k = queue.size(); j < k; j++) {
|
||||
LevelChunk chunk = getChunk(world, queueRaw[j]);
|
||||
if (chunk != null) tickBlock(world, chunk, random);
|
||||
}
|
||||
|
||||
weightsSum = 0L;
|
||||
edges.clear();
|
||||
queue.clear();
|
||||
weights.clear();
|
||||
samples.clear();
|
||||
}
|
||||
@@ -159,7 +100,7 @@ public final class RandomTickSystem {
|
||||
}
|
||||
|
||||
private static void tickBlock(ServerLevel world, LevelChunk chunk, RandomSource random) {
|
||||
OptionalLong optionalPos = chunk.leaf$getTickingPos(random.nextInt(chunk.leaf$lastTickingBlocksCount()));
|
||||
OptionalLong optionalPos = chunk.leaf$getTickingPos(random.nextInt(chunk.leaf$tickingBlocksCount()));
|
||||
if (optionalPos.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -187,11 +128,14 @@ public final class RandomTickSystem {
|
||||
} else {
|
||||
this.bits += BITS_STEP;
|
||||
}
|
||||
if ((this.cacheRandom & (TICK_MASK << bits)) == 0L && chunk.leaf$tickingBlocksCount() != 0L) {
|
||||
long chance = (TICK_MUL * tickSpeed * chunk.leaf$lastTickingBlocksCount() * SCALE) / CHUNK_BLOCKS;
|
||||
if ((this.cacheRandom & (TICK_MASK << bits)) == 0L) {
|
||||
int count = chunk.leaf$tickingBlocksCount();
|
||||
if (count != 0L) {
|
||||
long weight = (TICK_MUL * tickSpeed * count * SCALE) / CHUNK_BLOCKS;
|
||||
samples.add(chunk.getPos().longKey);
|
||||
weights.add(chance);
|
||||
weightsSum += chance;
|
||||
weights.add(weight);
|
||||
weightsSum += weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user