From dcd5b550cf2c4f0a1e2d67837c23a0c6f7a7ec34 Mon Sep 17 00:00:00 2001 From: scamiv <6170744+scamiv@users.noreply.github.com> Date: Sun, 23 Nov 2025 21:03:22 +0100 Subject: [PATCH] Worker now self-clocks; no heartbeats needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GameRunner exposes pending work via a new hasPendingTurns() so the worker can check whether more ticks need to be processed. Worker auto-runs ticks: as soon as it initializes or receives a new turn, it calls processPendingTurns() and loops executeNextTick() while hasPendingTurns() is true. No more "heartbeat" message type; the worker no longer depends on the main thread’s RAF loop to advance the simulation. Client main thread simplified: Removed CATCH_UP_HEARTBEATS_PER_FRAME, the heartbeat loop, and the lastBeatsPerFrame tracking. keepWorkerAlive now just manages frame skipping + draining. When it decides to render (based on renderEveryN), it drains pendingUpdates, merges them, updates GameView, and runs renderer.tick(). Because rendering a batch always implies draining, we restored the invariant that every GameView.update is paired with a layer tick() (no more lost incremental updates). MAX_RENDER_EVERY_N is now 5 to keep the queue from growing too large while the worker sprints. --- src/client/ClientGameRunner.ts | 14 +-------- .../graphics/layers/PerformanceOverlay.ts | 7 +++-- src/core/GameRunner.ts | 4 +++ src/core/worker/Worker.worker.ts | 29 +++++++++++++++++-- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/client/ClientGameRunner.ts b/src/client/ClientGameRunner.ts index e0804b885..348e80d6d 100644 --- a/src/client/ClientGameRunner.ts +++ b/src/client/ClientGameRunner.ts @@ -216,7 +216,6 @@ export class ClientGameRunner { private catchUpMode: boolean = false; private readonly CATCH_UP_ENTER_BACKLOG = 120; // turns behind to enter catch-up private readonly CATCH_UP_EXIT_BACKLOG = 20; // turns behind to exit catch-up - private readonly CATCH_UP_HEARTBEATS_PER_FRAME = 5; //upper bound on heartbeats per frame when in catch-up mode private pendingUpdates: GameUpdateViewData[] = []; private isProcessingUpdates = false; @@ -225,8 +224,7 @@ export class ClientGameRunner { private renderEveryN: number = 1; private renderSkipCounter: number = 0; private lastFrameTime: number = 0; - private readonly MAX_RENDER_EVERY_N = 60; - private lastBeatsPerFrame: number = 1; + private readonly MAX_RENDER_EVERY_N = 5; constructor( private lobby: LobbyConfig, @@ -317,7 +315,6 @@ export class ClientGameRunner { this.processPendingUpdates(); } }); - const worker = this.worker; const keepWorkerAlive = () => { if (this.isActive) { const now = performance.now(); @@ -327,14 +324,6 @@ export class ClientGameRunner { } this.lastFrameTime = now; - const beatsPerFrame = this.catchUpMode - ? this.CATCH_UP_HEARTBEATS_PER_FRAME - : 1; - this.lastBeatsPerFrame = beatsPerFrame; - for (let i = 0; i < beatsPerFrame; i++) { - worker.sendHeartbeat(); - } - // Decide whether to render (and thus process pending updates) this frame. let shouldRender = true; if (this.catchUpMode && this.renderEveryN > 1) { @@ -541,7 +530,6 @@ export class ClientGameRunner { this.backlogTurns, this.catchUpMode, this.renderEveryN, - this.lastBeatsPerFrame, ), ); diff --git a/src/client/graphics/layers/PerformanceOverlay.ts b/src/client/graphics/layers/PerformanceOverlay.ts index 3cd688449..bd101f80d 100644 --- a/src/client/graphics/layers/PerformanceOverlay.ts +++ b/src/client/graphics/layers/PerformanceOverlay.ts @@ -435,7 +435,7 @@ export class PerformanceOverlay extends LitElement implements Layer { private renderEveryN: number = 1; @state() - private beatsPerFrame: number = 1; + private beatsPerFrame: number | null = null; updateTickMetrics( tickExecutionDuration?: number, @@ -491,7 +491,7 @@ export class PerformanceOverlay extends LitElement implements Layer { this.renderEveryN = renderEveryN; } if (beatsPerFrame !== undefined) { - this.beatsPerFrame = beatsPerFrame; + this.beatsPerFrame = beatsPerFrame ?? null; } this.requestUpdate(); @@ -647,7 +647,8 @@ export class PerformanceOverlay extends LitElement implements Layer { ${this.inCatchUpMode ? html`