Skip to content

Restore on webgl context loss#3968

Open
VariableVince wants to merge 2 commits into
mainfrom
webgl-contextrestore
Open

Restore on webgl context loss#3968
VariableVince wants to merge 2 commits into
mainfrom
webgl-contextrestore

Conversation

@VariableVince
Copy link
Copy Markdown
Contributor

@VariableVince VariableVince commented May 19, 2026

Description:

When WebGL context is lost, restore context and all elements.

In GameView, handle potentially transient undefined states during context loss gracefully.

Test with chrome://gpucrash from another tab, then return to the game tab to see it being restored.

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:

tryout33

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cad90063-c3da-4403-adb5-909f5628d82d

📥 Commits

Reviewing files that changed from the base of the PR and between b6750bc and f338e89.

📒 Files selected for processing (1)
  • src/client/ClientGameRunner.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/client/ClientGameRunner.ts

Walkthrough

Refactors GameView for nullable/lazy renderer and adds a contextrestored event. Adds clearCaches() to WebGLFrameBuilder. Client runner now listens for contextrestored and orchestrates a full GPU state reupload (terrain, tiles, trails, structures, railroad, units). Minor territory-pass guards added.

Changes

WebGL Context Recovery

Layer / File(s) Summary
Context restored event contract
src/client/render/gl/Events.ts
contextrestored event added to GameViewEventMap with payload { type: "restored" }.
GameView nullable renderer and recovery infrastructure
src/client/render/gl/GameView.ts
GameView treats GPURenderer as nullable, adds initRenderer() for lazy init, installs WebGL context lost/restored listeners, caches icons and frame callbacks, and converts renderer facades to optional chaining with safe fallbacks.
WebGLFrameBuilder cache clearing
src/client/WebGLFrameBuilder.ts
Adds clearCaches() to reset internal renderer-side caches (knownSmallIDs, localPlayerSmallID) to force full re-upload on next update.
Context restoration orchestration in game runner
src/client/ClientGameRunner.ts
mountWebGLFrameLoop retains persistent WebGLFrameBuilder, registers contextrestored handler to clear caches, regenerate and re-upload terrain bytes/refs, re-upload tile/trail/frameData (including units typed as Map<number, UnitState>), force structure/railroad uploads, and flush updates via builder.update(gameView); returns { builder }.
Territory pass dirty-tracking optimization
src/client/render/gl/passes/TerritoryPass.ts
applyLiveDelta and applyLiveTrailDelta skip expanding constrained dirty-row bounds when a full upload is already pending, while still marking dirty tiles/trails.

Sequence Diagram

sequenceDiagram
  participant WebGL as WebGL Context
  participant GameView
  participant GPURenderer
  participant Client as ClientGameRunner
  participant FrameBuilder as WebGLFrameBuilder
  WebGL->>GameView: contextlost
  GameView->>GPURenderer: dispose() / set renderer = null
  GameView->>Client: emit "contextrestored"
  Client->>FrameBuilder: clearCaches()
  Client->>FrameBuilder: regenerate terrain refs/bytes & reupload frameData (tiles/trails/units)
  FrameBuilder->>GameView: update(gameView)
  GameView->>GPURenderer: initRenderer() (lazy)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • evanpelle

Poem

When contexts drop and pixels sleep,
Builders wake and caches sweep,
Terrain reborn, the tiles align,
Renderer springs to life — the frame's back online. 🎮✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly describes the main change: implementing WebGL context restoration when context is lost.
Description check ✅ Passed The description explains the core feature (WebGL context restoration), provides testing instructions, and confirms completion of required checks.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/client/render/gl/GameView.ts`:
- Around line 255-256: The updatePalette method currently only calls
this.renderer.updatePalette(paletteData) and neglects to update the cached
palette used during restore; modify updatePalette (in class GameView) to also
store a copy of the incoming palette into this.paletteData (e.g.,
this.paletteData = new Float32Array(paletteData) or similar) so the
restore/rebuild path uses the runtime-updated palette; keep the existing
renderer.updatePalette call intact.
- Around line 74-105: The new GPURenderer is created with a default camera after
a context loss because we never save/reapply the previous camera; modify the
class to capture the current camera into a cachedCameraState before disposing
(in onContextLost — call renderer.getCameraState() or read renderer.camera) and
then, inside initRenderer (or immediately after creating the new GPURenderer),
reapply that state via renderer.setCameraState(cachedCameraState) (or assign
renderer.camera = cachedCameraState) so the view is restored; ensure
onContextRestored still calls initRenderer and that cachedCameraState is
cleared/validated as needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 07c6744a-4b13-4e52-aeeb-066be4871586

📥 Commits

Reviewing files that changed from the base of the PR and between 15ac42b and b6750bc.

📒 Files selected for processing (5)
  • src/client/ClientGameRunner.ts
  • src/client/WebGLFrameBuilder.ts
  • src/client/render/gl/Events.ts
  • src/client/render/gl/GameView.ts
  • src/client/render/gl/passes/TerritoryPass.ts

Comment thread src/client/render/gl/GameView.ts
Comment thread src/client/render/gl/GameView.ts
@github-project-automation github-project-automation Bot moved this from Triage to Development in OpenFront Release Management May 19, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 19, 2026
@VariableVince VariableVince marked this pull request as ready for review May 19, 2026 03:01
@VariableVince VariableVince requested a review from a team as a code owner May 19, 2026 03:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Development

Development

Successfully merging this pull request may close these issues.

1 participant