docs: final handoff pass

Adds accessibility/README.md, the player-facing setup and keymap reference --
the thing to read before playtesting.

Brings the developer docs in line with what was actually built:

- docs/README.md rewritten as an index with current status and a one-paragraph
  architecture summary.
- docs/scratch.md gains a HANDOFF section: state of play, the commands to run
  after any change, the five traps that each cost real debugging time, what is
  NOT verified and why, deliberate omissions, and how to rebase onto a future
  game version.
- docs/03-implementation-plan.md gains a status banner listing where the
  implementation deliberately diverged from the plan (menu narration pulled
  forward as a blocker, levelCursorPopup not patched, tryInteract insufficient
  as a tracker filter, testbed added, no settings UI built).
- docs/04-open-questions.md gains a resolution banner: Q6 and Q8 remain open.

Also records that the testbed check count varies between runs (23-26) because
some blocks are conditional, so what matters is zero failures rather than the
total.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Accessibility Mod
2026-08-01 22:25:09 +02:00
co-authored by Claude Opus 5
parent 96ec79ed75
commit 6380998376
5 changed files with 284 additions and 15 deletions
+86 -2
View File
@@ -2,8 +2,8 @@
**Read this first on any handoff.** Living document: update it whenever state changes, before ending a turn.
Last updated: 2026-08-01 · Currently: **Phases 0–3 done + menus/dialogue.
Phases 4-5 done. Remaining: polish, mod settings, distribution.**
Last updated: 2026-08-01 · Currently: **Phases 0–5 COMPLETE. Handed off for
playtesting.** Remaining work is polish, mod settings and distribution.
**Game is playable start-to-finish by ear** from main menu through the intro
conversation into gameplay, plus journal, character, actions and inventory —
@@ -18,6 +18,11 @@ rm -rf ~/AppData/Roaming/LOVE/Alchemist # start from a clean save
It drives the game by code via `love.event.push`, navigating by *reading* focus
rather than counting keypresses. Every bug listed below was caught by it.
⚠ **The check COUNT varies between runs (23–26); this is expected.** Several
blocks are conditional — the config-menu section only runs if `selectByText`
lands on "Options", and mouse-hover can move menu focus at startup (see trap 2).
**What matters is `0 failures`, not the total.**
---
## What this project is
@@ -489,3 +494,82 @@ utterance — speech is verifiable from the log, not only by ear. `!` after
- `.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`.
---
## HANDOFF — read this if you are resuming
### State of play
Phases 0–5 complete. **23 state descriptors, 5 patches, 26/26 testbed checks**,
history unit tests passing, **one line changed in the game** (`main.lua`).
Everything in the original brief is implemented: console speech with
line-by-line review, the object tracker with the requested key scheme, tile
exploration, wall tones, and keyboard+speech access to every screen.
### First thing to do after any change
```
lua accessibility/tests/test_history.lua # pure Lua, instant
rm -rf ~/AppData/Roaming/LOVE/Alchemist # clean save
"C:/Program Files/LOVE/lovec.exe" . --a11y-test # ~4 min, 26 checks
git diff --stat vanilla-0.4.2 -- . ':!accessibility' ':!.gitignore' # must stay: main.lua | 1 +
```
### The five traps (all cost real debugging time — don't rediscover them)
1. **`love.keypressed` is captured by value.** `states.setup()` runs
`love[cb] = love[cb] or states[cb]` *before* us. Wrapping the `states` table
field alone does nothing for `keypressed`/`textinput` — you must also
reassign `love.keypressed`. `switch`/`update` are fine (looked up at call
time). **Any new callback you wrap needs the same treatment.**
2. **Focus moves without a keypress.** `main_menu.mousemoved` assigns
`selectedOption` from cursor position. Hence focus is *polled* in the update
hook, not announced only on keypress.
3. **Nested `states.switch` announces inner-first.** `ingame.open()` can switch
straight to `ingame_dialogue`. We announce after `realSwitch` returns, so the
outer announcement would clobber the inner one — guarded by checking
`states.getCurrent() ~= newState`.
4. **`states.lua` requires with a SLASH** (`require("states/"..name)`).
`require("states.main_menu")` loads a *second independent copy* with its own
upvalues. Always match the slash.
5. **Probes may need chaining or a cross-function search.** Some locals are
upvalues of an inner function (`narration` → `continueNarration`) or are only
touched in `open()` (`actions_menu`, `worldmap`). Use `menus.getAnyUpvalue`.
Use `menus.hasUpvalue` when you need "exists" rather than "has a value".
### Not verified — needs a real playthrough
These are blocked on content the prologue does not contain, **not** known broken:
- **Tracker categories** Items / Alchemy / Exits / Creatures / Terrain. Only
Interactables is populated in the tutorial house. Diagnostic: the testbed
prints `tracker contents:` with per-category kind names.
- **Inventory item names** — inventory is empty in the prologue, so only the
"empty slot" path has run.
- **The quantity slider** (`patches/slider.lua`). Confirmed *applied* by the
self-test but never exercised: `ingame_wait` is unreachable because
`tutorial_bed` has an empty `tryInteractFunction` by design, and
craft/refine/trade need an alchemy table and real items. The testbed already
has `walkTo()` and tracker-based bed lookup ready for when one is reachable.
- **Popup announcements** (`patches/popupstack.lua`) — loot/quest/recipe popups
did not fire during the prologue run.
### Known-missing features (deliberate, not bugs)
- **No mod settings UI.** Verbosity (`describe.verbosity`), wall-tone config
(`walltones.config`) and `speech.logToConsole` are code-level fields only.
- **Q6 unanswered**: our hotkeys are a separate scheme, not registered in the
game's own rebinding UI. They are therefore not user-rebindable.
- **Q8 unanswered**: no exhaustive keyboard-reachability audit was done. All 28
states implement `keypressed`, and every screen reached so far was navigable,
but this was not proven screen-by-screen.
- **Distribution not designed** (D1 deferred). Any shipped build must place the
Tolk DLLs beside the executable — they cannot live inside a `.love`.
### If a future game version breaks something
Run the game and read the startup self-test. It reports every patch and every
descriptor probe. `PROBE BROKEN: no upvalue 'x'` means that local was renamed —
fix the descriptor in `accessibility/states/<state>.lua`. `ok (unset until
opened)` is normal.
To rebase the mod onto a new game version: commit the new pristine tree on top
of the `vanilla-0.4.2` baseline, then replay the mod commits. The only game-file
conflict possible is the single `main.lua` line.