mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-05 08:26:03 +00:00
Dispose WebGL renderer when a game stops 🧹 (#4295)
## Problem `ClientGameRunner.stop()` tore down the worker, network, and sound, but left the `MapRenderer` (and its WebGL context), the WebGL canvas, the input overlay, and the self-driving RAF loop in place. When you exit a game via the **Exit button** or browser **back**, the page navigates to `/`, so the browser reclaims everything — that path is fine. But you can start a new game **without** a reload: matchmaking and joining another lobby go through `handleJoinLobby`, which calls `lobbyHandle.stop(true)` then `joinLobby()` on the same document. The old WebGL context stayed alive (the never-cancelled RAF kept it referenced, so it wasn't even GC'd), and each new game stacked another context. After a few games, mobile browsers hit their WebGL context limit — matching the repro in #4267. ## Fix `stop()` now disposes the renderer: - cancels the self-driving RAF loop and disconnects the frame-loop resize observer - disposes the `MapRenderer` (frees all GPU resources) - removes the WebGL canvas and the input overlay from the DOM `GPURenderer.dispose()` additionally calls `WEBGL_lose_context.loseContext()` so the context is released promptly instead of waiting on unreliable GC. The territory-patterns settings listener is wired to the existing graphics `AbortController` so it no longer outlives the disposed view. The cleanup runs unconditionally in `stop()` (a superseded join can stop before the game becomes active) and is idempotent against repeated `stop()` calls. Fixes #4267 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1226,5 +1226,9 @@ export class GPURenderer {
|
||||
this.gl.deleteTexture(this.sceneTarget.tex);
|
||||
this.lastUnits = new Map();
|
||||
this.lastStructures = new Map();
|
||||
// Deleting GL resources isn't enough — the context itself counts against
|
||||
// the browser's WebGL context limit until it's GC'd, which is unreliable
|
||||
// on mobile. Explicitly drop it so repeated game starts don't overflow.
|
||||
this.gl.getExtension("WEBGL_lose_context")?.loseContext();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user