The great simplification: every vintage gate collapses, the count restarts at 1
All 50 rooms were retired (backed up on the droplet and in Spaces), so no ledger needs an old branch to replay: forty revisions of deckRev gates fold into one canonical ruleset — the newest behavior everywhere. The ward's arming, the idiot's steering, the lazy illusion roll, the legacy redirection swap, and the flat wave all leave with their gates; RULES_REV restarts at 1 for whenever the rules fork again. Old-vintage test pins go with them. The opening screen now quietly drops seats whose rooms the server no longer knows, instead of listing them "unreachable" forever. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
e8df6efcde
commit
8a50ff7f36
@@ -227,8 +227,6 @@
|
||||
const k = `${c.x},${c.y}`;
|
||||
if (seen.has(k)) continue;
|
||||
seen.add(k);
|
||||
// Before rev 11 the grid stopped at zero; newer games renormalize.
|
||||
if (view!.deckRev < 11 && (c.x < 0 || c.y < 0)) continue;
|
||||
if (origins.some((o) => o.x === c.x && o.y === c.y)) continue;
|
||||
const next = origins.map((o, j) => (j === idx ? c : o));
|
||||
if (next.every((o, j) => next.some((p, m) => m !== j && adjacent(o, p)))) out.push(c);
|
||||
@@ -255,7 +253,6 @@
|
||||
});
|
||||
clearSelection();
|
||||
}
|
||||
const holdingWard = $derived(view?.yourHand.some((c) => c.cardId === "ward") ?? false);
|
||||
/** A live moment to interrupt: another wizard acts, no attack is pending. */
|
||||
const canInterruptNow = $derived(
|
||||
view != null && !isYourTurn && !view.stack && !view.chaosPending &&
|
||||
@@ -400,7 +397,7 @@
|
||||
// Fully reflecting a SWAP MEET: "lets the other player decide which
|
||||
// objects, if any, will be swapped" — the choice rides the counter.
|
||||
if (youMustRespond && card.cardId === "full-reflection" &&
|
||||
view.stack?.attackCard?.cardId === "swap-meet" && view.deckRev >= 27) {
|
||||
view.stack?.attackCard?.cardId === "swap-meet") {
|
||||
reflectSwapCard = card;
|
||||
reflectSwapMine = null;
|
||||
return;
|
||||
@@ -912,11 +909,8 @@
|
||||
reflectSwapCard = null;
|
||||
reflectSwapMine = null;
|
||||
}
|
||||
// Older rooms' rules trade only object-typed cards (rev < 26): the picker
|
||||
// must offer exactly what that room's engine will honor.
|
||||
function tradableHere(cardId: string): boolean {
|
||||
if (!view) return false;
|
||||
return view.deckRev >= 26 ? isMovableObject(cardId) : cardDef(cardId).cardType === "object";
|
||||
return view != null && isMovableObject(cardId);
|
||||
}
|
||||
/** What one side can put on a trade table: hand (yours) or displayed
|
||||
* cards (theirs), plus a carried treasure. Their treasure is claimable
|
||||
@@ -1753,9 +1747,6 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if view.yourWardArmed}
|
||||
<div class="slip ambush-note">🗡 Your ward is set — a thief who grabs your treasure bleeds for 3.</div>
|
||||
{/if}
|
||||
{#if youMustShield}
|
||||
<div class="slip urgent">
|
||||
Chaos comes for your hand — tap your Full Shield to sit out, or
|
||||
@@ -1808,20 +1799,12 @@
|
||||
{/if}
|
||||
{#if isYourTurn && view.sustained.some((e) => e.cardId === "idiot" && e.targetId === view.you)}
|
||||
<div class="slip urgent">
|
||||
{#if view.deckRev >= 37}
|
||||
🥴 "What am I doing here…?" — IDIOT drives you to the nearest
|
||||
of your own treasures. Spend your movement marching toward it;
|
||||
you may cast only counteractions, spells that speed the trip,
|
||||
and Drop Object to shake your own treasure from a thief's
|
||||
arms. It lifts when you stand on your treasure. (The marching
|
||||
is yours to honor.)
|
||||
{:else}
|
||||
🥴 "What am I doing here…?" — IDIOT drives you to the nearest
|
||||
of your own treasures. Spend your movement marching (the maze
|
||||
will steer your steps); you may cast only counteractions and
|
||||
spells that speed the trip. It lifts when you stand on your
|
||||
treasure.
|
||||
{/if}
|
||||
🥴 "What am I doing here…?" — IDIOT drives you to the nearest
|
||||
of your own treasures. Spend your movement marching toward it;
|
||||
you may cast only counteractions, spells that speed the trip,
|
||||
and Drop Object to shake your own treasure from a thief's
|
||||
arms. It lifts when you stand on your treasure. (The marching
|
||||
is yours to honor.)
|
||||
</div>
|
||||
{/if}
|
||||
{#if actionsSpent}
|
||||
@@ -2136,10 +2119,6 @@
|
||||
onclick={() => dispatch({ type: "pickUpObject", instanceId: obj.instanceId })}>
|
||||
Pick up {cardDef(obj.cardId).name}</button>
|
||||
{/each}
|
||||
{#if holdingWard && view.deckRev < 31}
|
||||
<button class="stamp" onclick={() => dispatch({ type: "armWard", armed: !view.yourWardArmed })}>
|
||||
{view.yourWardArmed ? "Stand down the ward" : "Set the ward"}</button>
|
||||
{/if}
|
||||
<button class="stamp" class:primary={punchWallMode} disabled={view.turn.attackUsed && !punchWallMode}
|
||||
onclick={() => (punchWallMode = !punchWallMode)}>
|
||||
{punchWallMode ? "Click the wall to punch — or cancel" : "Punch a wall…"}</button>
|
||||
|
||||
Reference in New Issue
Block a user