Credibility pass: the accretion sanded smooth
Blind reviews over d2b40ec..HEAD (engine / web / server+deploy). Orphaned doc comments rejoined their functions; the swap-meet tradables collapsed from four pasted deriveds to one (killing the "the's treasure" label); FEAR's aura and banner now share the engine's own dreadDistance; the long-press peek got one home; rulebook.ts stopped wearing JSON quotes; process-named tests and war-story comments now state the constraints they pin; the protocol doc caught up to its handlers; verify-ledgers.sh can actually count failures; the runbook learned about the determinism gate and the nightly backups. No behavior changes — 255 tests and all 48 production ledgers replay identically. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
3445d12206
commit
6adcbe23b5
@@ -2,10 +2,11 @@
|
||||
import type { Component } from "svelte";
|
||||
import type { GameView, SightTrace } from "@wizwar/engine";
|
||||
import type { Side } from "@wizwar/engine";
|
||||
import { dreadDistance } from "@wizwar/engine";
|
||||
import type { BoardFx } from "./fx";
|
||||
import { colorIndexOf as sharedColorIndex, wizardColor } from "./colors";
|
||||
import { CREATURE_ART, objectArt, TERRAIN_ART, tokenArt } from "./art";
|
||||
import EdgeGlyph from "./EdgeGlyph.svelte";
|
||||
import EdgeGlyph, { type LockState } from "./EdgeGlyph.svelte";
|
||||
import FirewallEdge from "./FirewallEdge.svelte";
|
||||
import IllusionShimmer from "./IllusionShimmer.svelte";
|
||||
import SightTraceOverlay from "./SightTraceOverlay.svelte";
|
||||
@@ -182,22 +183,16 @@
|
||||
|
||||
// FEAR's dread: three spaces in every direction, straight through walls
|
||||
// ("even if walls separate you"), never diagonally — and the maze wraps,
|
||||
// so the diamond continues from the opposite rim. Same measure the
|
||||
// engine's refusal takes.
|
||||
// so the diamond continues from the opposite rim. The engine's own
|
||||
// yardstick, so the aura and the refusal can never disagree.
|
||||
const fearCells = $derived.by(() => {
|
||||
const out = new Set<string>();
|
||||
const W = view.board.width;
|
||||
const H = view.board.height;
|
||||
for (const fp of view.players) {
|
||||
if (!fp.alive) continue;
|
||||
if (!view.sustained.some((e) => e.cardId === "fear" && e.targetId === fp.id)) continue;
|
||||
for (let dx = -3; dx <= 3; dx++) {
|
||||
for (let dy = -3 + Math.abs(dx); dy <= 3 - Math.abs(dx); dy++) {
|
||||
const wx = ((fp.position.x + dx) % W + W) % W;
|
||||
const wy = ((fp.position.y + dy) % H + H) % H;
|
||||
const k = `${wx},${wy}`;
|
||||
if (view.board.cells[k]) out.add(k);
|
||||
}
|
||||
for (const k of Object.keys(view.board.cells)) {
|
||||
const [x, y] = k.split(",").map(Number) as [number, number];
|
||||
if (dreadDistance(view.board, fp.position, { x, y }) <= 3) out.add(k);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
@@ -421,7 +416,7 @@
|
||||
: e.lock === "ajar" ? "unlocked until end of turn" : null}
|
||||
<EdgeGlyph x={e.x} y={e.y} kind={e.kind === "V" ? "V" : "H"}
|
||||
state={e.state === "door" ? "door" : "wall"}
|
||||
lock={(e.lock ?? null) as "removed" | "jammed" | "held" | "ajar" | null}
|
||||
lock={(e.lock ?? null) as LockState | null}
|
||||
title={lockTitle} damage={view.wallDamage[`${e.kind}:${e.x},${e.y}`] ?? 0}
|
||||
onpeek={onEdgePeek} />
|
||||
{/if}
|
||||
@@ -656,7 +651,7 @@
|
||||
{/if}
|
||||
{/each}
|
||||
{/if}
|
||||
<!-- FEAR's bubble: every square within three WALKED spaces (warps count) -->
|
||||
<!-- FEAR's bubble: the three-space diamond, through walls, wrapping the rim -->
|
||||
{#each fearCells as key (key)}
|
||||
{@const bx = Number(key.split(",")[0])}
|
||||
{@const by = Number(key.split(",")[1])}
|
||||
|
||||
Reference in New Issue
Block a user