Every room is now an append-only JSONL file (data/rooms/CODE.jsonl):
a birth-certificate meta line, then every join, start, and command.
Because the engine is deterministic, seed + log IS the game — on boot
the server replays each file and reconstructs the exact state, hands,
deck order, and chronicle. Verified live: create, join, play, KILL
the server, restart ("restored 1 room(s) from disk"), rejoin with the
seat token — identical positions, deck count, and hand, with the
chronicle history redelivered redacted per player. The client
remembers its seat (name, room, token) in localStorage and walks back
to the table automatically on connect, clearing the memory if the
seat is stale; a quiet "leave table" control forgets it on purpose.
This is the foundation phase 2 (play-by-turn) sits on: games now wait
indefinitely for their players — and debugging restarts cost nothing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
"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>
The rulebook allows discarding cards purely to churn for new ones, but
the client had no way to start it: a "Discard cards..." action now
switches the hand into marking mode (with a "never mind" exit), and
confirming sends the discard. Alongside it, the hair-trigger casts are
gone: selecting a card never plays it anymore — untargeted spells and
stone displays get a Cast button in the hint bar, and a bare number
card gets an explicit "Play for +N movement" button. Every play is
now a two-step, which is the correct cost in a game with no undo.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Paired openings now share a printed letter (A, B, C ...), exactly as
the physical boards mark them — making the 2-player crossed pairings
legible at a glance. While standing on an opening, its destination
square pulses with a dashed green ring, so "leave at B, re-enter at B"
stops being a leap of faith.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The engine's warps worked all along (verified in all six directions),
but the client offered no way to trigger one short of clicking the
destination cell across the map. The warp arrows are now buttons: when
you stand on an opening its arrow lights green — click it to step
through. Clicking a far arrow behaves as a click on its cell.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pick Up Treasure is disabled unless an uncarried treasure sits on your
square (and your actions haven't ended); Drop Treasure unless you are
actually carrying one. The warp-step button reuses the same derived
state. Buttons stay visible for stable layout — they just stop
inviting impossible clicks.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The design system is the physical set itself, taken from the scans:
card-stock cream, warm ink, and the six wizard marker colors, laid on
a dark leather tabletop. Cards in your hand are now the actual cards —
vertical corner rails (ATTACK / L.O.S. / ADJACENT), condensed gothic
titles, brown body text on cream, number cards as big bordered
numerals with per-value border styles; selecting lifts a card from
the fan. The board matches the physical tiles: ink-outlined white
brick walls on cracked flagstone, plank doors, eight-point home stars
in each wizard's color, swirled treasure discs, warp arrows. The
sidebar is paper: a turn slip, the rulebook's own hand-scrawled
life-points score sheet (Caveat over ruled lines), and a typewritten
chronicle that scrolls itself. The lobby is the box lid. Type:
Oswald condensed display / Archivo Narrow body / Courier Prime log.
Buttons are ink stamps. Board height-caps so board, actions, and the
full hand share one screen; responsive stack below 900px; reduced
motion respected. Verified with live screenshots at 1440x900.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
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>
KILLER OOZE (1 damage on entry, slip on 1-2: drop treasure, 2 more,
flat on your face until you roll to stand), CREATE PIT (jumps roll a
D4 — clear it on 2-4, fall in on a 1 and climb out on later rolls),
ROSEBUSH (3-point passage, blocks sight), DUST CLOUD (a permanent
zone of blindness: direction rolls inside, no LOS through, defeats
Visionstone), FILL SQUARE WITH SLIME (entering ends your actions,
blocks sight), HANDFUL OF TACKS (adjacent-only scatter, 3 points to
cross), CREATE DOOR (a new locked door in any wall or corridor),
BOOBYTRAP (four face-down tokens, one secretly real — 4 points under
anyone but the caster; the caster's view alone marks the true token),
GLUE (objects pinned for twice the number card), SAFE (items locked
away from everyone but the creator), TRADER (swap two floor items in
sight; glue and safes hold fast), and STONE TO WATER (walls melt into
range-2 waves, stone blocks into range-4 bursts). LOS blocking is now
per-terrain-kind. The board renders all of it, boobytrap placement is
a four-click ritual, and Trader is two. 108 tests passing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Wands charge on first use from the number card(s) played (Amplify and
Add both work when setting charges), spend one charge per use with a
hard once-per-turn limit, stay displayed while charged, and crumble
to the discard when the last charge goes. They are isolated from
their wielder — usable under NO SPELL — and Absorb Spell cannot eat
them. BLASTER WAND fires 3-point bolts through the normal
counteraction stack; STICKY WAND webs its victim (movement -3 for a
turn, +2 to any fire damage, including hotter firewall crossings);
SHIFT WAND shoves a wizard one space in any direction straight
through stone walls; WARP WAND opens a wall section that snaps back
at the end of the turn. DEJA-VU retrieves any discard except a wand.
The wands' 5e-era "stick" subtype is renamed "wand" per Eric (the 6e
faces say Wand; Exp2 shelf cards keep their period names). Client:
charge badges, shove targeting, retrieve-by-name. 101 tests passing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Creatures are first-class citizens: TROLL (D4 punches, 6 damage to
kill, regenerates at its creator's turn end), SKELETON (2-point
punches), WRAITH (walks through one wall a turn; its touch deals 2
and steals a random card), FIRE IMP (a stationary turret scorching
anyone in sight once per turn — including its creator — killed only
by Waterbolt or a Waterwall wave), DEMOCRATIC MONSTER (moved three
spaces by EVERY player on their turn, one claw per round), SHADOW (a
second body costing a life point per turn, destroyed by any damage),
and ALTER EGO (a stationary double). Monsters obey their creators,
move on the controller's turn, attack once per turn but never on
their creation turn (summoning IS your attack), refuse to strike
their creators, and vanish when their creator dies. Attacks can
target creatures directly (no counteraction window — monsters don't
counter); Dispel Creation un-creates them. Plus MEGA-MONSTER (double
a monster's toughness or speed), ADRENALINE (two attacks a turn),
MAD DASH, and LIFESAVER. Expansion Set #2 confirmed by Eric as a
5e-era product — marked historical-only in the data; the 6e game is
exactly base + Expansion #1 (200 cards, all verified). Lobby gains an
"include Expansion Set #1" toggle; the client renders creatures as
diamond tokens with select-move-attack interaction. 95 tests passing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The hard six: AROUND THE CORNER attaches to any LOS attack and bends
the sight line through one intermediate cell. BLIND victims lurch in
die-rolled directions (bumping a wall costs the movement point, per
the card) and their attacks fly wherever the die says — hitting
whoever stands that way, or dissipating. UGLY drives every opponent
in sight fleeing along shortest paths (breadth-first, die-broken ties)
until they cannot see the caster. ILLUSION WALL is per-player reality:
each opponent rolls 50/50 the first time it matters and the wall is
real for believers forever — believers' views render it as a wall,
the caster and those who saw through it get a ghostly dashed line,
and Dispel Creation banishes it. ROTATE SECTOR turns a sector 90
degrees with every wall, door, wizard, treasure, object, firewall and
alteration turning in place (the home star, being the exact center,
never moves); RELOCATE SECTOR slides a sector anywhere that keeps all
sectors adjacent, reassembling the map and recomputing wraparounds.
Client: modifier attachment (Amplify/Add/Extend/Around The Corner),
two-stage relocate, rotation direction toggle, dashed known-illusions.
Every card in the 6th edition basic deck is now implemented.
81 tests passing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stones are displayed permanents whose powers weave into the core
systems: BLOODSTONE (-1 to every hit taken, cancels Slow Death's
drip), SOULSTONE (last three points immune to spell damage — punches
and daggers still finish the job), BRAINSTONE (+2 cards now, hand
limit 9 — limits are now per-player and dynamic), POWERSTONE (+1 per
number card played, movement included), SPEEDSTONE (+1 movement,
overridden by SLOW), SHADOWSTONE (physical damage you deal feeds your
life), SHIELDSTONE (number cards become counteractions that shave
their value off damage AND duration), VISIONSTONE (LOS through any
single wall or door, at the holder's option). Damage now carries a
spell/physical kind everywhere. SLOW DEATH is a permanent curse: one
magical point per card drawn, forever — Fireball still burns stones
off their display. Re-displaying a stone is refused (no Brainstone
double-draws). 49 basic-set cards implemented, 15 remain (the hard
five: bent LOS, Blind, Illusion Wall, Ugly, sector manipulation).
72 tests passing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Terrain layer: FILL SQUARE WITH STONE (impassable, blocks LOS via new
cell-blocking sight checks), THORNBUSH (enter = 1 damage + turn ends +
next turn lost; no attacking in or into a bush), WALL OF FIRE (new
firewall edge state — passable for 4 magical damage, blocks LOS,
expires with its duration), WATERWALL (instant wave: players within
two spaces washed back two, 1 damage per blocked space), and DISPEL
CREATION with provenance tracking (only conjured walls/fire/stone/
bushes dispel — printed maze is safe). Objects: DAGGER (3) and LARGE
ROCK (2) are physical throws Full Shield cannot stop; they land on the
floor and anyone may pick them up (ending their turn's actions, hand
limit enforced); DROP OBJECT forces a named object or carried treasure
to the ground; DRAG pulls floor objects, treasures, or players
straight toward the caster. Control: LOCK IN PLACE (no moving or
being moved — teleports, swaps, knockbacks and drags all respect it),
BUDDY (a pact the caster breaks by attacking), MIST-BODY (through
walls and doors, cannot attack or be attacked, still burns in
firewalls), REUSE SPELL (retrieve your last spell). Client renders
terrain, firewalls, and ground objects, with cell/edge/two-stage
targeting and card-name inputs. 40 cards implemented; 63 tests pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Duration system: sustained effects expire at the start of the caster's
turns; SLOW (movement 1, no number cards, attack every other turn),
NO SPELL, MEDUSA (paralysis + damage immunity), INVISIBLE (1-in-4 hit
roll), SHRINK (50% miss, movement 2). Doors: PICK LOCK and MASTER KEY
(displayed, reusable) unlock adjacent doors until end of turn, REMOVE
LOCK is permanent, JAM LOCK seals a door for everyone. Movement:
TELEPORT (4 spaces through walls, ends movement), PASS THROUGH WALL
charges, POWER RUN (life for spaces), SWAP (consumes movement),
GO AWAY (knockback + lost turn), TELEPORT OPPONENT. Card warfare:
CARD ERASURE (named), THOUGHT-STEAL (2 random via seeded RNG),
TELEPATH (private hand reveal), POWER DRAIN (damage feeds the caster),
SUDDEN DEATH, STONE DEAD, WIZARDBLADE (same-square, number-powered,
stays displayed). Cast modifiers: AMPLIFY doubles power/duration
(stackable x2), ADD permits two number cards, EXTEND doubles duration;
REVERSE heals instead of harms but keeps secondary effects. Counters
now also halve durations (BLUNT) and split them (REFLECTION).
Security (from review findings): room codes and game seeds now come
from node:crypto, and every seat gets a secret token — reclaiming a
name in a room requires its token, closing the impersonation hole.
29 cards implemented; 51 tests passing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Server: room registry with 4-letter codes, host/join/start flow, the
authoritative command loop (seed + append-only command log per room —
the replay/async foundation), and per-player redacted views and events
broadcast after every change. Client: lobby, SVG board (floors, walls,
doors, homes, color-keyed treasures and wizard tokens matching the
physical set's six colors, warp arrows), click-to-move, click-to-punch,
card hand with tooltips from verified card text, cast flow with number
card attachment and waterbolt split, edge-click targeting for wall
spells, counteract-or-pass prompt, discard flow, end-turn draw
selector, and a humanized event log. Verified end-to-end over real
websockets with two clients: join, start, private deals, moves, turn
sync.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
npm workspaces with three TypeScript packages: @wizwar/engine (pure
game logic), @wizwar/server (Node websocket authority), @wizwar/web
(Svelte 5 + Vite client). Server handshake and client build verified.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>