Rev 23: POWER DRAIN drains the number played; the troll punches walls; the first-person stack fits

POWER DRAIN's gain is the number played, BLUNTed or ABSORBed or not
(FAQ: the counter blunts the damage done, not the drain), and a wall
drained for its points gives them up too. Older games gave only what
the opponent lost and nothing from a wall, and replay so.

"This rock-hard beast can punch a player (or a wall, etc.)": a commanded
troll now punches a wall line beside it for a D4, once a turn — a new
command, so no old game changes.

Under the first-person pane the board strip could run into the dock on
a short or tall window; the pane now takes no more height than the row
can spare and the strip shrinks beneath it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
This commit is contained in:
Eric Wagoner
2026-09-17 00:07:34 -04:00
co-authored by Claude Fable 5.1
parent 803c51415e
commit 80dd7a7865
6 changed files with 145 additions and 11 deletions
+24
View File
@@ -998,3 +998,27 @@ describe("the alter ego casts from its own square", () => {
expect(done.players.find((p) => p.id === defender)!.life).toBe(10);
});
});
describe("the troll's fist on a wall", () => {
it("punches a wall line beside it for a D4, once a turn", () => {
let { state } = newGame();
state = toRound2(state);
const me = activePlayer(state).id;
const r = summon(state, me, "troll");
state = r.state;
const other = state.players.find((p) => p.id !== me)!.id;
state = must(state, me, { type: "endTurn", draw: 0 });
state = must(state, other, { type: "endTurn", draw: 0 });
const troll = state.creatures[0]!;
const board = boardView(state);
const side = SIDES.find((s) => board.edges[edgeKey(troll.position, s)] === "wall")!;
const res = applyCommand(state, me, { type: "creatureAttackWall", creatureId: troll.id, cell: troll.position, side });
expect(res.ok).toBe(true);
if (!res.ok) return;
const hit = res.events.find((e) => e.type === "wallDamaged");
expect(hit && hit.type === "wallDamaged" ? hit.amount : 0).toBeGreaterThanOrEqual(1);
expect(res.state.creatures[0]!.attackUsed).toBe(true);
const again = applyCommand(res.state, me, { type: "creatureAttackWall", creatureId: troll.id, cell: troll.position, side });
expect(again.ok).toBe(false);
});
});