Tracker selection now survives a rescan. The scan is rebuilt every turn and
both lists are distance-sorted, so holding a bare index meant one step by the
player silently re-pointed the selection at a different rat. The tracker now
remembers identity instead -- the actor table for creatures, coordinates for
tiles -- and re-derives the indices in reanchor() after each rescan. Selection
is dropped only when the thing genuinely stops being reported (out of FoV,
killed, picked up), and the existing clamp then falls back to the nearest.
Ctrl+Home walks to the selection, reusing the exact shape of the game's own
click-to-path in ingame.mousepressed: calculatePathFromPlayer, then either
bufferInput or playerInput for a one-step path. Interruptions and threatened-
player truncation therefore behave the way a mouse click does. Most things
worth tracking stand on impassable tiles, which calculatePathFromPlayer refuses
outright, so we fall back to the cheapest of the 8 neighbours and say "next to"
rather than "to". Guarded on states.getCurrent() == "ingame": elsewhere the
input buffer belongs to another state and feeding it moves would be a bug.
Wall tones now follow the usual proximity convention -- a near wall is loud,
one out at radius is quiet. It was inverted, which read backwards in play since
a nearby wall is the more urgent fact. config.louderWhenFurther still flips it.
Testbed covers both: selection identity across a forced rescan, and that
Ctrl+Home moves the player without breaking out of the map.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Game-file footprint unchanged: still one line in main.lua.
Three-level navigation as specified in D2: Ctrl+PageUp/Down cycles categories,
PageUp/Down cycles kinds, Shift+PageUp/Down cycles instances of that kind, Home
announces where it is.
- categories.lua: flag-first classification into Creatures, Items, Alchemy,
Interactables, Exits and Terrain features, reusing the game's own 'exit' tag
and excluding the six nameless mechanical templates.
- tracker.lua: scan, cache, navigation, announcements.
Caching keys on level name, player position and turn: position because
everything sorts by distance to the player, turn because creatures move and
containers empty. Scans run on keypress, never per frame.
FoV is respected throughout -- creatures only when currently visible, tiles when
visible or remembered -- so the tracker never becomes a cheat.
Home reports path length alongside the offset, via the game's own
calculatePathFromPlayer. Straight-line distance is misleading indoors, where a
chest three tiles north through a wall can be twenty steps away.
Corrects D4 in docs/05-decisions.md. I had claimed tile.tryInteract cleanly
separates 'the player can do something here' from scenery. It does not: 'wall'
carries a flavour-only tryInteractFunction ('You touch the wall. It's cold and
rough.'), so every wall segment was promoted into Interactables -- 13 in the
starting house, burying the chest and cauldron. Structural tiles
(blocksMovement and blocksVision) are now excluded before the tryInteract test;
containers and furniture block movement but not sight, so they survive.
12 kinds/19 instances instead of 13/32.
13/13 testbed checks, history unit tests passing.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>