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>
53 lines
2.5 KiB
Markdown
53 lines
2.5 KiB
Markdown
# Accessibility mod — developer documentation
|
||
|
||
Making *Sulphur Memories: Alchemist* 0.4.2 blind-accessible.
|
||
Player-facing keymap and setup: `accessibility/README.md`.
|
||
|
||
**Picking this up mid-stream? Read [scratch.md](scratch.md) first.** It is the
|
||
living handoff document: current state, every bug found and why, and the traps.
|
||
|
||
| Doc | Contents |
|
||
|---|---|
|
||
| [scratch.md](scratch.md) | **Start here.** Working state, bugs found, gotchas, keymap, how to run the testbed. |
|
||
| [01-architecture.md](01-architecture.md) | How the game is built: states, console, level model, keybindings. |
|
||
| [02-hooking-strategy.md](02-hooking-strategy.md) | How the mod attaches with (near) zero edits to game files. |
|
||
| [03-implementation-plan.md](03-implementation-plan.md) | The original six-phase plan, with outcomes. |
|
||
| [04-open-questions.md](04-open-questions.md) | Questions raised; see 05 for answers. |
|
||
| [05-decisions.md](05-decisions.md) | Decisions made, and the D4 correction. |
|
||
|
||
## Status
|
||
|
||
**Phases 0–5 complete.** 23 state descriptors, 5 patches, 26/26 testbed checks,
|
||
history unit tests passing.
|
||
|
||
**Game-file footprint: one line in `main.lua`.** Verify at any time:
|
||
|
||
```
|
||
git diff --stat vanilla-0.4.2 -- . ':!accessibility' ':!.gitignore'
|
||
```
|
||
|
||
## The three findings that shaped everything
|
||
|
||
1. **The game was already keyboard-complete.** All 28 states implement
|
||
`keypressed`, with a full rebindable-keys system. The gap was that nothing
|
||
*announced* what was focused — so the job was narration, not reimplementation.
|
||
|
||
2. **The game already writes the text.** `console.print` is a single chokepoint
|
||
for all log messages; `level.getCursorMessage()` describes tiles;
|
||
`inventoryCursorPopup.set` covers four screens. Mostly we re-route existing
|
||
strings to speech rather than writing a description engine.
|
||
|
||
3. **Everything is a `require`d singleton, and `debug.getupvalue` works.** Module
|
||
functions can be patched in place, and file-local focus variables
|
||
(`selectedOption`, …) are readable from outside. Hence the one-line footprint.
|
||
|
||
## Architecture in one breath
|
||
|
||
`main.lua` calls `require("accessibility").initialize()`. That patches module
|
||
singletons (`console.print`, `popupStack.add`, `inventoryCursorPopup.set`,
|
||
`modules.slider`), wraps `states.switch` / `update` / `keypressed` / `textinput`,
|
||
and installs a global hotkey layer. Per-screen narration lives in
|
||
`accessibility/states/<statename>.lua` descriptors, read via `debug.getupvalue`.
|
||
A startup self-test reports which patches and probes still resolve — the canary
|
||
for a future game version moving something.
|