Card wave 2: durations, doors, teleports, modifiers; harden room auth
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>
This commit is contained in:
co-authored by
Claude Fable 5
parent
36b3ffe9a6
commit
67743dd17e
@@ -292,7 +292,7 @@ describe("stack discipline", () => {
|
||||
it("unimplemented cards refuse to cast with a clear error", () => {
|
||||
let { state } = newGame();
|
||||
const caster = activePlayer(state);
|
||||
const card = giveCard(state, caster.id, "medusa");
|
||||
const card = giveCard(state, caster.id, "ugly");
|
||||
const result = applyCommand(state, caster.id, { type: "cast", instanceId: card.instanceId });
|
||||
expect(result.ok).toBe(false);
|
||||
if (!result.ok) expect(result.error).toMatch(/not implemented/);
|
||||
|
||||
Reference in New Issue
Block a user