mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-04 17:06:07 +00:00
perf(core): speed up packedTileUpdates (Uint32 pairs, no tile wrappers) (#3255)
## Description Reduces CPU + GC pressure from tile update serialization. **What changed** - Switched `packedTileUpdates` from `BigUint64Array` (BigInt packing) to `Uint32Array` `[tileRef, state]` pairs, updating `GameView` ingestion. - Updated tile state to use `GameMap.tileState(tile)` and `GameMap.updateTile(tile, state)`. - Removed per-tile `GameUpdateType.Tile` wrapper allocations by recording raw `(tile, state)` pairs in `GameImpl` and draining them via `drainPackedTileUpdates()` in `GameRunner`. **Why it’s faster** - Avoids BigInt and pack/unpack. - Avoids per-tile object allocations. **Compatibility** - Wire format change: `packedTileUpdates` is now `Uint32Array` pairs instead of `BigUint64Array`. ## Please complete the following: - [ ] 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:
+24
-17
@@ -39,7 +39,7 @@ import {
|
||||
UnitInfo,
|
||||
UnitType,
|
||||
} from "./Game";
|
||||
import { GameMap, TileRef, TileUpdate } from "./GameMap";
|
||||
import { GameMap, TileRef } from "./GameMap";
|
||||
import { GameUpdate, GameUpdateType } from "./GameUpdates";
|
||||
import { PlayerImpl } from "./PlayerImpl";
|
||||
import { RailNetwork } from "./RailNetwork";
|
||||
@@ -83,6 +83,7 @@ export class GameImpl implements Game {
|
||||
private _nextUnitID = 1;
|
||||
|
||||
private updates: GameUpdates = createGameUpdatesMap();
|
||||
private tileUpdatePairs: number[] = [];
|
||||
private unitGrid: UnitGrid;
|
||||
|
||||
private playerTeams: Team[];
|
||||
@@ -248,10 +249,7 @@ export class GameImpl implements Game {
|
||||
return;
|
||||
}
|
||||
this._map.setFallout(tile, value);
|
||||
this.addUpdate({
|
||||
type: GameUpdateType.Tile,
|
||||
update: this.toTileUpdate(tile),
|
||||
});
|
||||
this.recordTileUpdate(tile);
|
||||
}
|
||||
|
||||
units(...types: UnitType[]): Unit[] {
|
||||
@@ -379,6 +377,7 @@ export class GameImpl implements Game {
|
||||
|
||||
executeNextTick(): GameUpdates {
|
||||
this.updates = createGameUpdatesMap();
|
||||
this.tileUpdatePairs.length = 0;
|
||||
this.execs.forEach((e) => {
|
||||
if (
|
||||
(!this.inSpawnPhase() || e.activeDuringSpawnPhase()) &&
|
||||
@@ -417,6 +416,20 @@ export class GameImpl implements Game {
|
||||
return this.updates;
|
||||
}
|
||||
|
||||
private recordTileUpdate(tile: TileRef): void {
|
||||
this.tileUpdatePairs.push(tile, this._map.tileState(tile));
|
||||
}
|
||||
|
||||
drainPackedTileUpdates(): Uint32Array {
|
||||
const pairs = this.tileUpdatePairs;
|
||||
const packed = new Uint32Array(pairs.length);
|
||||
for (let i = 0; i < pairs.length; i++) {
|
||||
packed[i] = pairs[i];
|
||||
}
|
||||
pairs.length = 0;
|
||||
return packed;
|
||||
}
|
||||
|
||||
private hash(): number {
|
||||
let hash = 1;
|
||||
this._players.forEach((p) => {
|
||||
@@ -588,10 +601,7 @@ export class GameImpl implements Game {
|
||||
owner._lastTileChange = this._ticks;
|
||||
this.updateBorders(tile);
|
||||
this._map.setFallout(tile, false);
|
||||
this.addUpdate({
|
||||
type: GameUpdateType.Tile,
|
||||
update: this.toTileUpdate(tile),
|
||||
});
|
||||
this.recordTileUpdate(tile);
|
||||
}
|
||||
|
||||
relinquish(tile: TileRef) {
|
||||
@@ -609,10 +619,7 @@ export class GameImpl implements Game {
|
||||
|
||||
this._map.setOwnerID(tile, 0);
|
||||
this.updateBorders(tile);
|
||||
this.addUpdate({
|
||||
type: GameUpdateType.Tile,
|
||||
update: this.toTileUpdate(tile),
|
||||
});
|
||||
this.recordTileUpdate(tile);
|
||||
}
|
||||
|
||||
private updateBorders(tile: TileRef) {
|
||||
@@ -1017,11 +1024,11 @@ export class GameImpl implements Game {
|
||||
): Set<TileRef> {
|
||||
return this._map.bfs(tile, filter);
|
||||
}
|
||||
toTileUpdate(tile: TileRef): bigint {
|
||||
return this._map.toTileUpdate(tile);
|
||||
tileState(tile: TileRef): number {
|
||||
return this._map.tileState(tile);
|
||||
}
|
||||
updateTile(tu: TileUpdate): TileRef {
|
||||
return this._map.updateTile(tu);
|
||||
updateTile(tile: TileRef, state: number): void {
|
||||
this._map.updateTile(tile, state);
|
||||
}
|
||||
numTilesWithFallout(): number {
|
||||
return this._map.numTilesWithFallout();
|
||||
|
||||
Reference in New Issue
Block a user