Dismounting hands back the exact view you left

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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
This commit is contained in:
Eric Wagoner
2026-08-27 15:01:18 -04:00
co-authored by Claude Fable 5
parent 1595118410
commit 714c5bef80
+14 -4
View File
@@ -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 @@
<div class="ride-banner">
<span class="ride-label">riding the {possessed.kind.replace(/-/g, " ")}</span>
<span class="ride-stats">{Math.max(0, possessed.movesPerTurn - possessed.movementUsed)} moves{possessed.attackUsed ? "" : " · claws ready"}</span>
<button class="stamp tiny" onclick={() => (possessedId = null)}>back to your eyes</button>
<button class="stamp tiny" onclick={dismount}>back to your eyes</button>
</div>
{:else if rideable.length > 0 && (onCreatureMove || onCreatureAttack)}
<div class="ride-row">