From 714c5bef8017ef182535e613167ac9ca256fe899 Mon Sep 17 00:00:00 2001 From: Eric Wagoner Date: Thu, 27 Aug 2026 15:01:18 -0400 Subject: [PATCH] Dismounting hands back the exact view you left MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stepping out of a creature's skull treated the return as a fresh cut, and fresh cuts face the deepest corridor — spinning the rider 90 degrees from where they had been looking. The saddle now remembers: your position and facing are saved at mount and restored verbatim on every dismount path (the button, the turn passing, the mount dying), with no cut and no re-aim. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF --- packages/web/src/LiveFirstPerson.svelte | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/web/src/LiveFirstPerson.svelte b/packages/web/src/LiveFirstPerson.svelte index 326d939..8c7336a 100644 --- a/packages/web/src/LiveFirstPerson.svelte +++ b/packages/web/src/LiveFirstPerson.svelte @@ -79,9 +79,19 @@ !c.justCreated && (c.movementUsed < c.movesPerTurn || !c.attackUsed)) : []); + /** The rider's own stance, held while riding: dismounting must hand + * back the exact view you left — same feet, same facing, no cut. */ + let preMount: { x: number; y: number; facing: number } | null = null; + function dismount() { + possessedId = null; + if (preMount) { + cam.x = preMount.x; cam.y = preMount.y; cam.facing = preMount.facing; + preMount = null; + } + } // A dead or vanished mount — or the turn passing — dismounts you. $effect(() => { - if (possessedId && (!possessed || !canStride)) possessedId = null; + if (possessedId && (!possessed || !canStride)) dismount(); }); // Mounting seats the eyes in the creature's skull facing its longest // corridor; the rider steers from there. @@ -90,6 +100,7 @@ if (!possessedId || !possessed) { seatedMount = null; return; } if (seatedMount === possessedId) return; seatedMount = possessedId; + preMount = untrack(() => ({ x: cam.x, y: cam.y, facing: cam.facing })); const mx = possessed.position.x + 0.5, my = possessed.position.y + 0.5; let deepest = -1, face = 0; for (const a of [0, Math.PI / 2, Math.PI, -Math.PI / 2]) { @@ -229,8 +240,7 @@ if (Math.hypot(untrack(() => cam.x) - mx, untrack(() => cam.y) - my) > 0.01) { cam.x = mx; cam.y = my; } - camReady = false; // the wizard's eyes reseat on dismount - return; + return; // dismount() restores the rider's own stance, uncut } const v = view; const tx = m.position.x + 0.5; @@ -384,7 +394,7 @@
riding the {possessed.kind.replace(/-/g, " ")} {Math.max(0, possessed.movesPerTurn - possessed.movementUsed)} moves{possessed.attackUsed ? "" : " · claws ready"} - +
{:else if rideable.length > 0 && (onCreatureMove || onCreatureAttack)}