Skip to content

Commit

Permalink
Don't call recalcBlockCounts on the client
Browse files Browse the repository at this point in the history
This logic is expensive, and we only need to know if there may be any special colliding blocks in the section.

Before this change ClientboundLevelChunkWithLightPacket was the top contributor to frame time spikes, after ths change it's nowhere near the top of the profile. Specifically, the recalc logic was taking upwards of 80% of the processing time for this packet, the simplified check only takes <5%.
  • Loading branch information
jpenilla committed Sep 17, 2024
1 parent 23eddfe commit 36f6c06
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import net.minecraft.client.Minecraft;
import net.minecraft.util.BitStorage;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.Palette;
Expand Down Expand Up @@ -62,8 +64,8 @@ abstract class LevelChunkSectionMixin implements BlockCountingChunkSection {
private final IntList tickingBlocks = new IntList();

@Override
public final int moonrise$getSpecialCollidingBlocks() {
return this.specialCollidingBlocks;
public final boolean moonrise$maybeHasSpecialCollidingBlocks() {
return this.specialCollidingBlocks != 0;
}

@Override
Expand Down Expand Up @@ -184,7 +186,7 @@ public void recalcBlockCounts() {
}

/**
* @reason Call recalcBlockCounts on the client, as the client does not invoke it when deserializing chunk sections.
* @reason the client does not invoke recalcBlockCounts when deserializing chunk sections, but we need this info for collision optimizations
* @author Spottedleaf
*/
@Inject(
Expand All @@ -193,7 +195,13 @@ public void recalcBlockCounts() {
value = "RETURN"
)
)
private void callRecalcBlocksClient(final CallbackInfo ci) {
this.recalcBlockCounts();
private void checkForSpecialCollidingBlocksClient(final CallbackInfo ci) {
final ProfilerFiller profiler = Minecraft.getInstance().getProfiler();
profiler.push("checkForSpecialCollidingBlocksClient");
try {
this.specialCollidingBlocks = this.maybeHas(CollisionUtil::isSpecialCollidingBlock) ? 1 : 0;
} finally {
profiler.pop();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

public interface BlockCountingChunkSection {

public int moonrise$getSpecialCollidingBlocks();
public boolean moonrise$maybeHasSpecialCollidingBlocks();

public IntList moonrise$getTickingBlockList();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1994,7 +1994,7 @@ public static boolean getCollisionsForBlocksOrWorldBorder(final Level world, fin
continue;
}

final boolean hasSpecial = ((BlockCountingChunkSection)section).moonrise$getSpecialCollidingBlocks() != 0;
final boolean hasSpecial = ((BlockCountingChunkSection)section).moonrise$maybeHasSpecialCollidingBlocks();
final int sectionAdjust = !hasSpecial ? 1 : 0;

final PalettedContainer<BlockState> blocks = section.states;
Expand Down

0 comments on commit 36f6c06

Please sign in to comment.