Changelog
Movement audit: $journey::position used math angles against find_path's yaw; travel_to supersede; face <object>
2026-07-10 07:38 UTC · claude (#13505)
$journey::position (#10576) advanced x+=cos(a), y+=sin(a) -- the math-angle convention -- while find_path emits YAW (south=0, east=pi/2, north=pi, west=3pi/2), the same frame as $vector_utils:apply_2d_vector and #6:orientation. Walking north therefore interpolated the mover due WEST for the whole walk; arrive() snapped .coords to the destination at the end, so endpoints were always right and every mid-walk coordinates() read (GMCP position, 3D audio, footsteps) was 90 degrees wrong. position() now delegates to $vector_utils:apply_2d_vector, the one canonical yaw->delta verb.
The suite never caught this because every journey fixture hand-wrote its path and labelled angle 0.0 "east". New guard #2200:test_position_honors_find_path_angles derives its path from a real find_path call; do not replace it with a literal path. Retuned test_interpolated_coordinates, test_interpolated_coords_multiseg, test_stop_travel, #410:test_sit_stops_journey to yaw.
travel_to cleared this.journey before reading this:coordinates(); coordinates() only interpolates while the journey is a live waif, so re-walking mid-stride started from the previous journey's stale .coords anchor and rubber-banded the mover backwards. It now supersedes through the single stop_travel() path (settle -> cancel). cancel_travel cleared pending_interaction unconditionally, which would have wiped the walker's own resume token (the direction verb sets it to task_id() before calling travel_to); it now clears only the waiter it actually killed.
#6:face raises E_INVARG instead of returning it. New #6:face_object(target) computes the bearing via $vector_utils:get_2d_vector; the face command now accepts a compass word, degrees, or an object name. #6:test_orientation_basics was already red, asserting the Web-Audio frame (up=+Y) against #6:orientation's correct MOO frame (up=+Z); fixed the test. $room #2700:enterfunc forked a task calling is_player() on possibly-recycled objects with no validity guard; guarded.
No $spatial_room room cache exists: zero properties matching cach* on #2903/#2200 or any ancestor, zero verbs db-wide containing cached_paths. The 2026-03-29 Spatial System Audit note's item 7 is stale.