Accessibility ModandClaude Opus 5 0df3842bf1 inventory: speak the item action menu
Pressing enter/z on an inventory item plays a click and, until now, said
nothing. The click is sound.select: the menu WAS opening every time.

inventory.keypressed -> inventoryWindow.enableItemMenu() builds a second,
nested selection over the grid (modules/item/itemMenu.lua) listing the
actions that item currently allows, filtered from itemActions.lua by
per-action conditions: Activate, Wield/Unwield, Wear/Take off, Switch
on/off, Drink, Eat, Apply, Read, Open, Prepare for throwing/Pack away.
Up/down move in it, enter activates, any other key cancels. None of it
goes through console.print or the cursor popup, so it was silent -- and
since the game has no separate equipment screen, this menu is the only
way to equip anything. Reported by Talon: the torch quest was unplayable.

_itemgrid.lua now checks window.itemMenu first and keeps the grid cell
quiet underneath, since the menu is modal over it. The menu is a closure
with no getters, so lines and currentSelectedAction are read as upvalues
of its own draw(). The item name leads only when the menu opens, and the
"just opened" memory is the menu table itself rather than a flag, which
keeps read() idempotent -- a flag would be consumed by the focus poll and
the real announcement would come out headless.

Items also now read "equipped", which is part of the focus key on
purpose: after Switch on the menu closes with the cursor unmoved, so
otherwise the re-read is suppressed as unchanged and the action still
feels silent. Now: "Switch on" -> "a torch, equipped, slot 3".

New patch (the 6th) wraps the inventoryWindow factory for the dead case:
when getActionsList returns nil -- an item with no applicable actions --
the game does literally nothing, not even the click, which by ear is
indistinguishable from a dropped keypress. Says "<item>, no actions".

The prologue inventory is empty, so the live path is unverified; the
testbed instead builds an itemMenu from a synthetic item and asserts the
two upvalue names still resolve. That is the version-bump canary for this
descriptor, not proof of the wording. 38 checks, 0 failures.

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

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():

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.

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 for orientation, then 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 (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.

S
Description
Accessibility mod for alchemist
Readme
1.2 MiB
Languages
Lua 98.9%
Shell 1.1%