Skip to content

Commit

Permalink
Optimize client light update processing
Browse files Browse the repository at this point in the history
  • Loading branch information
Desoroxxx committed Dec 17, 2024
1 parent 1cdcfa8 commit b0a431b
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 18 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project follows the [Ragnarök Versioning Convention](https://github.co
### Changed

- `DeduplicatedLongQueue` now creates a new deduplication set instead of clearing it
- Client light processing now uses a queue which improves performance of light updates

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import java.util.Iterator;
import java.util.Set;
import java.util.*;

import static dev.redstudio.alfheim.Alfheim.IS_NOTHIRIUM_LOADED;
import static dev.redstudio.alfheim.Alfheim.IS_VINTAGIUM_LOADED;
Expand Down Expand Up @@ -56,28 +55,15 @@ private boolean disableVanillaLightUpdates(final Set<BlockPos> instance) {
if (setLightUpdates.isEmpty() || (!IS_NOTHIRIUM_LOADED && !IS_VINTAGIUM_LOADED && renderDispatcher.hasNoFreeRenderBuilders()))
return;

final Iterator<BlockPos> iterator = setLightUpdates.iterator();
final float lightUpdateLimit = 2048 + ((float) setLightUpdates.size() / 4); // Todo: Rework this once again, this is currently pretty dumb.
// It fixed the issue where the FPS on lower end hardware would plummet for a few seconds.
// But it also reduced how smooth the frame rate was on higher end hardware.
// Updating blocks is costly and will take a long time, this is why lower end hardware plummets for a few seconds.
// Higher end hardware instead has somewhat of a FPS "buffer" which can handle it fine over multiple frames thus reducing frame-time spikes.
// The technically the best way to do this (that I hadn't though of before) was to add current "FPS" to the equation.
// If the FPS is low more updates would be done in one frame if it is high we can afford spreading light updates over multiple frames.

short lightUpdatesProcessed = 0;
while (iterator.hasNext() && lightUpdatesProcessed < lightUpdateLimit) {
final BlockPos blockpos = iterator.next();

iterator.remove();
final Queue<BlockPos> queue = new ArrayDeque<>(setLightUpdates);
BlockPos blockpos;

while ((blockpos = queue.poll()) != null) {
final int x = blockpos.getX();
final int y = blockpos.getY();
final int z = blockpos.getZ();

markBlocksForUpdate(x - 1, y - 1, z - 1, x + 1, y + 1, z + 1, false);

lightUpdatesProcessed++;
}
}
}

0 comments on commit b0a431b

Please sign in to comment.