Credibility pass: the collapse loses its scaffolding
Blind reviews over the rev-37..40 features and the gate collapse. The scripted surgery's scars come out: bare brace blocks unwrapped (with one hiding an unreachable scrambleHands), the amputated comment healed, the dead events parameter unthreaded from the illusion-sight chain, the laziness probe in perceivedBoard collapsed to the rule it always produced, GameView.deckRev retired with its last reader, the ward's arming stub told honestly, and every comment or test title still citing the retired revision numbering reworded to the rule it guards. Rim mechanics unify on rimWarpMouth and breachRim; the test suite gains plainRimWall and pushSustained and loses its loop-shaped scars and rev-named helpers. No behavior changes; 255 tests pass unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
8a50ff7f36
commit
4a91d56d24
@@ -208,8 +208,9 @@
|
||||
});
|
||||
|
||||
/** Legal empty slots the lifted sector may land on — mirroring the
|
||||
* engine's relocateSector checks: on the 5-grid, non-negative, vacant,
|
||||
* and leaving every sector adjacent to at least one other. */
|
||||
* engine's relocateSector checks: on the 5-grid, vacant, and leaving
|
||||
* every sector adjacent to at least one other (negative landings are
|
||||
* fine; the maze renormalizes). */
|
||||
const relocateGhosts = $derived.by(() => {
|
||||
if (!view || selectedCard?.cardId !== "relocate-sector" || !pendingSectorOrigin) return null;
|
||||
const origins = view.board.placements.map((p) => p.origin);
|
||||
|
||||
@@ -162,7 +162,6 @@ export function humanize(e: GameEvent): string | null {
|
||||
case "treasurePickedUp": return `${e.player} grabs ${e.owner}'s treasure!`;
|
||||
case "objectDropped": return `${e.player} sets down the ${cardDef(e.card.cardId).name}${e.forced ? " (forced)" : ""}.`;
|
||||
case "objectPickedUp": return `${e.player} picks up the ${cardDef(e.card.cardId).name} — actions over.`;
|
||||
case "wardSet": return e.armed ? "Your ward is set — the next thief bleeds." : "Your ward stands down.";
|
||||
case "chaosShielded": return `${e.player} raises a FULL SHIELD and sits out the chaos.`;
|
||||
case "tableTalk": return `\u{1F4AC} ${e.player}: ${e.text}`;
|
||||
case "dieRolled": return `\u{1F3B2} ${e.player ?? "The maze"} rolls a ${e.roll} — ${e.purpose}.`;
|
||||
@@ -421,7 +420,8 @@ class Net {
|
||||
// A seat the server answered for but did not list is gone — the
|
||||
// room was deleted (or the seat's token voided). Quietly drop it
|
||||
// from the ledger rather than showing "unreachable" forever.
|
||||
// (The server checks at most 50 seats per ask; never prune blind.)
|
||||
// (The server checks at most MAX_MYGAMES_SEATS = 50 per ask;
|
||||
// never prune blind past that cap.)
|
||||
if (this.seats.length <= 50) {
|
||||
const listed = new Set((msg.games as GameSummary[]).map((g) => `${g.roomId}:${g.name}`));
|
||||
const kept = this.seats.filter((s) => listed.has(`${s.roomId}:${s.name}`));
|
||||
|
||||
Reference in New Issue
Block a user