perf(ui): switch UI layers to wall-time tick intervals (#3025)

## Description:

Preparatory change for the upcoming “unbounded worker” work: 
decouple expensive UI layer updates from game tick frequency by moving
UI ticking to wall-clock intervals. This reduces redundant UI work when
the simulation runs faster than real time (notably replays /
singleplayer at speed > 1) while keeping the UI responsive and
predictable.

## Changes:

- Add optional `Layer.getTickIntervalMs()` and enforce it in
`GameRenderer.tick()` using wall-clock time.
- Convert key UI layers from tick-modulus gating to fixed intervals:
  - `ControlPanel`: 100ms
  - `GameRightSidebar`: 250ms
  - `MainRadialMenu`: 500ms
  - `Leaderboard`, `NameLayer`, `ReplayPanel`, `TeamStats`: 1000ms


## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] 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-01-26 05:14:55 +01:00
committed by GitHub
parent de3794313d
commit 0bfad91c04
9 changed files with 90 additions and 46 deletions
+5 -3
View File
@@ -39,6 +39,10 @@ export class ControlPanel extends LitElement implements Layer {
private _lastTroopIncreaseRate: number;
getTickIntervalMs() {
return 100;
}
init() {
this.attackRatio = Number(
localStorage.getItem("settings.attackRatio") ?? "0.2",
@@ -81,9 +85,7 @@ export class ControlPanel extends LitElement implements Layer {
return;
}
if (this.game.ticks() % 5 === 0) {
this.updateTroopIncrease();
}
this.updateTroopIncrease();
this._maxTroops = this.game.config().maxTroops(player);
this._gold = player.gold();