perf(core): reduce packed tile update churn (#3253)

## Description:
- Build packedTileUpdates directly into a BigUint64Array (avoid
intermediate JS array + copy).

- Transfer packedTileUpdates.buffer in worker postMessage to avoid
structured-clone.


- Avoids large short-lived allocations during tile-update (lower peak
heap and GC pressure).
- Prevents duplicating buffers across thread boundaries when the main
thread is behind. (one buffer per queued update, not two)

**Notes**

- after postMessage(..., [packedTileUpdates.buffer]) transfer the
worker’s packedTileUpdates becomes unusable (its .buffer is detached).


- [ ] I have added screenshots for all UI updates
- [ ] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [ ] I have added relevant tests to the test directory
- [ ] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

DISCORD_USERNAME
This commit is contained in:
scamiv
2026-02-19 22:53:46 +01:00
committed by GitHub
parent 7ee07fc9f0
commit fcf45db672
2 changed files with 12 additions and 2 deletions
+6 -2
View File
@@ -173,12 +173,16 @@ export class GameRunner {
}
// Many tiles are updated to pack it into an array
const packedTileUpdates = updates[GameUpdateType.Tile].map((u) => u.update);
const tileUpdates = updates[GameUpdateType.Tile];
const packedTileUpdates = new BigUint64Array(tileUpdates.length);
for (let i = 0; i < tileUpdates.length; i++) {
packedTileUpdates[i] = tileUpdates[i].update;
}
updates[GameUpdateType.Tile] = [];
this.callBack({
tick: this.game.ticks(),
packedTileUpdates: new BigUint64Array(packedTileUpdates),
packedTileUpdates,
updates: updates,
playerNameViewData: this.playerViewData,
tickExecutionDuration: tickExecutionDuration,
+6
View File
@@ -30,6 +30,12 @@ function gameUpdate(gu: GameUpdateViewData | ErrorUpdate) {
}
function sendMessage(message: WorkerMessage) {
if (message.type === "game_update") {
// Transfer the packed tile updates buffer to avoid structured-clone copies and
// reduce worker-side memory churn during long runs / catch-up.
ctx.postMessage(message, [message.gameUpdate.packedTileUpdates.buffer]);
return;
}
ctx.postMessage(message);
}