From 724d1786363559e08b3421161d3b745a9c4d26b2 Mon Sep 17 00:00:00 2001 From: Eric Wagoner Date: Wed, 19 Aug 2026 21:40:48 -0400 Subject: [PATCH] Hotfix: fear's new metric leaked into old vintages and broke replay QD3S failed to restore ('replay failed at seq 76: an unnatural dread keeps you away'): the walkingDistance switch ran at every rev, refusing a move that was legal under the crow-flies rule when it was played. fearRepels now measures walked spaces at rev 32+ and as the crow flies below, so every stored ledger replays its own vintage. No data was lost; the room's ledger was intact throughout. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0138A8CjeQRpvzKxuMfz1Bqc --- packages/engine/src/game.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/engine/src/game.ts b/packages/engine/src/game.ts index d91e80e..5ba15ef 100644 --- a/packages/engine/src/game.ts +++ b/packages/engine/src/game.ts @@ -3727,9 +3727,15 @@ function fearRepels(state: GameState, moverId: PlayerId | null, from: Cell, to: if (!other.alive || other.id === moverId) continue; if (sustainedOn(state, other.id, "fear").length === 0) continue; // "Spaces" are counted through the maze — warps included, walls - // respected — exactly as feet would walk them. - const d = walkingDistance(state, other.position, to); - const dBefore = walkingDistance(state, other.position, from); + // respected — exactly as feet would walk them (rules rev 32). Earlier + // games measured as the crow flies, and their ledgers replay so. + const walked = (state.config.deckRev ?? 1) >= 32; + const d = walked + ? walkingDistance(state, other.position, to) + : Math.abs(other.position.x - to.x) + Math.abs(other.position.y - to.y); + const dBefore = walked + ? walkingDistance(state, other.position, from) + : Math.abs(other.position.x - from.x) + Math.abs(other.position.y - from.y); if (d <= 3 && d < dBefore) return true; } return false;