The dread wraps: fear's diamond continues from the opposite rim

The maze is a torus — a wizard walking through walls off one edge
arrives at the other, so the crow flies around the wrap too.
dreadDistance measures toroidal manhattan; the aura's wash wraps with
it. No rev-32 game has cast fear yet, so the measure corrects in
place; older vintages replay flat as they were played.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0138A8CjeQRpvzKxuMfz1Bqc
This commit is contained in:
Eric Wagoner
2026-08-19 22:00:29 -04:00
co-authored by Claude Fable 5
parent bcd2155fe0
commit 0a0108c48c
2 changed files with 22 additions and 8 deletions
+14 -5
View File
@@ -3722,15 +3722,24 @@ function takeFromHand(p: PlayerState, instanceId: string): CardInstance | null {
* monsters (rules rev 32 widened it beyond walking wizards; forced movement
* such as knockback or a wave is not willing and passes).
*/
/**
* FEAR's measure FAQ: "as a Wizard walks (if he could walk through
* walls), not diagonally." Orthogonal steps, walls ignored and the maze
* wraps, so stepping off one rim continues from the opposite one.
*/
function dreadDistance(board: AssembledBoard, a: Cell, b: Cell): number {
const dx = Math.abs(a.x - b.x);
const dy = Math.abs(a.y - b.y);
return Math.min(dx, board.width - dx) + Math.min(dy, board.height - dy);
}
function fearRepels(state: GameState, moverId: PlayerId | null, from: Cell, to: Cell): boolean {
const board = boardView(state);
for (const other of state.players) {
if (!other.alive || other.id === moverId) continue;
if (sustainedOn(state, other.id, "fear").length === 0) continue;
// FAQ: "The 3 spaces away is measured as a Wizard walks (if he could
// walk through walls), not diagonally" — orthogonal steps, walls
// ignored. Warps do not carry the dread; walls do not shield from it.
const d = Math.abs(other.position.x - to.x) + Math.abs(other.position.y - to.y);
const dBefore = Math.abs(other.position.x - from.x) + Math.abs(other.position.y - from.y);
const d = dreadDistance(board, other.position, to);
const dBefore = dreadDistance(board, other.position, from);
if (d <= 3 && d < dBefore) return true;
}
return false;