From b3bc4d079b3e365ded7fbbd2f6cdc8da377fb000 Mon Sep 17 00:00:00 2001 From: Eric Wagoner Date: Sun, 23 Aug 2026 17:04:38 -0400 Subject: [PATCH] Stepping through a believed illusion reads as magic, not a glitch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A9WK's mystery, solved by Eric: the wizard walked through an illusion wall it disbelieves, and the viewer — still deceived — watched the camera slide through solid stone. The deception stays intact, but the crossing now performs: any body stepping through an edge the VIEWER holds as wall (which can only be an illusion the mover saw through) shimmers on both faces, with the stone-gray wash when the eyes themselves cross. Same dressing Pass Wall wears. Co-Authored-By: Claude Fable 5 --- packages/web/src/fpv/fx3d.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/web/src/fpv/fx3d.ts b/packages/web/src/fpv/fx3d.ts index c536226..4786b77 100644 --- a/packages/web/src/fpv/fx3d.ts +++ b/packages/web/src/fpv/fx3d.ts @@ -114,9 +114,21 @@ export function fpFxForEvents( if ((e.type === "moved" || e.type === "creatureMoved") && "direction" in e) { const via = e.type === "moved" ? e.via : "step"; const key = edgeKey(e.from, e.direction); - if (via === "step" && view.board.edges[key] === "door") { + const edgeState = view.board.edges[key] ?? "open"; + if (via === "step" && edgeState === "door") { out.push({ fx: { id: nextId++, kind: "door", edge: key, t0: 0, dur: 1100 }, delay: 0 }); } + if (via === "step" && edgeState === "wall") { + // A body just stepped through what THIS viewer holds solid — an + // illusion the mover disbelieves. The viewer keeps their false + // belief, but the crossing must read as magic, not a glitch: + // shimmer both faces, and wash the screen if these are the eyes. + out.push({ fx: { id: nextId++, kind: "impact", art: "shimmer", at: { x: e.from.x + 0.5, y: e.from.y + 0.5 }, t0: 0, dur: 500 }, delay: 0 }); + out.push({ fx: { id: nextId++, kind: "impact", art: "shimmer", at: { x: e.to.x + 0.5, y: e.to.y + 0.5 }, t0: 0, dur: 500 }, delay: 200 }); + if (e.type === "moved" && e.player === povId) { + out.push({ fx: { id: nextId++, kind: "flash", color: "#9a8fb0", peak: 0.35, t0: 0, dur: 450 }, delay: 0 }); + } + } if (e.type === "moved" && e.via === "passWall") { out.push({ fx: { id: nextId++, kind: "impact", art: "shimmer", at: { x: e.from.x + 0.5, y: e.from.y + 0.5 }, t0: 0, dur: 500 }, delay: 0 }); out.push({ fx: { id: nextId++, kind: "impact", art: "shimmer", at: { x: e.to.x + 0.5, y: e.to.y + 0.5 }, t0: 0, dur: 500 }, delay: 200 });