Credibility pass: the collapse loses its scaffolding

Blind reviews over the rev-37..40 features and the gate collapse. The
scripted surgery's scars come out: bare brace blocks unwrapped (with one
hiding an unreachable scrambleHands), the amputated comment healed, the
dead events parameter unthreaded from the illusion-sight chain, the
laziness probe in perceivedBoard collapsed to the rule it always produced,
GameView.deckRev retired with its last reader, the ward's arming stub
told honestly, and every comment or test title still citing the retired
revision numbering reworded to the rule it guards. Rim mechanics unify on
rimWarpMouth and breachRim; the test suite gains plainRimWall and
pushSustained and loses its loop-shaped scars and rev-named helpers.
No behavior changes; 255 tests pass unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-21 13:04:01 -04:00
co-authored by Claude Fable 5
parent 8a50ff7f36
commit 4a91d56d24
17 changed files with 367 additions and 452 deletions
+109 -147
View File
@@ -3,7 +3,7 @@ import { applyCommand, activePlayer, boardView, createGame, gameLos } from "../s
import { cellKey, edgeKey, SIDES, stepTarget, type Cell, type Side } from "../src/board";
import type { CardInstance } from "../src/cards";
import { eligibleCellsFor, sightedCellsFor, viewFor } from "../src/view";
import { newExpansionGame as newGame, must, giveCard, emptyNeighborCell } from "./helpers";
import { newExpansionGame as newGame, must, giveCard, emptyNeighborCell, plainRimWall } from "./helpers";
describe("expansion terrain", () => {
it("killer ooze burns on entry and can drop you on your face", () => {
@@ -163,170 +163,132 @@ describe("expansion terrain", () => {
});
it("wall of fire takes a rim warp — both mouths burn the crossing", () => {
{
let { state } = createGame({
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
});
const me = activePlayer(state);
const warp = state.board.warps[0]!;
me.position = { ...warp.from.cell };
const wof = giveCard(state, me.id, "wall-of-fire", "WF", 0);
const r = applyCommand(state, me.id, {
type: "cast", instanceId: wof.instanceId,
target: { kind: "edge", cell: warp.from.cell, side: warp.from.side },
});
if (!r.ok) throw new Error(r.error);
state = r.state;
const nearKey = edgeKey(warp.from.cell, warp.from.side);
const farKey = edgeKey(warp.to.cell, warp.to.side);
expect(boardView(state).edges[nearKey]).toBe("firewall");
expect(boardView(state).edges[farKey]).toBe("firewall");
// The corridor still runs — through flame: the crossing lands on the
// far rim and burns for 4.
state = must(state, me.id, { type: "move", direction: warp.from.side });
const after = state.players.find((p) => p.id === me.id)!;
expect(cellKey(after.position)).toBe(cellKey(warp.to.cell));
expect(after.life).toBe(11);
}
let { state } = createGame({
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
});
const me = activePlayer(state);
const warp = state.board.warps[0]!;
me.position = { ...warp.from.cell };
const wof = giveCard(state, me.id, "wall-of-fire", "WF", 0);
const r = applyCommand(state, me.id, {
type: "cast", instanceId: wof.instanceId,
target: { kind: "edge", cell: warp.from.cell, side: warp.from.side },
});
if (!r.ok) throw new Error(r.error);
state = r.state;
const nearKey = edgeKey(warp.from.cell, warp.from.side);
const farKey = edgeKey(warp.to.cell, warp.to.side);
expect(boardView(state).edges[nearKey]).toBe("firewall");
expect(boardView(state).edges[farKey]).toBe("firewall");
// The corridor still runs — through flame: the crossing lands on the
// far rim and burns for 4.
state = must(state, me.id, { type: "move", direction: warp.from.side });
const after = state.players.find((p) => p.id === me.id)!;
expect(cellKey(after.position)).toBe(cellKey(warp.to.cell));
expect(after.life).toBe(11);
});
it("waterwall takes a rim warp — the collapse washes both rims", () => {
{
let { state } = createGame({
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
});
const me = activePlayer(state);
const other = state.players.find((p) => p.id !== me.id)!;
const warp = state.board.warps[0]!;
me.position = { ...warp.from.cell };
other.position = { ...warp.to.cell };
const ww = giveCard(state, me.id, "waterwall", "WW", 0);
const r = applyCommand(state, me.id, {
type: "cast", instanceId: ww.instanceId,
target: { kind: "edge", cell: warp.from.cell, side: warp.from.side },
});
if (!r.ok) throw new Error(r.error);
// Both wizards stood in the mouths; the collapse washed both inward.
const meAfter = r.state.players.find((p) => p.id === me.id)!;
const otherAfter = r.state.players.find((p) => p.id === other.id)!;
expect(cellKey(meAfter.position)).not.toBe(cellKey(warp.from.cell));
expect(cellKey(otherAfter.position)).not.toBe(cellKey(warp.to.cell));
}
let { state } = createGame({
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
});
const me = activePlayer(state);
const other = state.players.find((p) => p.id !== me.id)!;
const warp = state.board.warps[0]!;
me.position = { ...warp.from.cell };
other.position = { ...warp.to.cell };
const ww = giveCard(state, me.id, "waterwall", "WW", 0);
const r = applyCommand(state, me.id, {
type: "cast", instanceId: ww.instanceId,
target: { kind: "edge", cell: warp.from.cell, side: warp.from.side },
});
if (!r.ok) throw new Error(r.error);
// Both wizards stood in the mouths; the collapse washed both inward.
const meAfter = r.state.players.find((p) => p.id === me.id)!;
const otherAfter = r.state.players.find((p) => p.id === other.id)!;
expect(cellKey(meAfter.position)).not.toBe(cellKey(warp.from.cell));
expect(cellKey(otherAfter.position)).not.toBe(cellKey(warp.to.cell));
});
it("illusion wall hangs on a rim warp mouth", () => {
{
const { state } = createGame({
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
});
const me = activePlayer(state);
const warp = state.board.warps[0]!;
me.position = { ...warp.from.cell };
const il = giveCard(state, me.id, "illusion-wall", "IL", 0);
const r = applyCommand(state, me.id, {
type: "cast", instanceId: il.instanceId,
target: { kind: "edge", cell: warp.from.cell, side: warp.from.side },
});
expect(r.ok).toBe(true);
if (r.ok) {
expect(r.state.illusionWalls[edgeKey(warp.from.cell, warp.from.side)]).toBeDefined();
}
const { state } = createGame({
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
});
const me = activePlayer(state);
const warp = state.board.warps[0]!;
me.position = { ...warp.from.cell };
const il = giveCard(state, me.id, "illusion-wall", "IL", 0);
const r = applyCommand(state, me.id, {
type: "cast", instanceId: il.instanceId,
target: { kind: "edge", cell: warp.from.cell, side: warp.from.side },
});
expect(r.ok).toBe(true);
if (r.ok) {
expect(r.state.illusionWalls[edgeKey(warp.from.cell, warp.from.side)]).toBeDefined();
}
});
it("stone to water breaches the outer rim, opening a warp", () => {
{
let { state } = createGame({
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
});
const me = activePlayer(state);
const board = boardView(state);
// Stand at a plain rim wall (an off-board edge that is no warp mouth).
let rim: { cell: Cell; side: Side } | null = null;
outer: for (const k of Object.keys(board.cells)) {
const [x, y] = k.split(",").map(Number) as [number, number];
for (const side of SIDES) {
const n = { x: x + (side === "E" ? 1 : side === "W" ? -1 : 0), y: y + (side === "S" ? 1 : side === "N" ? -1 : 0) };
if (board.cells[cellKey(n)]) continue;
if (board.edges[edgeKey({ x, y }, side)] !== "wall") continue;
if (state.board.warps.some((w) => cellKey(w.from.cell) === k && w.from.side === side)) continue;
rim = { cell: { x, y }, side };
break outer;
}
}
if (!rim) throw new Error("setup: no plain rim wall found");
me.position = { ...rim.cell };
const warpsBefore = state.board.warps.length;
const stw = giveCard(state, me.id, "stone-to-water", "SW", 0);
state = must(state, me.id, {
type: "cast", instanceId: stw.instanceId,
target: { kind: "edge", cell: rim.cell, side: rim.side },
});
// The far rim melted with it and the wraparound now runs.
expect(state.board.warps.length).toBe(warpsBefore + 2);
}
let { state } = createGame({
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
});
const me = activePlayer(state);
const rim = plainRimWall(state);
me.position = { ...rim.cell };
const warpsBefore = state.board.warps.length;
const stw = giveCard(state, me.id, "stone-to-water", "SW", 0);
state = must(state, me.id, {
type: "cast", instanceId: stw.instanceId,
target: { kind: "edge", cell: rim.cell, side: rim.side },
});
// The far rim melted with it and the wraparound now runs.
expect(state.board.warps.length).toBe(warpsBefore + 2);
});
it("no doors through the rim", () => {
{
const { state } = createGame({
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
});
const me = activePlayer(state);
const board = boardView(state);
let rim: { cell: Cell; side: Side } | null = null;
outer: for (const k of Object.keys(board.cells)) {
const [x, y] = k.split(",").map(Number) as [number, number];
for (const side of SIDES) {
const n = { x: x + (side === "E" ? 1 : side === "W" ? -1 : 0), y: y + (side === "S" ? 1 : side === "N" ? -1 : 0) };
if (!board.cells[cellKey(n)] && board.edges[edgeKey({ x, y }, side)] === "wall") {
rim = { cell: { x, y }, side };
break outer;
}
}
}
if (!rim) throw new Error("setup: no rim wall found");
me.position = { ...rim.cell };
const cd = giveCard(state, me.id, "create-door", "CD", 0);
const r = applyCommand(state, me.id, {
type: "cast", instanceId: cd.instanceId,
target: { kind: "edge", cell: rim.cell, side: rim.side },
});
expect(r.ok).toBe(false);
}
const { state } = createGame({
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
});
const me = activePlayer(state);
const rim = plainRimWall(state);
me.position = { ...rim.cell };
const cd = giveCard(state, me.id, "create-door", "CD", 0);
const r = applyCommand(state, me.id, {
type: "cast", instanceId: cd.instanceId,
target: { kind: "edge", cell: rim.cell, side: rim.side },
});
expect(r.ok).toBe(false);
});
it("stone to water melts a door — a small entryway in a stone wall", () => {
{
const { state } = createGame({
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
});
const me = activePlayer(state);
const board = boardView(state);
// Stand the caster at some door and melt it point-blank.
let doorAt: { cell: Cell; side: Side } | null = null;
outer: for (const k of Object.keys(board.cells)) {
const [x, y] = k.split(",").map(Number) as [number, number];
for (const side of SIDES) {
if (board.edges[edgeKey({ x, y }, side)] === "door") {
doorAt = { cell: { x, y }, side };
break outer;
}
const { state } = createGame({
playerIds: ["alice", "bob"], seed: 42, sets: ["basic", "expansion1"],
});
const me = activePlayer(state);
const board = boardView(state);
// Stand the caster at some door and melt it point-blank.
let doorAt: { cell: Cell; side: Side } | null = null;
outer: for (const k of Object.keys(board.cells)) {
const [x, y] = k.split(",").map(Number) as [number, number];
for (const side of SIDES) {
if (board.edges[edgeKey({ x, y }, side)] === "door") {
doorAt = { cell: { x, y }, side };
break outer;
}
}
if (!doorAt) throw new Error("setup: no door on this board");
me.position = { ...doorAt.cell };
const stw = giveCard(state, me.id, "stone-to-water", "SW", 0);
const r = applyCommand(state, me.id, {
type: "cast", instanceId: stw.instanceId,
target: { kind: "edge", cell: doorAt.cell, side: doorAt.side },
});
expect(r.ok).toBe(true);
if (r.ok) {
const key = edgeKey(doorAt.cell, doorAt.side);
expect(boardView(r.state).edges[key] ?? "open").toBe("open");
expect(r.state.doorStates[key]).toBeUndefined();
}
}
if (!doorAt) throw new Error("setup: no door on this board");
me.position = { ...doorAt.cell };
const stw = giveCard(state, me.id, "stone-to-water", "SW", 0);
const r = applyCommand(state, me.id, {
type: "cast", instanceId: stw.instanceId,
target: { kind: "edge", cell: doorAt.cell, side: doorAt.side },
});
expect(r.ok).toBe(true);
if (r.ok) {
const key = edgeKey(doorAt.cell, doorAt.side);
expect(boardView(r.state).edges[key] ?? "open").toBe("open");
expect(r.state.doorStates[key]).toBeUndefined();
}
});
});