Commit Graph
10 Commits
Author SHA1 Message Date
Eric WagonerandClaude Fable 5 2bb2ca62d8 Reflected Swap Meet: the reflector chooses the trade (rev 27)
'FULL REFLECTION lets the other player decide which objects, if any,
will be swapped' — the reflector's choice now rides their counteract
(params.cardId, reflector's item first), resolved with the roles
swapped when the reflection settles; 'none' or no choice trades
nothing. The client walks the reflector through the same give-and-take
picker, with a 'swap nothing' refusal.

Also from room XRT7: the trade picker now honors each room's own rules
revision (older rooms trade only object-typed cards), so it can no
longer offer a wizardblade a rev-25 engine will quietly refuse — and a
fizzled swap finally says so in the log instead of vanishing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0138A8CjeQRpvzKxuMfz1Bqc
2026-08-17 22:36:00 -04:00
Eric WagonerandClaude Fable 5 3aef6694f3 Swap Meet trades treasures — a carried treasure is a carried item
The trade grammar gains a 'treasure' token (never present in stored
ledgers, so no gate needed): a dagger can buy back the treasure in a
thief's arms, or two armfuls of gold can change hands outright. The
one-treasure carry limit and WEAKNESS both hold in a trade as at a
grab — a one-way treasure needs an open slot and an able back. The
picker offers each side's carried treasure alongside displayed items,
withholding theirs when your own arms are already full.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0138A8CjeQRpvzKxuMfz1Bqc
2026-08-17 22:19:29 -04:00
Eric WagonerandClaude Fable 5 00517e08b1 Pacts are honored; Swap Meet trades items, not card names (rev 26)
The pact fix: a clockwork no longer attacks a wizard it holds a BUDDY
pact on — Eric watched one sign the pact and punch him the next turn.
A pact is torn up for exactly one thing: a kill. And the post-attack
pact is signed only by a wizard who wants OUT of the fight (hauling
gold, bleeding, or with other enemies left) — a healthy duelist keeps
its options, and mutual-pact stalemates stay out of bot wars.

Swap Meet drops the 'name a card' prompt for a real trade picker:
click the other trader, choose one of your carried items, then claim
one of their displayed items. Rules rev 26 widens the engine's match
from object-typed cards to every movable object (daggers, rocks,
wands, stones); older games matched narrowly and replay so.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0138A8CjeQRpvzKxuMfz1Bqc
2026-08-17 22:14:57 -04:00
Eric WagonerandClaude Fable 5 cdeb3d5103 Idiot enforces its card (rev 23) + attack sight-line tracing
Rules rev 23 — IDIOT, per the card and FAQ:
- No handling items: pick up / drop of treasures and objects refused
  (dropping was the exploit: capturing a stolen treasure on your own home,
  or dropping your own treasure underfoot for an instant cure)
- No punching, no thrown dagger / large rock (attacks on players)
- No effect on a victim already carrying one of their own treasures
Ungated (permissive): counteractions are now castable while idiotized (the
one thing the card expressly allows — the gate wrongly blocked them), and
goal-aiding spells (IDIOT_AIDS: destroy-wall, teleport, mad-dash, ...) per
the FAQ's 'you could, however, destroy a wall'.

Sight tracing: while an LOS attack sits on the stack, the board draws the
line it traveled — straight when direct, leg by leg through both warp
mouths (with pulsing rings) when the maze's wraparound carried it. Engine
traceSight/traceSightFor/stackSightTrace; overlay in Board.svelte; shown
live and in replays. Verified against H3PC's cross-board Idiot cast.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0138A8CjeQRpvzKxuMfz1Bqc
2026-08-17 19:03:09 -04:00
Eric WagonerandClaude Fable 5 695307daa8 Credibility pass: one voice, no scars
A three-reviewer sweep for tells of piecemeal machine generation,
every finding verified against the code before touching it. No
behavior changes; the full suite passes unchanged (plus two
strengthened pins).

Engine: removed four void-silenced fossils (a parseEdgeKey call
voided where it stood, stoneEffect's ignored cardId parameter, the
actualTarget remnant in doCast, a voided loop variable in shadow
upkeep); fixed the initialize-then-overwrite narration in
spawnCreature; replaced a filter(() => false) no-op; waterwall now
rides waveFromEdge instead of carrying its own verbatim copy (and the
single-caller washBack wrapper went with it); blind wall-bumps and
LOS blockers each collapsed to one implementation; the wand-id list
and the "permanent" duration sentinel became named constants; the
ambush number local no longer shadows the imported numberValue
function; assorted reviewer-aimed phrasings rewritten as the
constraints they guard.

Server/deploy: the protocol header now documents all eleven message
types; dropped an eslint pragma with no eslint, a test script with no
tests, and an rsync exclude anchored at a path that never existed
(the real data/ dir now excluded); the Caddy vhost has one source of
truth; stale "pending DNS" note removed — the record resolves.

Web: ~90 lines of CSS swallowed verbatim into a mobile media query
deduplicated; the reduced-motion guard on the board now actually
stops the marked-cell pulse; one shared color module replaces two
drifted palettes; an orphaned doc comment rejoined its function.

Tests: the ten-times-pasted helper block became test/helpers.ts;
wave-numbered files renamed for the behaviors they pin; deliberation
comments and void-ed corpses of unwritten assertions deleted; silent
seed-dependent early-returns now fail loudly; one assertion that
compared a value to itself now pins the home-translation it meant to;
the stored-log single-number command form gained the explicit
compatibility test it deserved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-16 11:56:55 -04:00
Eric WagonerandClaude Fable 5 45666bca16 Ambushes: the async-native form of Interrupt and Opportunity Fire
Eric's diagnosis: "in the moment" interruption cards are worthless in
correspondence play — there is no moment. The answer was already in
the game: WARD is a contingency card, and ambushes generalize it. On
your turn, playing Interrupt or Opportunity Fire now arms an ambush:
commit it with an attack from your hand (plus an optional number
card) and a trigger — an opponent entering your line of sight, coming
beside you, or grabbing a treasure — and it springs automatically
when the condition occurs, whether you are watching or asleep. The
sprung attack opens the normal counteraction stack, so the victim
gets their defense (asynchronously, like any attack). Committed cards
leave your hand until the trap springs or you disarm it; ambushes are
invisible to everyone but their owner (view-level redaction), die
with their owner, stay armed if the shot is momentarily illegal, and
honor the no-combat first round. Live play in the moment still works
too — and the client now actually offers it (the old UI never let
you click those cards out of turn). The rail shows your armed traps
with a disarm control; the chronicle announces AMBUSH! when one
springs. 124 tests passing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-16 01:36:53 -04:00
Eric WagonerandClaude Fable 5 89961bbb59 ADD joins two number cards on movement, as printed
"You may add two NUMBER cards together for any single action" —
movement included. The engine accepts a second movement number when an
ADD accompanies it (once per turn); the client spends your Add
automatically and says so on the button. 120 tests passing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 23:41:37 -04:00
Eric WagonerandClaude Fable 5 c9524a37db Thumb Of God lands: the 6th edition is 100% implemented
Eric chose the "divine meteor" redesign for the one card that cannot
be digitized faithfully (the physical version has you flick the die at
the board from six inches). Digital form: aim at a square in sight;
the die drifts 0-2 squares in a random direction, then every token in
and around the landing square — ground objects, treasures, creatures,
and wizards alike — is flung to a random nearby square. Walls mean
nothing to falling cardboard; tokens knocked off the board settle at
the nearest edge, per the original card; there is no counteraction.

With this, all 128 unique cards of the 6th edition game (69 basic +
59 Expansion Set #1) are implemented, tested, and playable online.
The "unimplemented card" guard test now points at an Expansion #2
shelf card, which is the only kind left. 119 tests passing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 23:05:47 -04:00
Eric WagonerandClaude Fable 5 21dcd532a3 Add Swap Home Bases — the audit's one escapee
Neutral, LOS to the other player, legal only when both home bases hold
an equal number of treasures. With this, every card in the 6th edition
game is implemented except Thumb Of God, which awaits its digital
redesign. 118 tests passing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 23:02:43 -04:00
Eric WagonerandClaude Fable 5 06eea72ded Expansion wave 4: 27 combat, curse, and utility cards
Fortune: GIFT FROM ABOVE (+3, no ceiling), GIFT FROM BELOW (a trap in
the deck — 3 damage on the draw, harmless in the opening deal).
Modifiers: POWER ATTACK burns life into any damage spell. Curses:
WEAKNESS (drop your treasure, take double, carry nothing), STRENGTH
(double physical dealt; the two cancel), WALKING DEAD (half a point
per space walked, forever), DISEASE (the victim becomes a carrier who
infects everyone in squares they enter), IDIOT (the victim shambles
toward their nearest own treasure, able only to counteract, until
they stand on it and ask "What am I doing here?"). Defense: EMPATHY
(attacks bite their caster too), FORCE FIELD (spell-stopping
counteraction). Mischief: MENTAL SWAP (trade whole hands), MENTAL
FORCE (march someone three spaces), BUTT-HEAD (become a goat, ram for
the distance charged), HEAVE-HO (throw your carried treasure as a
weapon), THIEF and SWAP-MEET (item larceny), CHAOS (all hands in a
pile, shuffled, redealt), ILLUSIONARY ATTACK (a fake spell that hurts
if believed), WARD (a trapped treasure bites its thief), REMOVE CURSE
(strip any duration spell, rolling to hit the shrunken or invisible),
SWARTHMORE'S ENCHANTMENT (+1 on an enchanted object). Space-time:
DIMENSIONAL WARP (paired step-through tokens), REDIRECTION (swap two
outer exits' wraparounds), BIG MAN (fills the corridor: no entry, no
punches, no casting past him), FEAR (nobody approaches within 3),
and the out-of-turn pair — INTERRUPT and OPPORTUNITY FIRE — which
open a one-action window in another player's turn. Only THUMB OF GOD
remains, awaiting its digital redesign. 117 tests passing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 23:01:42 -04:00