From f372b0a3cabd7aaa72d6130a140533b33299d1e8 Mon Sep 17 00:00:00 2001 From: Eric Wagoner Date: Sat, 31 Oct 2026 22:54:00 -0400 Subject: [PATCH] A fire imp asks for no orders, and Chaos asks for no shield you do not hold The creature slip offered "attack ready" for every creature you control, but only trolls, skeletons and shadows strike on command; a fire imp neither moves nor takes orders, so it no longer awaits any. The Chaos slip told every player to tap a Full Shield; a hand without one is now told so and offered only the way through. The duel skill gains game fifteen's lessons. Co-Authored-By: Claude Opus 5.5 --- .claude/skills/wizwar-duel/SKILL.md | 23 +++++++++++++++++++++++ packages/web/src/App.svelte | 15 ++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/.claude/skills/wizwar-duel/SKILL.md b/.claude/skills/wizwar-duel/SKILL.md index b461127..0201a17 100644 --- a/.claude/skills/wizwar-duel/SKILL.md +++ b/.claude/skills/wizwar-duel/SKILL.md @@ -255,6 +255,29 @@ probing legality is free, so when unsure, try it and read the error. on WARP LANDING squares hit players who never see the token coming. That placement doctrine is proven; repeat it. +## Game-fifteen scars (six seats, lost to a two-life walk home) + +- **Same victim twice, again — and the kill feeds the carrier.** + Kestrel banked Automaton IV's first chest, his troll killed IV, and + IV's cards passed to him — the hand that kept him alive on two life + long enough to walk IV's second chest home (the game-nine lesson, + taught a second time). A wizard's death is a card windfall for its + killer: when a weak player falls to someone carrying, price the loot + into his survival. When a human has one banked, find the victim whose + LAST floor chest sits nearest him and guard THAT square. +- **The interception window is the turn BEFORE the grab.** Once he held + the chest four steps from home, nothing I could reach could see his + road. Run the sight-and-block scan against his likely grab squares + every turn he has one banked, not after he picks up. +- **CHAOS scrambles your own tools.** I cast it to strip his numbers and + lost both pick-locks my door route needed; my whole plan was a hand + I no longer held. Cast it only when your plan does not depend on the + hand you are giving away. +- Stone and thornbush as blockers worked twice against a bot carrier + (8 -> 11, then 8 -> 22 steps): a bot BFS reroutes rather than wades, + and buys real turns. The block scan (my reach x visible empty squares + x carrier's new distance) is the tool; keep it in the scratchpad. + ## The passivity audit (Eric, after game thirteen) - "You did nothing but draw for several turns" — true, and fatal. A diff --git a/packages/web/src/App.svelte b/packages/web/src/App.svelte index c528e3c..8e9e513 100644 --- a/packages/web/src/App.svelte +++ b/packages/web/src/App.svelte @@ -1890,12 +1890,17 @@ return bent ? bentSightedCellsFor(view, castingDouble?.position) : sightedCellsFor(view, castingDouble?.position); }); + /** The creatures that strike on command; the rest (a fire imp, a wraith) + * pick their own victims, as the engine's creatureAttack holds. */ + const ORDERED_ATTACKERS = new Set(["troll", "skeleton", "shadow"]); + const attackReady = (c: { kind: string; attackUsed: boolean; justCreated?: boolean }) => + ORDERED_ATTACKERS.has(c.kind) && !c.attackUsed && !c.justCreated; /** Creatures awaiting your orders this turn (yours + any democratic monster). */ const idleCreatures = $derived( view != null && isYourTurn ? view.creatures.filter((c) => (c.controllerId === view!.you || c.kind === "democratic-monster") && - (c.movementUsed < c.movesPerTurn || (!c.attackUsed && !c.justCreated))) + (c.movementUsed < c.movesPerTurn || attackReady(c))) : [], ); @@ -3440,7 +3445,11 @@ {#if youMustShield}
- Chaos comes for your hand. Tap your Full Shield to sit out, or + {#if view.yourHand.some((c) => c.cardId === "full-shield")} + Chaos comes for your hand. Tap your Full Shield to sit out, or + {:else} + Chaos comes for your hand, and you hold no Full Shield to sit it out. + {/if}
{:else if view.chaosPending} @@ -3450,7 +3459,7 @@ {@const moves = c.movesPerTurn - c.movementUsed}
🜲 {c.controllerId === view.you ? "Your" : "The"} {cardDef(c.kind).name} awaits orders: - {#if moves > 0}{moves} move{moves === 1 ? "" : "s"}{/if}{#if moves > 0 && !c.attackUsed && !c.justCreated} · {/if}{#if !c.attackUsed && !c.justCreated}attack ready{/if}. + {#if moves > 0}{moves} move{moves === 1 ? "" : "s"}{/if}{#if moves > 0 && attackReady(c)} · {/if}{#if attackReady(c)}attack ready{/if}. Tap its token to command it.
{/each}