Files
wizwar6e/.claude/skills/wizwar-duel/SKILL.md
T
Eric WagonerandClaude Fable 5 3bd7e3c81d Credibility pass: the duels leave the code, staying in the ledgers
Third pass, scoped from 7a32370. Three blind reviewers (engine, web,
server/tools) each concluded the work is coherent engineering with
seam-level tells; every finding was verified before touching a line.

Session biography left the comments: the bot brain's heuristics no
longer cite the opponent who taught them, the RNRX coma parenthetical
and the thief-chase citation are gone, the seat-wallet comments state
their invariants without the war stories, and process-named test
groups now name the behaviors they pin. The incident record lives
where history belongs — commit messages and the ledgers.

Structural dedup: one VISIONSTONE one-edge-sight loop serves both
LOS paths; one creature-arrival touch handler serves walking and
warp-stepping (error text aligned); one facingWedge helper draws both
keymap ribbons; one spriteVisibleInCol rule serves the draw pass and
the hover test (which also stops re-sorting per pointermove); and
deepestFacing joins the director, replacing four copied scans.

Test hardening exposed real rot the tells were hiding: the tight
CreatureState cast caught two literals with a bogus field masking
three missing ones; the number-hoarding rig had NEVER run (its
column didn't exist on seed 42 — it now carves its own geometry);
the bank-guard rig now drives the whole table to an arrival
assertion; the bent-trace test walls off straight sight so the bend
must answer. Silent `return`-on-rig-failure became loud throws, and
can-never-fail assertions were removed.

Sweep-up: the eyeTurn ghost comment, the stacked leave() doc
comments (leave now delegates to leaveLocal), the dead ternary in
the seat client, the kick handler's name-coercion drift, kick ledger
lines gain timestamps, archiveRoomFile reuses fileFor, the RULES_REV
alias retires in favor of the engine constant, hitTest un-exports,
the NUL-sentinel hover shape becomes an honest "none" variant, and
the steering holds get named constants. The bezel's stride cluster
also centers per the table's note.

288 tests, 24 ledgers verified, all workspaces typecheck.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
2026-08-27 15:43:24 -04:00

7.4 KiB

name, description
name description
wizwar-duel Play Wiz-War live against Eric — join his room as a real seat, reason about every move yourself, and duel turn by turn over the websocket. Use when Eric wants a game, gives a room code, or says "let's play".

Playing Wiz-War against Eric

You are a PLAYER, not the automaton. Read the board, reason, and choose every command yourself. Eric plays in his browser; you play through the CLI seat at tools/claude-seat.mjs. He prompts "go" after his moves — each of his messages is your cue to look and act.

The seat client

Run from the repo root (needs the workspace's ws package):

node tools/claude-seat.mjs join <ROOM> Claude   # take a seat (token saved)
node tools/claude-seat.mjs view                 # board + hand + last events
node tools/claude-seat.mjs do '<command json>'  # one engine command
node tools/claude-seat.mjs chat "text"          # table talk

Seat state persists in /tmp/wizwar-claude-seat.json (override: WIZWAR_SEAT); server defaults to production (WIZWAR_SERVER to point elsewhere). Eric creates the room, gives you the code, and starts the game after you join.

Commands are the engine's Command union (packages/engine/src/game.ts): {"type":"move","direction":"N|S|E|W"}, cast (with target, optional numberInstanceIds/params), playNumberForMovement, pickUpTreasure, dropTreasure, warpStep, counteract, pass, punch, setAmbush, wardChoice, endTurn (with draw). A refused command costs nothing — probing legality is free, so when unsure, try it and read the error.

Reading the map

  • The renderer prints y=0 at top; y grows SOUTH. N = y-1, S = y+1.
  • C2 is you, P1 etc. are opponents, $c/$1 treasures, h? homes, two-letter codes are square contents (SA safe, RO rosebush, ST stone, DU dust). D on a line is a door, a wall, blank is open.
  • WARPS line lists rim passages as 2,0N→2,9: standing at (2,0) and moving N carries you to (2,9). The warp rides one specific side of its square — check which before you walk (a wrong guess burns moves; ask me how I know).
  • Dimensional-warp TOKENS (cast by players) are separate: stand on one and warpStep. Creatures use creatureWarpStep.

Hard-won rules knowledge (each cost me something in game one)

  • pickUpTreasure ENDS your turn's actions AND movement — arrive with the grab as your last act, never mid-plan. dropTreasure at home too.
  • You can pick up ANY floor treasure, including your own stolen-and- delivered one sitting on the enemy's home square. Repossession is real.
  • THIEF and punches need same-square; THIEF steals a named card and fizzles (card spent) on a wrong guess.
  • MENTAL FORCE moves the victim ≤3 walked spaces — walls and relocked doors shrink its reach; rev 5+ refuses impossible destinations.
  • Doors relock behind you when you pass through (rev 4+). Your own escape route can seal itself — and seal pursuers out.
  • LOS threads through rim warps: you can be seen (and shot) through a warp mouth from the far side of the board. Camping one square off the mouth keeps you hidden.
  • lock-in-place freezes movement AND warpStep for a full turn; REUSE SPELL retrieves only your LAST cast spell, enabling one re-lock.
  • An ambush (setAmbush interrupt/opportunity-fire + committed attack) triggers on LOS entry transitions only — someone already in sight never springs it. It survives forever and fires out of turn.
  • Walking-dead bleeds ½ life per space moved, permanently. Once cursed, every plan must be priced in steps.

Game-two scars (each cost me the game or nearly)

  • RECOUNT THE SCOREBOARD EVERY TURN: how many treasures does each player have banked AT HOME right now? I sprinted a "winning" delivery in game two that was actually my FIRST of two — Eric had un-banked me five rounds earlier and let me monologue. Banked counts, not vibes.
  • A banked treasure is NOT safe: anyone can pick it up off your home square and carry it away. Guard the bank or count it as contested.
  • LOS is FREE-ANGLE center-to-center (the rulebook's rule), not rows and columns: razor diagonals threading open gaps are legal for everyone — including at you. The board draws bent/straight traces.
  • ILLUSIONARY ATTACK deals its imitated spell's damage if NOT countered; ANY counteraction dispels it entirely. Counter it with the cheapest thing you hold; never "call the bluff" by passing.
  • Never trust your ASCII parse of the map for multi-step plans: run a BFS over view.board.edges (see tools/claude-seat.mjs view JSON, or write a quick router) before spending a number card on a sprint. I burned a 7-move turn bouncing off six misread walls.
  • Eric counter-plays YOUR bot upgrades: he summoned a troll bodyguard specifically against the archmage's exile-the-winner instinct, and relocated MY home sector mid-carry. Expect meta-warfare.
  • In 4p with automatons: the bots are chaos agents — they stun, exile, disease, and con. Herd them at Eric; never assume they're on script.

Game-three scars (lost in four rounds)

  • CHECK dimWarps EVERY SINGLE VIEW — Kestrel (Eric's wizard) has won two games with quietly-placed wormholes ending beside his home. The client prints a !! line for them; treat any new token pair as a five-alarm fire and recompute both players' delivery distances through it.
  • Never lead the attack against Kestrel. Three games, three saved counters sprung at the perfect moment (anti-anti, full-shield bait, full-reflection held three rounds for my lightning). Force his counters out with throwaways or positional threats before committing a real spell; his patience is perfect and he telegraphs nothing.
  • DESTROY WALL showers the ADJACENT caster with rubble (4 damage) — cast it from range, never on your own square's edge.
  • Wading a rosebush costs 3. A reflected LIGHTNING BLAST still stuns its caster even at 1 reflected damage — the stun is the payload, and a lost turn against Kestrel is a lost game.
  • Grab-turn-one openings feel great and prove nothing: deliveries are the only score. He banked quietly both times while I showboated.

Playing well

  • Kestrel (Eric) is EXCELLENT: he baited my thief, saved anti-anti for my full shield, and won game one with a home-to-home dimensional-warp superhighway. Infrastructure beats sprinting — watch what he builds, and consider your own wormhole early.
  • Win = 2 enemy treasures delivered to your home, or last wizard alive. Track BOTH players' step-counted delivery timelines every turn; the race is decided in tempo, not damage.
  • Hold counters (full-shield, absorb) for permanent curses and lethal damage. Absorb soaks 3 points; it cannot touch durations.
  • OPSEC: your prose is visible to Eric. NEVER name the cards you hold or draw, and never announce plans. (Game one: I narrated my hand like a debug log until he asked why I was making it easy.) Trash talk freely — about the board, never your hand.
  • Send chat for table talk at dramatic moments; it's half the fun.

Cadence

  1. On "go": view, read HIS events since your last turn (the client prints only NEW events; view shows a short history tail).
  2. Think about the whole board — his timeline, yours, threats, LOS.
  3. Execute your commands one at a time, checking errors.
  4. endTurn with a draw that respects the 7-card hand limit.
  5. Tell Eric it's his turn — reasoning aloud is fine, hand contents are not. When a stack waits on him, say so and wait for "go".