Files
alchemist-accessibility/accessibility/docs/README.md
T
Accessibility ModandClaude Opus 5 18e6473dd3 docs: add CLAUDE.md so agents start from the accessibility context
New sessions land in what looks like a game repository and start treating the
task as game development, so the accessibility framing had to be re-explained
every time. CLAUDE.md states it up front: everything outside accessibility/ is
the vanilla game and is read-only reference, and a request phrased as a game
bug ("the journal doesn't work") means a screen reader user cannot use it.

Deliberately a pointer rather than a copy, so it cannot drift out of sync with
accessibility/docs/. It sends readers to docs/scratch.md first and carries only
what a fresh agent would otherwise get wrong: that the user is blind so no
verification may depend on seeing anything, the small-footprint rule, that
speech must never throw, the FoV rule, how to run the testbed, and how to read
the startup self-test when something is silent.

CLAUDE.md sits in the game tree, so it would show up in the footprint check
that must stay "main.lua | 1 +". Excluded there and in the three places the
docs quote that command.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 01:04:25 +02:00

53 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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' ':!CLAUDE.md'
```
## 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.