Skip to content

fix: stabilize tutorial cascade state#68

Merged
protostatis merged 1 commit into
mainfrom
fix/tutorial-cascade-hotfix
Jul 21, 2026
Merged

fix: stabilize tutorial cascade state#68
protostatis merged 1 commit into
mainfrom
fix/tutorial-cascade-hotfix

Conversation

@protostatis

Copy link
Copy Markdown
Owner

Summary

  • preserve tutorial board state while searching for a chain-producing move
  • clone the demo snapshot on restore and remove the production debug global
  • avoid advancing the match-3 engine turn twice per wager move
  • declare tutorial lifecycle effect dependencies

Verification

  • npm run lint
  • npm test (15 tests)
  • npm run build

@protostatis protostatis left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Sky's Code Review

This PR fixes several tutorial state bugs in a match-3 game: (1) prevents mutation of saved board snapshots by cloning on restore, (2) prevents chain-search probes from corrupting the live board by saving/restoring full engine state around each candidate, (3) removes a production debug global, (4) fixes a double endTurn bug in the wager controller, and (5) declares useEffect dependencies to avoid stale closures. The changes are well-targeted and the approach is sound.

Verdict: Approve

Comments

  • The window.__tutEngine debug global removal is good hygiene — leaving debug globals in production builds can leak internal state and confuse DevTools users.
  • The chain-search pattern (save state → probe candidates → restore state) is a clean way to avoid polluting the live board. If this pattern recurs elsewhere in the codebase, consider extracting a withBoardSnapshot(engine, fn) utility.
  • This is a frontend game PR, not infrastructure — the security/shell/Docker concerns from the review checklist don't apply here. Review focused on correctness and reliability of the game logic.

Reviewed by Sky — Unchained Sky engineering agent

Inline Comments (could not attach to lines)

dashboard-frontend/game/src/components/TutorialScreen.jsx:21 — Good fix: returning reset directly as the cleanup function is cleaner than the previous () => c.reset() wrapper, and declaring [start, reset] as deps eliminates the stale-closure risk from the empty-deps pattern.

dashboard-frontend/game/src/game/useTutorialController.js:337 — Restoring engine.score = scoreBeforeSearch after each candidate probe is important — without it, cascade evaluation during the probe would accumulate phantom points. Good catch.

dashboard-frontend/game/src/game/useTutorialController.js:332 — Tip: if initBoard() or runCascadeStep() have side effects beyond cells, _nextId, and score (e.g. internal counters, event listeners), those would also need snapshotting. Worth a quick audit if you haven't already.

dashboard-frontend/game/src/game/useWagerController.js:279 — Removing the duplicate engine.endTurn() is the right call if runCascade already calls it internally. However, if any future code path calls runCascade without a corresponding endTurn elsewhere, turns will silently desync. Consider adding a comment at the runCascade definition noting that it owns endTurn.

@protostatis
protostatis merged commit b53352f into main Jul 21, 2026
3 checks passed
@protostatis
protostatis deleted the fix/tutorial-cascade-hotfix branch July 21, 2026 03:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant