The mid-round democratic monster claws when its turn comes

Every creature is born with attackUsed spent — the right way to say
"cannot attack the turn created" for monsters whose flag refreshes
next turn. But the democratic monster's flag budgets its ROUND, so a
mid-round summon arrived pre-spent and bumped harmlessly until the
round rolled over. Creation-turn pacifism now rides justCreated
alone for the monster (checked at the touch), and its round-claw
starts live — folded into rev 18 with the boundary refresh.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-17 16:53:28 -04:00
co-authored by Claude Fable 5
parent 3b0aa01867
commit b4adb97536
2 changed files with 30 additions and 2 deletions
+6 -2
View File
@@ -2543,7 +2543,11 @@ function spawnCreature(
maxDamage: stats.maxDamage,
movesPerTurn: stats.moves,
movementUsed: 0, // "It may move on that turn." (Exp1 sheet)
attackUsed: true, // "cannot attack the turn they are created"
// "Cannot attack the turn they are created" is justCreated's job; the
// democratic monster's attackUsed budgets its ROUND, so spending it at
// birth would mute a mid-round summon until the round rolled over
// (rules rev 18).
attackUsed: !(kind === "democratic-monster" && (state.config.deckRev ?? 1) >= 18),
justCreated: true,
wallPassesPerTurn: stats.wallPasses,
wallPassUsed: 0,
@@ -2666,7 +2670,7 @@ function doMoveCreature(prev: GameState, creatureId: string, direction: Side): C
events.push({ type: "cardsDiscarded", player: p.id, cards: [card!] });
}
}
if (creature.kind === "democratic-monster" && !creature.attackUsed) {
if (creature.kind === "democratic-monster" && !creature.attackUsed && !creature.justCreated) {
creature.attackUsed = true; // "may attack only one player per round of turns"
events.push({ type: "creatureTouched", creatureId: creature.id, kind: creature.kind, player: p.id });
if (rev4) {
+24
View File
@@ -616,3 +616,27 @@ describe("the democratic monster's claw survives the first wizard's death (rules
expect(state.creatures[0]!.attackUsed).toBe(false);
});
});
describe("a mid-round democratic monster claws on the next turn (rules rev 18)", () => {
it("creation spends the turn, not the round", () => {
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"], deckRev: 18 });
state = toRound2(state);
const creator = activePlayer(state);
const r0 = summon(state, creator.id, "democratic-monster");
state = r0.state;
const dm = state.creatures.find((c) => c.kind === "democratic-monster")!;
expect(dm.attackUsed).toBe(false);
expect(dm.justCreated).toBe(true);
// Next player's turn: justCreated clears; the claw is live.
state = must(state, creator.id, { type: "endTurn", draw: 0 });
const mover = activePlayer(state);
const victim = state.players.find((p) => p.id !== mover.id)!;
const fresh = state.creatures.find((c) => c.kind === "democratic-monster")!;
expect(fresh.justCreated).toBe(false);
// March it onto the victim: the touch must open.
fresh.position = { x: victim.position.x - 1, y: victim.position.y };
const r = applyCommand(state, mover.id, { type: "moveCreature", creatureId: fresh.id, direction: "E" });
if (!r.ok) throw new Error(r.error);
expect(r.state.stack?.creatureId ?? null).toBe(fresh.id);
});
});