Credibility pass: sweep the workshop floor
Scoped to everything since the last pass (695307d). The residue of
fast iteration, removed: a reduced-motion media query that had
swallowed a full copy of the .faq-seal rules; doc comments orphaned
from their functions by inserted methods; the FAQ scrape's seams
(section headings run into ruling bodies under the wrong topics, a
next-page heading shipped as a ruling, an amputated "h", and rulings
filed under alphabetically-nearest strangers — Large Rock/Dagger now
lives on those cards; Book of Spells and Torquemada describe no card
in this set and are gone); the write-only aisle flag left behind by
the reverted rev 7; a linter-silenced dead destructure; a duplicated
median lookup; dead casts; and the fallback path that ignored the
apprentice's one-card draw.
Tests now typecheck (tsconfig includes test/), which surfaced the
missing type imports and a drifted creature literal hiding under an
as-cast. Also: a no-op self-assignment, mid-file imports hoisted, a
dynamic-import habit made static, a hedge comment replaced with a
loud setup failure, the fallback-retries-itself dead rung removed
from both bot drivers, and the twin peek scrims merged.
Deliberately kept: the TIERS lookup guard (ledger JSON is untrusted),
the wand-cost stanzas (they differ on the power-attack trade — a
rules question, not a dedup), and rollDie's coexistence with rollD4
(migrating changes visible logs; future work).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
73150a89b5
commit
3308850bb6
@@ -6,9 +6,15 @@
|
||||
import { createHash, randomBytes, randomInt, timingSafeEqual } from "node:crypto";
|
||||
import {
|
||||
applyCommand,
|
||||
automatonCommand,
|
||||
automatonFallback,
|
||||
AUTOMATON_STYLES,
|
||||
AUTOMATON_TIERS,
|
||||
createGame,
|
||||
redactEvent,
|
||||
viewFor,
|
||||
type AutomatonStyle,
|
||||
type AutomatonTier,
|
||||
type Command,
|
||||
type GameEvent,
|
||||
type GameState,
|
||||
@@ -17,14 +23,6 @@ import {
|
||||
} from "@wizwar/engine";
|
||||
import { appendLine, ensureDataDir, readAllRooms, roomFileExists, type RoomLine } from "./store";
|
||||
import { recordRoom } from "./stats";
|
||||
import {
|
||||
automatonCommand,
|
||||
automatonFallback,
|
||||
AUTOMATON_STYLES,
|
||||
AUTOMATON_TIERS,
|
||||
type AutomatonStyle,
|
||||
type AutomatonTier,
|
||||
} from "@wizwar/engine";
|
||||
|
||||
export interface LoggedCommand {
|
||||
seq: number;
|
||||
@@ -289,10 +287,12 @@ export function driveOneAutomaton(room: Room): { seat: PlayerId; events: GameEve
|
||||
if (!seat || !room.bots.has(seat)) return null;
|
||||
const view = viewFor(room.state!, seat);
|
||||
const bot = room.bots.get(seat);
|
||||
const cmd = automatonCommand(view, bot?.style, bot?.tier) ?? automatonFallback(view);
|
||||
let r = runCommand(room, seat, cmd);
|
||||
const chosen = automatonCommand(view, bot?.style, bot?.tier);
|
||||
let r = runCommand(room, seat, chosen ?? automatonFallback(view, bot?.tier));
|
||||
if ("error" in r) {
|
||||
r = runCommand(room, seat, automatonFallback(view));
|
||||
// A refused choice retries with the fallback — unless the fallback IS
|
||||
// what just failed — then burns down the ladder to endTurn and pass.
|
||||
if (chosen) r = runCommand(room, seat, automatonFallback(view, bot?.tier));
|
||||
if ("error" in r) r = runCommand(room, seat, { type: "endTurn", draw: 0 });
|
||||
if ("error" in r) r = runCommand(room, seat, { type: "pass" });
|
||||
if ("error" in r) {
|
||||
@@ -509,6 +509,8 @@ export function loadPersistedRooms(): void {
|
||||
room.bots.set(line.name, {
|
||||
style: (line.style as AutomatonStyle) ?? "hunter",
|
||||
secret: line.secret === true,
|
||||
// Tier-less join lines predate tiers, when every automaton
|
||||
// played the full repertoire — not the "adept" lobby default.
|
||||
tier: (line.tier as AutomatonTier) ?? "archmage",
|
||||
});
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user