The setup is unusual enough to need its own page, and the facts were scattered across scratch.md, CLAUDE.md and publish.sh: the mod is developed inside a copy of a commercial game, so the dev tree deliberately has no remote and publishing means rebuilding a filtered repo and force-pushing that instead. docs/00-dev-setup.md covers the two-tree arrangement and which one you are in, prerequisites and why the game must be an extracted folder rather than a .love (ffi.load goes through the OS loader), building a dev tree from scratch including the vanilla-0.4.2 baseline tag and the one main.lua line, the everyday commands, the save location, reading the [speech] console and the startup self-test, and the publish flow with its leak check. Linked from CLAUDE.md and the docs index. No code change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
4.2 KiB
CLAUDE.md
What this repository is
A blind-accessibility mod for the commercial game Sulphur Memories: Alchemist 0.4.2 (LÖVE 11.5, Lua/LuaJIT). The work here is accessibility, not game development.
This file ships in two places, so check which one you are in:
- The development tree — an extracted copy of the game with
main.luaandstates/besideaccessibility/. Everything outsideaccessibility/is the vanilla game: treat it as read-only reference material. You read it to find out how the game works, and you patch it only where the docs sanction. - The standalone mod repository (
alchemist-accessibility) — onlyaccessibility/and the docs; no game. You cannot run or test anything here. SeeREADME.mdfor how the two relate. The sections below about running the game and checking the game-file footprint apply to the development tree only.
All mod code lives in accessibility/ either way.
If a request sounds like a game change ("make the journal readable", "the
inventory doesn't work"), it almost always means "a screen reader user cannot
use this" — the fix belongs in accessibility/, not in states/ or models/.
Read this before doing anything
accessibility/docs/scratch.md — a living handoff document. It carries the
current state of play, confirmed decisions that should not be relitigated, the
traps that have already cost real debugging time, and what is verified versus
merely written. Read it first, and update it before you finish.
accessibility/docs/00-dev-setup.md — how this tree is put together and why:
the two-tree arrangement, prerequisites, building a dev tree from scratch, the
everyday commands, and how publishing strips the game out. Read it if anything
about the setup surprises you.
Then accessibility/docs/README.md maps the rest: architecture, hooking
strategy, the phased plan, open questions, decisions.
accessibility/README.md is the user-facing manual — the key bindings the mod
adds. Update it when you add or change a key.
Working agreements
- The user is blind. Every verification must be describable in text. Never rely on a screenshot, and never ask them to check something visually. Console output and testbed transcripts are the evidence.
- Change as little game code as possible, so the mod re-applies cleanly to
new game versions. Currently the entire game-side footprint is one line in
main.lua. Check it has not grown:It must staygit diff --stat vanilla-0.4.2 -- . ':!accessibility' ':!.gitignore' ':!CLAUDE.md'main.lua | 1 +. The pristine tree is taggedvanilla-0.4.2. - Speech must never throw. A missing DLL degrades to silence; the game keeps running. Wrappers call through to the original and return its results verbatim.
- Never reveal anything outside
FoV/rememberedFoV. The mod must not become a cheat.
accessibility/docs/scratch.md has the full invariant list; these are the ones
worth knowing before you write a line.
Verify 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
The testbed drives the real game by code and navigates by reading focus rather than counting keypresses. It has caught essentially every bug in this project, so run it — a change that looks obviously correct is exactly the kind that fails.
What matters is 0 failures, not the check count, which varies between runs
because several blocks are conditional.
Use lovec.exe (not love.exe) for a console. Every utterance is mirrored there
as a [speech] line, so speech is verifiable from a log rather than only by ear:
! interrupted, * immediate, queued.
If something mysteriously does not speak
Run the game and read the startup self-test. It reports every patch and every
descriptor probe. Most menu narration reads the game's file-local variables via
debug.getupvalue, so a renamed local in a future game version shows up there as
PROBE BROKEN: no upvalue 'x' rather than as silence three screens in.
ok (unset until opened) is normal.