Rev 22: the self-stack resolves — one wizard cannot bounce to himself

A democratic monster touching its own creator opens a stack where one
player wears both hats, and doPass matched the attacker first: every
pass "bounced the exchange to the defender" — the same wizard —
forever. Room 928D livelocked there at seq 83; once the boot kick
revived its pump, the automaton politely passed 389 times. At rev 22
a self-stack pass RESOLVES (the claw lands, the game moves on);
older ledgers hold their recorded bounces and replay so. 928D itself
was repaired by truncating the no-op run and lifting it to rev 22,
verified clean and unstuck on a copy before installation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-17 18:14:18 -04:00
co-authored by Claude Fable 5
parent 4a75370de5
commit 7372bfc5e8
4 changed files with 46 additions and 3 deletions
+7 -1
View File
@@ -5071,7 +5071,13 @@ function doPass(prev: GameState, playerId: PlayerId): CommandResult {
const state = clone(prev);
const stack = state.stack!;
const events: GameEvent[] = [];
if (playerId === stack.attackerId) {
// A self-stack (a democratic monster touching its own creator) has one
// party wearing both hats: their pass RESOLVES — bouncing it "to the
// defender" would hand the exchange back to themselves forever
// (rules rev 22; older ledgers hold those no-op bounces and replay so).
const selfStack =
stack.attackerId === stack.defenderId && (state.config.deckRev ?? 1) >= 22;
if (playerId === stack.attackerId && !selfStack) {
// The attacker declining to answer bounces the exchange back so the
// defender may stack further counters — but not past a total stop:
// re-prompting then reads as "your shield failed" and goads the table