| D3 | **Small explicit patches** to game files are allowed where they simplify things — but every state descriptor also carries a `probe` spec so we can flip to zero-edit `debug.getupvalue` mode if the game ships fused on Steam. `render` is shared by both backends. |
| D4 | Six tracker categories confirmed and coverage-verified: Creatures / Items / Exits / Interactables / Terrain features / Alchemy. |
| — | Screen reader: **NVDA**. Running the game via `lovec` during dev is approved. |
| — | User is blind — all verification must be describable in text; don't rely on screenshots. |
## Still-open questions (in `04-open-questions.md`)
Q6 keybinding integration vs separate · Q8 full keyboard audit as deliverable?
None block Phase 0. Q4 lands in Phase 1, Q5 + verbosity in Phase 2.
---
## Key facts worth not rediscovering
- **`console.print(msg, colorTemplate)`** in `modules/console.lua` is the *single* chokepoint for all game log text. Repeated identical messages coalesce into `"msg (x3)"` via a `times` counter. Buffer entries expire after 3s — useless as history, so we keep our own.
- **`level.getCursorMessage()`** returns the description under the examine cursor (actor first, then top visible tile). The game already has a full arrow-key examine mode: `states/ingame_observe.lua`.
- **`cursorPopup.set(...)`** — patching `views/inventoryCursorPopup.lua` + `views/levelCursorPopup.lua` narrates focus in `inventory`, `craft`, `refine`, `trade`, `ingame_observe` at once.
- **All 28 states already implement `keypressed`.** The gap is narration, not reachability.
- **`modules/tile.lua:234`**: `tile.tryInteract = (self.loot or self.tryInteractFunction) and function...` — authoritative "player can do something here" flag. Basis of tracker classification.
- **Template counts:** 231 tiles, 40 actors, 344 items. Parent inheritance is *already flattened* by `modules/tile/preprocess.lua` during `love.load`, so read fields directly.
| `main.lua` | +1 line: `require("accessibility").initialize()` after `console.prepare()` | Sole mod entry point. Placed there because templates, keybindings, `states.setup()` and the console canvas are all ready by then, and it's before the first `states.switch()`. |
-`.luacheckrc` uses `std = "min+alch"` with an explicit globals list — add mod globals there to keep lint clean.
- Upstream quirk (not ours to fix): `modules/tile/preprocess.lua` flattens parents in a single `pairs()` pass, so a grandchild may inherit from a not-yet-flattened parent depending on hash order.
- Tolk DLL sources on this machine: `D:\code\cafe`, `D:\code\dragonrpg-mapmaker`, `D:\code\DragonWarriorAccess`.