Repository navigation
fix(render): incremental redraw during replay playback - #151
Merged
Merged
Conversation
play-replay repainted the whole screen every frame via render-full, which first blanks the entire terminal with the bg colour (render.lg: "blank entire terminal") and then redraws. On the web build that blank-then-repaint reads as a visible full-screen flicker on each replayed turn (#110). Mirror the live play loop (play/play-advance): render-dirty per turn — an incremental FOV-delta redraw with no screen clear — and fall back to a full repaint only on a floor change, where the whole viewport legitimately changes. Render-only; the seed chain and action-log are untouched, so replay stays bit-identical. Verified in the browser: the replayed run animates cell-by-cell with no full-screen blank between frames. Closes #110 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Collaborator
Author
|
Confirmed fixed via this replay pr-151 AQAAAAAA... To see the problem, try same against 149 (if still open): Confirmed fixed via this replay pr-149 AQAAAAAA... |
Collaborator
Author
nnunley
approved these changes
Jul 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
play-replaynow redraws incrementally during playback — a dirty FOV-delta render per turn — instead of full-repainting every frame. Full repaint stays only for a floor change, where the whole viewport turns over anyway.Independent of the render-perf stack (#145/#146/#149): the change is in
play-replay, notrender.lg, andrender-dirtyis already the live path onmain.Why
render-fullblanks the entire terminal before it repaints — it paints every row with the background colour, then draws the panels on top. The live game loop only pays that cost when it has to (floor change or resize); every normal turn goes throughrender-dirty, which touches only the cells that changed and never clears.play-replaynever adopted that split — it calledrender-fullon every action. So each replayed turn cleared the screen and repainted it, and on the web build that blank-then-repaint reads as a full-screen flicker across the whole playback (#110).How
Mirror
play/play-advance: compare(:depth w')against the pre-action depth,render-dirty w' wwhen they match,render-fullon a floor change.render-dirtytakes the previous world as its diff base — the reduce already carries it, so threading it in is the whole change.I left out the live loop's resize branch on purpose. Replay has no interactive resize mid-playback; a stray resize would leave one stale frame until the next turn redraws, which isn't worth polling
term/sizeevery frame for. Easy to add back if that turns out to matter.Safety
Render-only. The seed chain and action log are untouched, so a replayed run stays bit-identical — same reconstruction, only fewer escapes drawing it. Verified in the browser: the replayed run animates cell-by-cell with the map, HUD, and log staying put frame to frame, no full-screen blank between turns. Existing suite passes.
Closes #110