From a94ab5c6f5ad705648e9ae13bf399ac53154f838 Mon Sep 17 00:00:00 2001 From: Eric Wagoner Date: Sun, 23 Aug 2026 19:19:33 -0400 Subject: [PATCH] A cut is not a stride MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The wraith reel still ended in a wall, and the ledger showed why: its final step CUTS home from the cutaway at the summon site — a nine-cell leap — and the camera read that leap as a walk, faced along it into the masonry, and counted itself aimed, which silenced the closing-shot rescue. Leaps no longer set facing: any step that will cut computes willCut first, strides only turn the eyes within a stride's reach, and a cut that lands with nothing aimed always re-picks its view from the new position. The wraith turn now closes down a corridor with the wraith itself in frame. Co-Authored-By: Claude Fable 5 --- packages/web/src/Replay.svelte | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/web/src/Replay.svelte b/packages/web/src/Replay.svelte index e973830..88a4f51 100644 --- a/packages/web/src/Replay.svelte +++ b/packages/web/src/Replay.svelte @@ -253,12 +253,13 @@ } return null; })(); + // A leap the legs cannot explain (first frame, teleport, the return + // from a cutaway) is a CUT, and a cut is not a stride: the direction + // of travel means nothing at the far end. + const willCut = !camReady || (dist > 1.6 && !hurled); let targetFacing = camF; let aimed = false; - // A stride turns the eyes along it — but only a REAL stride: on the - // reel's first run the camera sits at its uninitialized origin, and - // that phantom distance must not pick the opening shot's direction. - if (camReady && dist > 0.05 && !hurled) { targetFacing = Math.atan2(dy, dx); aimed = true; } + if (camReady && !willCut && dist > 0.05 && !hurled) { targetFacing = Math.atan2(dy, dx); aimed = true; } else if (aim) { const ax = aim.x + 0.5, ay = aim.y + 0.5; const toAim = Math.hypot(ax - tx, ay - ty); @@ -316,7 +317,10 @@ for (const t of v.treasures) if (t.position && !t.carriedBy) score += bonus(t.position, 3); return score; }; - const staring = castRay(v, tx, ty, targetFacing).dist < (atEnd ? 1.2 : 0.8); + // A cut lands with whatever stale facing it carried, so a cut with + // nothing aimed always re-picks its view from the new position. + const staring = willCut || + castRay(v, tx, ty, targetFacing).dist < (atEnd ? 1.2 : 0.8); if (staring) { const current = viewScore(targetFacing); let bestA = targetFacing, bestScore = current; @@ -329,7 +333,7 @@ targetFacing = bestA; } } - if (!camReady || (dist > 1.6 && !hurled)) { + if (willCut) { // First frame, or a leap the legs cannot explain: cut. cam.x = tx; cam.y = ty; cam.facing = targetFacing; camReady = true;