Changelog
Exit coordinate cache sentinel, travel_to_exit excludes its own exit, WAIF blockers surfaced
2026-07-10 08:06 UTC · claude (#13505)
$exitwaif #1641::coordinates lazily derives an exit's position from its direction and caches it in .coords. The "unset" sentinel was `!= {0.0, 0.0, 0.0}`, which is wrong twice: {0,0,0} is the room CENTRE (a legal exit position, so a centred exit recomputed on every call), and an emptied `.coords = {}` was served back forever as a real position instead of recomputing. The sentinel is now "is this a 3-element list?". NOTE for anyone resetting exits by hand: `x.coords = {}` now forces recompute; `{0,0,0}` is honoured as a genuine centre position. This is the $spatial_room "room cache" -- it lives on the exit waif, not on #2903 or #2200.
find_path treats exits as obstacles, so pathing onto an exit's own coordinates reports that exit as the blocker: an exit stood in its own doorway. travel_to_exit now passes the target exit as find_path's `exclude`. It also takes `dir` explicitly -- it previously read `dir` as a free variable, so check_for_next_room(exit, dir) raised E_VARNF the instant a real walk succeeded -- and takes an optional `who`, so it is testable without moving a live player.
travel_to_exit now returns 0 (no walk needed), the walk's eta, or {E_INVARG, blocker}; the `north` command verb owns the telling and the suspend rather than travel_to_exit calling player:tell and kill_task from inside a helper. travel_to's blocker branch previously only fired for `typeof(path) == OBJ`, so WAIF blockers (exits) degraded to a bare E_INVARG and the caller could not name what stopped you; it now accepts OBJ and WAIF.
Root cause of the reported "travel takes no time": #1174 @dig/@edit-exits does `exit.coords = player.coords`, stamping the digger's standing position onto the exit. Two doors dug from the same spot shared one coordinate, so standing on either was standing on both, distance 0.0, and the `dist > 1.5` gate skipped the walk entirely. Exits reset to their canonical edge coordinates.
Tests, each watched failing first: #2903:test_exit_coordinates_cache_sentinel, #2903:test_travel_to_exit_excludes_target_exit, #2903:test_find_path_excludes_target_exit, #2200:test_travel_to_returns_waif_blocker. Suites green: #2903 34/34, #2200 10/10, #6 7/7, #9501 13/13, #410 1/1. Live-proven: from 7.5m, `west` walks, takes the travel time, and traverses the exit.