Expansion wave 1: the creature system and first eight monster cards
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>
This commit is contained in:
co-authored by
Claude Fable 5
parent
e475253fb0
commit
df0675c735
@@ -68,6 +68,16 @@ function humanize(e: GameEvent): string | null {
|
||||
: `${e.player} is convinced the wall is real.`;
|
||||
case "sectorRotated": return `The maze GRINDS — a sector rotates ${e.clockwise ? "clockwise" : "counterclockwise"}!`;
|
||||
case "sectorRelocated": return `The maze SHUDDERS — an entire sector slides away!`;
|
||||
case "creatureCreated": return `${e.controller} summons a ${e.kind.replace(/-/g, " ")}!`;
|
||||
case "creatureMoved": return null;
|
||||
case "creatureAttacked": return e.dieRoll != null ? `The troll swings (rolled ${e.dieRoll})!` : `The creature strikes!`;
|
||||
case "creatureTouched": return `The creature falls upon ${e.player}!`;
|
||||
case "creatureDamaged": return e.amount > 0 ? `The ${e.creatureId} takes ${e.amount} damage.` : `The attack has no effect on it.`;
|
||||
case "creatureDestroyed": return `The ${e.kind.replace(/-/g, " ")} is destroyed (${e.by})!`;
|
||||
case "trollRegenerated": return `The troll's stony hide knits itself back together.`;
|
||||
case "shadowUpkeep": return `The shadow drains its master (${e.lifeAfter} life left).`;
|
||||
case "impScorches": return `The fire imp scorches ${e.player}!`;
|
||||
case "monsterBoosted": return `The monster GROWS — its ${e.boost} doubles!`;
|
||||
case "trapRedrawnDuringDeal": return null;
|
||||
case "died": return `☠ ${e.player} is dead${e.killedBy ? ` — killed by ${e.killedBy}` : ""}.`;
|
||||
case "handTaken": return `${e.to} takes ${e.count} cards from ${e.from}'s body.`;
|
||||
@@ -150,8 +160,8 @@ class Net {
|
||||
this.send({ type: "join", roomId, name, token: this.token });
|
||||
}
|
||||
|
||||
start(): void {
|
||||
this.send({ type: "start" });
|
||||
start(expansion: boolean): void {
|
||||
this.send({ type: "start", expansion });
|
||||
}
|
||||
|
||||
command(command: Command): void {
|
||||
|
||||
Reference in New Issue
Block a user