maniator / maniator/verticopolis
[P3] Interaction state is scattered across five sources, so derived UI state can be computed somewhere skippable
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 5
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
Deferred from the /gds-code-review of the desktop command seam (PR #715).
Five different places answer "is the game interactable right now": app.shownChoice, app.shownUpdate, #modal.open, #splash existing, and #crash-screen existing. GameApp carries 27 mutable public fields that friend-modules write directly.
That scatter caused a real defect found in this review. The host-command availability push sat below runFrame's early return on app.shownChoice || app.shownUpdate, so the desktop shell was told "everything is available" in exactly the state where #modal.open guaranteed every command would be refused. Two of the five sources disagreeing, in the one state that mattered. Fixed at the instance in #715; this row is the class.
There are also three hand-rolled computed-selector-with-change-detection implementations: UI.paletteScanKey, lastUiUpdate, and the new lastAvailabilityKey.
Party ruling (2026-07-29): no state management library. Three app-specific reasons:
src/engine/is deliberately framework-free and Classic is byte-locked, so a store creeping into simulation state risks golden masters for no gain. None of the pain is insim.- The
adoptSimdesign depends on friend-modules re-readingapp.simper call, which is the property a reactive store would most want to "fix". - All five disagreeing sources are UI chrome state.
sim,engine,audio, andgridare fine.
Fix shape: one module owning interaction state with a change notification, replacing the DOM queries in hostCommands.refusalFor and the 6 Hz poll in tickHostCommands, and collapsing the three dirty-gates into one implementation.
Only worth doing if it owns all five sources. Owning two would add a sixth source rather than remove five, which is why it was kept out of #715. Needs a design doc first per the deliberate-addition rule.
No engine, save, or gameplay impact. /bmad-code-review.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the interaction sources named in the issue—app.shownChoice, app.shownUpdate, #modal.open, #splash, and #crash-screen—and trace hostCommands.refusalFor, tickHostCommands, UI.paletteScanKey, lastUiUpdate, and lastAvailabilityKey. Begin with the required design doc; done means one module owns all five sources, not two, with unified change notification and dirty-gate behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- desktop, frontend
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100