Captures the final code reviewer's recommendations: hard prerequisites (read/light/extinguish/use verbs; disambiguation; endedWith ending screen), should-fix items (look-at parser polish, theme-state divergence, roomState type lie), and a polish backlog. Read this before generating the next plan.
3.8 KiB
Halfstreet — notes for the room-prose follow-on plan
These notes carry over from the final code review of the engine/UI/bible plan (2026-05-08). Read before generating the room-prose implementation plan.
Hard prerequisites — land BEFORE authoring rooms
These are gaps the engine ships with that will block specific rooms or items in the bible. Make them the first commits of the follow-on plan.
-
Add
read,light,extinguish,useverb handlers to the dispatcher. The bible's items include a lamp (light/extinguish), letter and burial-register page (read), lamp+matches combination (useorlight with). None have dispatcher handlers in the shipped engine. Authoring rooms around items players can't interact with creates blocked playthroughs. -
Wire disambiguation end-to-end. The parser already returns
unknown-nounfor ambiguous nouns and the type system hasPendingDisambiguation, but the dispatcher never sets it. The bible has two keys (brass-key,iron-key) both aliasedkey; without disambiguation,take keysilently fails for any player who doesn't type the full noun. Plan: change the parser to return a dedicated{kind: 'ambiguous', candidates}variant, and have the dispatcher convert it into apendingDisambiguationset + a "Which key — …?" narration. -
Implement the ending-screen UI and
endedWithflag-checking logic. All three endings are written verbatim in the bible. The engine has theendedWithfield but never sets it; the terminal never checks it. Without this, a true-ending playthrough setsrevenantLaid = trueand the player keeps typing into a terminal that should have shown the ending. Land this as the first commit of the prose plan, then author the vault and ending rooms last so they can be tested end-to-end.
Should-fix while you're in there
-
look at Xparser polish. Strip leading stop-words (at,the,a,an) from the noun token list before matching.look at lampcurrently fails noun resolution; onlyexamine lampandx lampwork. Spec sayslook at Xshould examine X. -
Theme-state divergence. When the player clicks
[B]/[C],theme.tsupdates the DOM and localStorage but does not updatestate.theme. Nextthememeta-command then toggles from the stalestate.theme. Cleanest fix: removethemefromGameStateentirely (it's a UI preference, not game state) and have the engine'sthememeta-verb read the DOM via the UI layer. -
Type lie in
roomState. The type isRecord<string, string | boolean | number>but the code storesstring[]fordroppedItems/takenItemsviaascasts in both directions. Widen the union to includestring[]. -
Add a self-contained locked-exit-with-key dispatcher test. The current
dispatcher.test.ts"opens a locked exit" test is a stub (expect(true).toBe(true)). The sample world's locked exit is unreachable without the key behind it, so the playthrough test can't cover this either. Add a 15-line synthetic world to dispatcher.test.ts.
Polish / nice-to-have
- PageUp/PageDown transcript scrolling (spec calls it out, not implemented).
- Cursor blink at 1.05Hz (currently uses native ~0.53Hz
caret-coloronly). - Old-line opacity fade at the top of the transcript (spec, not implemented).
- Scanline accessibility toggle (
[?]settings dropdown, spec, not implemented). Important for photosensitivity.
What's already good — don't refactor
- Three-layer architecture (world data → engine → UI) holds end-to-end. Don't introduce cross-layer shortcuts.
- Engine purity (no Date, Math.random, console, DOM) is verified. Keep new verbs pure.
- Type contract and
verbatimModuleSyntaxdiscipline are clean. Useimport typefor type-only imports. - Test coverage is meaningful, not gamed. Match this density for new verbs.