diff --git a/CLAUDE.md b/CLAUDE.md index 8a93fbf..1610f97 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,13 +2,22 @@ ## What this repository is -This is an extracted copy of the commercial game *Sulphur Memories: Alchemist* -0.4.2 (LÖVE 11.5, Lua/LuaJIT) — **and the work here is a blind-accessibility mod -for it, not game development.** +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.** -Everything outside `accessibility/` 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 in the rare case the docs sanction. All mod code lives in `accessibility/`. +This file ships in two places, so check which one you are in: + +- **The development tree** — an extracted copy of the game with `main.lua` and + `states/` beside `accessibility/`. Everything outside `accessibility/` 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`) — only + `accessibility/` and the docs; no game. You cannot run or test anything here. + See `README.md` for 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 diff --git a/README.md b/README.md new file mode 100644 index 0000000..12ec0dc --- /dev/null +++ b/README.md @@ -0,0 +1,159 @@ +# Alchemist Accessibility + +A blind-accessibility mod for **Sulphur Memories: Alchemist** 0.4.2 — screen +reader speech, an object tracker, tile-by-tile exploration and directional wall +tones. + +Speech goes through **Tolk**, so it uses whichever screen reader you already have +running (NVDA, JAWS, System Access) and falls back to SAPI 5 if none is. + +> This repository contains **only the mod**. It does not contain the game, and +> you need your own copy. Developed against version **0.4.2**. + +--- + +## Installing + +You need the game as an *extracted source folder* — a directory with `main.lua` +and `conf.lua` in it — rather than a packed `.love` or the Steam build. The mod +loads its TTS libraries by absolute path, which cannot work from inside a +`.love` archive. + +**1. Copy the `accessibility/` folder** from this repository into the game +folder, next to `main.lua`: + +``` +Sulphur Memories Alchemist 0.4.2/ + main.lua + conf.lua + states/ + models/ + accessibility/ <- this repository's accessibility/ folder +``` + +**2. Add one line to `main.lua`.** Find `love.load()` (around line 95) and add +the marked line immediately after `console.prepare()`: + +```lua +function love.load() + ... + user.initialize() + states.setup() + console.prepare() + require("accessibility").initialize() --ACCESSIBILITY MOD: sole entry point + local messages = require("models.messages") +``` + +That is the *entire* game-side change — one line. Everything else the mod does +is applied at runtime from inside `accessibility/`, which is what lets it be +lifted onto a new game version cheaply. + +The placement matters: by that point templates are preprocessed, keybindings are +loaded, `states.setup()` has run and the console canvas exists, and it is still +before the first `states.switch()`. + +If you prefer, `install.patch` in this repository applies the same change: + +``` +git apply install.patch # from inside the game folder +``` + +**3. Run the game.** + +``` +"C:\Program Files\LOVE\love.exe" "C:\path\to\Sulphur Memories Alchemist 0.4.2" +``` + +You should hear "Main menu" once it loads. + +--- + +## Checking it works + +Run with **`lovec.exe`** instead of `love.exe` to get a console window. Every +spoken line is mirrored there, and at startup the mod prints a self-test: + +``` +[accessibility] TTS initialised +[accessibility] TTS: available +[accessibility] speech channel: yes +[speech]! Main menu +``` + +- `TTS: UNAVAILABLE` — the DLLs in `accessibility/lib/` were not loadable. +- `speech channel: NO` — Tolk loaded but found no screen reader and no SAPI, so + nothing will be audible. + +The self-test also reports every patch and every menu probe. If a future game +version renames something the mod reads, it shows up here at startup as +`PROBE BROKEN: no upvalue 'x'` rather than as silence three screens into a +playthrough. + +--- + +## What it adds + +Full key list and explanation: **[`accessibility/README.md`](accessibility/README.md)**. + +In brief: + +| | | +|---|---| +| **Message log** | `[` / `]` walk back and forth, `\` repeats, `Shift+\` copies. New messages are spoken automatically. | +| **Looking around** | `/` scans all eight neighbours, `;` says where you are, `Ctrl`+numpad probes one direction without moving. The game's own examine mode (`x`) is fully spoken. | +| **Object tracker** | `PageUp`/`PageDown` with `Ctrl`/`Shift` to move through categories, kinds and instances; `Home` for distance and path length; `Ctrl+Home` to walk there. | +| **Your character** | `'` for health and effects, `,` for the selected action. Damage and healing are announced unprompted. | +| **Wall tones** | Each step, a tone sounds from the direction of any wall within five tiles, positioned in 3D. | +| **Menus** | All 23 screens are spoken, including the journal's page text, inventory, crafting, dialogue and the options screens. | + +The tracker never reports anything outside the game's own field of view or your +remembered map — it is an accessibility aid, not a cheat. + +--- + +## Reporting problems + +Run with `lovec.exe` and include the console output. `[speech]` lines show +exactly what was said and when — `!` interrupted, `*` urgent, ` ` queued. + +The most useful report is **something that was silent when it should not have +been**, together with the screen you were on and the key you pressed. + +--- + +## For developers + +Start with [`CLAUDE.md`](CLAUDE.md) for orientation, then +[`accessibility/docs/`](accessibility/docs/) — `docs/README.md` maps it, and +`docs/scratch.md` is the living handoff document with the current state of play +and the traps already discovered. + +There is a code-driven test harness that plays the game by itself and checks +what gets spoken: + +``` +"C:\Program Files\LOVE\lovec.exe" . --a11y-test +``` + +Design goal throughout: **change as little game code as possible**, so the mod +re-applies cleanly to a new game version. + +--- + +## Credits and licensing + +The mod is built on [love2talk](https://github.com/rustyoldrake/love2talk) +(vendored in `accessibility/vendor/love2talk/`, see `VENDORED.md` there for the +local modifications and the licence). + +`accessibility/lib/` contains: + +- **Tolk** — screen reader abstraction, LGPL 3.0 +- **nvdaControllerClient64.dll** — NVDA controller client +- **SAAPI64.dll** — System Access API + +These ship with the mod because Tolk loads them through the OS loader, so they +must sit on disk beside the game rather than inside an archive. + +*Sulphur Memories: Alchemist* is the property of its developers and is not +included or redistributed here. diff --git a/install.patch b/install.patch new file mode 100644 index 0000000..681c26a --- /dev/null +++ b/install.patch @@ -0,0 +1,12 @@ +diff --git a/main.lua b/main.lua +index 35d3b50..5a83f76 100644 +--- a/main.lua ++++ b/main.lua +@@ -95,6 +95,7 @@ function love.load() + user.initialize() + states.setup() + console.prepare() ++ require("accessibility").initialize() --ACCESSIBILITY MOD: sole entry point + local messages = require("models.messages") + if keybindingsConflicts then + states.switch("menu_message",