The opening a game plays was the one piece of content that had to be
assembled in the wiring, because OnStart wanted an Action. It takes the
name of a registered Script now, so an opening is a Script like any
other, and Validate rejects a name that is not there.
OnFinale names the closing script and queues it straight after the start
one — what a "boot into the ending" debug flag wants.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
AudioPlayer keeps the *AssetManager it is handed, so attaching it during
construction quietly pinned it to the manager NewGame happened to make. A
domain that assigns its own registry onto the Game — legal, the fields are
plain *Manager values — got a working image path and a silent audio one.
Run attaches instead, once the Game is final.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Set is the deliberate overwrite: it replaces a registered entry in place,
keeping its position in the insertion order, and falls back to Register
when the name is new. Register keeps panicking on duplicates.
All returns every entry in insertion order; orderedWidgets is now just
that call, and reversedWidgets builds on it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A connection between two scenes had to be hand-built as a hotspot: an area,
a cursor, a GoTo, and a flag check written out again for every door. Scene
now carries Exits, and the engine expands each one into a hotspot.
- Exit{To, Label, Side, Area, Needs, Blocked, OnLook, OnTake} in scene.exit.go.
With no Area an exit is an edge strip, sized as a fraction of Game.SceneArea()
so a game whose HUD covers the foot of the window gets strips inside the
painting. Game.ExitLook / Game.ExitTake supply the look and take responses
once for the whole game, so the phrasing is not repeated per exit.
- Game.SceneHotspots(name) is the scene's own hotspots followed by its exits,
cached per scene. Authored hotspots come first, so a painted thing beats the
edge strip wherever the two overlap. HotspotAt and HotspotDebug read it.
- Game.CurrentScene() / PreviousScene(), both persisted in the save file. The
engine tracked the current scene but exposed no accessor, so every game had
to shadow it to know where it was.
- Back() returns to the previous scene — what an exit with an empty To binds
to, for a scene reachable from several rooms whose way out is a direction
rather than a place.
- Validate rejects an exit naming a scene nobody registered.
Generated hotspots are named ExitName(To) ("exit:street", "exit:back"), so the
location graph can be read straight back out of the registered scenes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The repo was registered in Woodpecker but had no pipeline, so nothing
ever ran on it. There is no test suite here, so the check is what can
actually catch a regression in a library: that it still compiles and
loads.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The repo now lives at engines/inkwell, and a Go module path is not
covered by Gitea's redirect: `go get git.teletypegames.org/engines/inkwell`
failed with "module declares its path as git.teletypegames.org/games/inkwell".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>