From 794b809a1b3877ea3708c7be73a4241577894f93 Mon Sep 17 00:00:00 2001 From: Eric Wagoner Date: Mon, 17 Aug 2026 15:01:07 -0400 Subject: [PATCH] Swapping homes stops announcing a body swap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SWAP HOME BASES traded homes correctly but borrowed the positionsSwapped event, so the chronicle claimed the wizards themselves changed places. It now speaks its own event — "swap home bases — the maze's loyalties shift!" — and both hearths shimmer as their allegiance changes. Co-Authored-By: Claude Fable 5 --- packages/engine/src/game.ts | 3 ++- packages/web/src/fx.ts | 5 +++++ packages/web/src/net.svelte.ts | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/engine/src/game.ts b/packages/engine/src/game.ts index 1463336..6d04b76 100644 --- a/packages/engine/src/game.ts +++ b/packages/engine/src/game.ts @@ -498,6 +498,7 @@ export type GameEvent = | { type: "spellSustained"; effectId: string; cardId: string; caster: PlayerId; target: PlayerId; turns: number } | { type: "spellExpired"; effectId: string; cardId: string; target: PlayerId } | { type: "teleported"; player: PlayerId; from: Cell; to: Cell; by: PlayerId; cardId: string } + | { type: "homeBasesSwapped"; a: PlayerId; b: PlayerId; aHome: Cell; bHome: Cell } | { type: "positionsSwapped"; a: PlayerId; b: PlayerId; aTo: Cell; bTo: Cell } | { type: "cardErased"; player: PlayerId; cardId: string | null; found: boolean } | { type: "cardsStolen"; from: PlayerId; to: PlayerId; count: number } @@ -2290,7 +2291,7 @@ const CARD_EFFECTS: Record const mine = caster.home; caster.home = other.home; other.home = mine; - events.push({ type: "positionsSwapped", a: caster.id, b: other.id, aTo: caster.home, bTo: other.home }); + events.push({ type: "homeBasesSwapped", a: caster.id, b: other.id, aHome: caster.home, bHome: other.home }); checkVictory(state, events); return null; }, diff --git a/packages/web/src/fx.ts b/packages/web/src/fx.ts index bfe2957..4521977 100644 --- a/packages/web/src/fx.ts +++ b/packages/web/src/fx.ts @@ -177,6 +177,11 @@ export function fxForEvents( } break; } + case "homeBasesSwapped": + push({ kind: "shimmer", at: e.aHome }); + push({ kind: "shimmer", at: e.bHome }, 200); + beat++; + break; case "teleported": push({ kind: "shimmer", at: e.from }); push({ kind: "shimmer", at: e.to }, 200); diff --git a/packages/web/src/net.svelte.ts b/packages/web/src/net.svelte.ts index 78d8ed4..7c185c3 100644 --- a/packages/web/src/net.svelte.ts +++ b/packages/web/src/net.svelte.ts @@ -68,6 +68,7 @@ export function humanize(e: GameEvent): string | null { ? `${e.player} teleports across the maze!` : `${e.player} is teleported away by ${e.by}!`; case "positionsSwapped": return `${e.a} and ${e.b} swap places!`; + case "homeBasesSwapped": return `${e.a} and ${e.b} swap home bases — the maze's loyalties shift!`; case "cardErased": return e.found ? `${e.player}'s ${e.cardId ? cardDef(e.cardId).name : "card"} is erased from their mind!` : `${e.player} wasn't holding that card — the erasure fizzles.`;