Two-player decks shed LIFESAVER, as the card itself instructs

"Not applicable in a 2-player game." — the card face. New games deal
from deck revision 2, which removes it when exactly two wizards sit
down; three or more keep it. The revision travels in GameConfig and
the persisted start line, and stored games without one replay against
the original build — changing an existing game's deck composition
would scramble its deterministic replay. Test pins all three cases:
removed at two, present at three, present in legacy two-player games.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-16 12:07:28 -04:00
co-authored by Claude Fable 5
parent 26c4b6efdf
commit efec82e88d
5 changed files with 34 additions and 6 deletions
+5 -4
View File
@@ -157,7 +157,7 @@ export function pickColor(room: Room, playerId: PlayerId, color: number): string
return null;
}
function startInMemory(room: Room, expansion: boolean, colors?: number[]): { events: GameEvent[] } | { error: string } {
function startInMemory(room: Room, expansion: boolean, colors?: number[], deckRev?: number): { events: GameEvent[] } | { error: string } {
const n = room.players.length;
if (n < 2 || n > 6) return { error: "supported player counts: 2 to 6" };
const { state, events } = createGame({
@@ -165,6 +165,7 @@ function startInMemory(room: Room, expansion: boolean, colors?: number[]): { eve
seed: room.seed,
sets: expansion ? ["basic", "expansion1"] : ["basic"],
...(colors ? { colors } : {}),
...(deckRev ? { deckRev } : {}),
});
room.expansion = expansion;
room.state = state;
@@ -175,9 +176,9 @@ function startInMemory(room: Room, expansion: boolean, colors?: number[]): { eve
export function startGame(room: Room, expansion: boolean): { events: GameEvent[] } | { error: string } {
if (room.state) return { error: "already started" };
const colors = resolveColors(room);
const result = startInMemory(room, expansion, colors);
const result = startInMemory(room, expansion, colors, 2);
if ("error" in result) return result;
appendLine(room.id, { kind: "start", expansion, colors });
appendLine(room.id, { kind: "start", expansion, colors, deckRev: 2 });
recordRoom(room);
return result;
}
@@ -396,7 +397,7 @@ export function loadPersistedRooms(): void {
room.players.push(line.name);
room.tokens.set(line.name, joinHash);
} else if (line.kind === "start") {
const r = startInMemory(room, line.expansion, line.colors);
const r = startInMemory(room, line.expansion, line.colors, line.deckRev);
if ("error" in r) throw new Error(`replay start failed: ${r.error}`);
} else if (line.kind === "command") {
if (!room.state) throw new Error("command before start in log");