From 86c71fc001ef4c9e1cc819ea42ab7d5d06039057 Mon Sep 17 00:00:00 2001 From: Accessibility Mod Date: Sun, 2 Aug 2026 01:21:16 +0200 Subject: [PATCH] publish: reproducible standalone mod repo via git-filter-repo The mod is 63 files; the tree it lives in is 1838 files of a commercial game and 296 MB of history. Publishing therefore means stripping, and stripping by hand is exactly the sort of thing that quietly leaks a build of the game. accessibility/publish/publish.sh rebuilds the standalone repository from this tree with git-filter-repo, then asserts that no path outside accessibility/ and the docs survived, and aborts rather than pushing if one did. The publish-only files live in accessibility/publish/ rather than at the root so that the game-file footprint check stays a clean "main.lua | 1 +", and the filter renames them to the root where a visitor to the mod repo expects them. The script then drops the publish machinery itself, which means nothing to someone installing the mod. README.md is the install guide: copy accessibility/ into an extracted game folder and add the one line to main.lua, which install.patch also applies. CLAUDE.md now states which of the two repos the reader is in, since half of it (running the game, the footprint check) is meaningless without the game present. Co-Authored-By: Claude Opus 5 --- CLAUDE.md | 21 +++++-- README.md | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++ install.patch | 12 ++++ 3 files changed, 186 insertions(+), 6 deletions(-) create mode 100644 README.md create mode 100644 install.patch 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",