Commit Graph
555 Commits
Author SHA1 Message Date
Eric WagonerandClaude Fable 5.1 c79fdb4adb The collection is Kestrel's Hall
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-23 19:51:06 -04:00
Eric WagonerandClaude Fable 5.1 9d087ccaa1 The front page and the about page point to the other games of the Kestrel's Nest
The list is the kit's family.json, shipped as /family.json and refreshed
at deploy when the kit is beside this checkout.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-23 12:26:49 -04:00
Eric WagonerandClaude Fable 5.1 13a6fc2603 The host may let the Peanut Gallery talk
A gallery line wears the eye and a name that no wizard at the table
holds; the host opens or hushes it from the lobby or the mast, on the
ledger, and the gallery is reined per address.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-23 09:47:26 -04:00
Eric WagonerandClaude Fable 5.1 f68b3cef06 The desk's replies no longer ring the bell: reports and players' answers do, the desk's own mail does not
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-23 08:54:08 -04:00
Eric WagonerandClaude Fable 5.1 35d805fda3 The lobby tells a caller what hour it is where the keeper lives, and that other games can go on in another tab
WIZWAR_KEEPER_TZ names the zone (Eastern by default); the room carries it
and the client words the hour by the minute.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-23 08:49:37 -04:00
Eric WagonerandClaude Fable 5.1 31bfcf7bc0 Rev 26: BUTT-HEAD's ram is priced into the blow, so STRENGTH, AMPLIFY, and the counters weigh it (KWUZ)
Ramses cast STRENGTH, then an amplified BUTT-HEAD three squares off, and
the goat dealt three: the ram was applied in onResolved, past the pipe
that doubles, soaks, and adds. Older games keep the bare distance.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-23 08:16:30 -04:00
Eric WagonerandClaude Fable 5.1 5193b12b8e Rev 25: a bush or the ooze is attacked like a wall — POWER ATTACK counts, thrown weapons land at its foot
Older games took neither; both sides pinned.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-22 12:19:15 -04:00
Eric WagonerandClaude Fable 5.1 66b5c06f17 Credibility pass: one teleport step, one bell, one step type, and the comments that argued are gone
Since 6e49fc9. Engine: the teleport BFS in the view and the engine's
wallIgnoringDistance share teleportStep; the counter trail is weighed
between steps instead of on six arms; the bush attack takes its
adjacency from SIDES like the wall does; a dead redirected clause, a
one-member set, an identity ternary, and a stray try/catch are gone;
two tests now assert what their names promise. Server: KEEPER and
MAX_SEATS live in rooms.ts, the three Sentry bells ring through one
helper, the unread reply field is dropped, actingSeat comes from the
engine, and the protocol header names every message. Web: ReplayStep
is one type, cardName one helper, the say box and the reference section
one snippet each, the keeper's name arrives from the server rather than
the source, and the lifesaver ruling that ruled nothing is out.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-22 09:56:49 -04:00
Eric WagonerandClaude Fable 5.1 c4a555f8df Fuller banter pools, and the blow's own names decide who dealt pain and who killed
Damage lands on the defender's step, so a trigger keyed to the actor
never credited the attacker: across thirty three-bot games the kill line
fired zero times and the dealt-pain line five, against 328 takes. Both
now read the attackResolved, punched, and died events themselves.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-22 09:39:05 -04:00
Eric WagonerandClaude Fable 5.1 be96dd6047 The archmage cuts off a winning delivery and aims at the leader when no kill is on the table
Reuben's three wins today were walked home unseen: the clockwork
fought whoever stood in front of it. Now a delivery that would end the
game pulls every automaton toward that wizard's home (where the banked
gold is lifted off the doorstep) or the road to it, and among visible
targets the thief still dies first, a kill is still taken, and only then
does the aim shift to whoever has more treasures banked. Measured with
deploy/brain-trial.mjs, which seats the working tree's brain against an
older checkout's at one table.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-22 09:11:34 -04:00
Eric WagonerandClaude Fable 5.1 1b18dffd28 sentry-slack-alert.sh parses again
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-21 15:26:42 -04:00
Eric WagonerandClaude Fable 5.1 46c345dff4 deploy/sentry-slack-alert.sh routes every wizwar issue to a Slack channel, token from the shell
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-21 15:18:08 -04:00
Eric WagonerandClaude Fable 5.1 11e9f950c6 Reports are threads, and every turn of one rings the desk's bell
A player answers the desk under its reply from their lobby, proven by
the seat the report was filed from; the lobby shows the exchange in
order and says whose word is pending. A new report, a player's answer,
and a desk reply each raise a Sentry issue on the keeper's phone — the
first two from the server, the last from the reply script itself,
straight to Sentry from the droplet. The Desktop digest lists the
answers, and the desk's rule reads a report as reopened when the last
word is the player's.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-21 12:08:55 -04:00
Eric WagonerandClaude Fable 5.1 ffbca5bfb9 deploy/pull-feedback.sh mirrors reports, replies, and screenshots to the Desktop with a digest
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-21 11:11:42 -04:00
Eric WagonerandClaude Fable 5.1 071e7ce988 A permanent spell settles 'for good' in the chronicle and the receipt, not for a billion turns
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-21 11:09:01 -04:00
Eric WagonerandClaude Fable 5.1 48350a3686 A report may carry a screenshot
The 🐞 form takes a picture beside its words — PNG, JPEG, or WebP, under
2.5 MB, previewed before sending. The socket's message cap is far too
small for one, so the picture goes through a plain HTTP door after the
report is filed, addressed to the report's id, one per report within
the hour, checked by its own first bytes, and kept in feedback-images/
beside the reports with a line on the report saying so. The desk's
skill knows where to look.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-21 11:02:59 -04:00
Eric WagonerandClaude Fable 5.1 d76a18d5e6 A seated wizard leaves the room's expected list, live and on rebuild
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 23:45:36 -04:00
Eric WagonerandClaude Fable 5.1 1ebd6dbe47 A refused seat is logged, and the wallet drops a seat only on the second refusal in a row
A lost seat mid-game is the costliest quiet failure this table has: one
refusal around a restart cost Kestrel PRPM's seat with nothing in the
journal to say why.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 23:22:00 -04:00
Eric WagonerandClaude Fable 5.1 f738957100 Rev 24: a REFLECTION against a permanent curse afflicts both wizards
"If this spell is REFLECTed, both players take 1/2 point of damage per
space moved" (WALKING DEAD); "In case of REFLECTION, both players are
affected" (IDIOT); SLOW DEATH follows REFLECTION's own rule that a
spell works for both parties. A permanent curse has no duration for
the reflection's split to halve, so the caster went untouched; the
curse is now laid on them as well, as if cast back. Older games replay
as they were; PRPM, reflected at seq 108 with no move since, was
re-stamped to 24 at its table's request.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 23:07:41 -04:00
Eric WagonerandClaude Fable 5.1 f26893f45b The reel measures its padding inside its width, so it stays within the share page on a phone
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 21:18:35 -04:00
Eric WagonerandClaude Fable 5.1 942e04c821 The reel fits a phone: title on its own line, a smaller caption, controls that stay on screen
The shared replay page had no rules for a narrow screen: the reel's
header stacked into a column, the caption ran large, and the controls
ran off the right edge. Under 640px the title takes its own line with
the count and buttons beneath, the caption reads smaller, and the
controls wrap. The share page also pins its text size against
Safari's inflation.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 21:11:48 -04:00
Eric WagonerandClaude Fable 5.1 11dff428f4 The leading casting panel sizes to its card instead of scrolling inside a sliver
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 20:49:55 -04:00
Eric WagonerandClaude Fable 5.1 1019cb5a38 The casting panel leads the right column, and a number's movement button sits in the dock
On a laptop the right column scrolls in place, and the turn banner,
the coaching, and the scoresheet pushed the casting panel — where an
attack is answered and a number is played for movement — below the
fold, showing as a sliver. The panel now leads the column while a card
is aimed or a blow answered, and a number's "Play for +N movement"
also stands in the dock beneath the board.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 20:48:47 -04:00
Eric WagonerandClaude Fable 5.1 e6ede1aa48 The pulse reads a challenge issue as a caller, not an error
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 00:56:06 -04:00
Eric WagonerandClaude Fable 5.1 ba1d1d297f The keeper's bell rings at error level, so Sentry files it as high priority and alerts
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 00:36:51 -04:00
Eric WagonerandClaude Fable 5.1 3c10e0463f The raven sets expectations; Create and Join say so when the table is not yet reached
The lobby tells a challenger what to expect in the table's own voice:
the keeper answers every raven, sometimes within the minute, sometimes
after a night's sleep; the seat is held either way, and the table is
theirs meanwhile. A Create or Join tried before the socket is open
used to vanish; it now says the table is still being reached.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 00:34:45 -04:00
Eric WagonerandClaude Fable 5.1 1be1cf7d1b A lobby may challenge the keeper, and the table can talk before the boards flip
"Challenge Kestrel, the keeper" holds a seat under the keeper's name,
writes the call to the ledger, says so at the table, and raises a
Sentry issue fingerprinted to the room — one ring per call, with the
room's link in the message — which is the alarm the keeper's phone
listens for. The keeper answers by the link: taking the seat, and
leaving a word if the game must wait. For that word, and for any table
to settle when to start, the lobby now shows its talk and carries a
composer; a joiner sees what was said before they sat. Three calls per
address per hour, one per room.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 00:30:49 -04:00
Eric WagonerandClaude Fable 5.1 de279364ce The table-talk count is reactive, so your own words never show as unread
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 00:25:07 -04:00
Eric WagonerandClaude Fable 5.1 8582b7feb7 What you missed, in facts; a timeline on the reel; room for table talk
A returning player's slip now lists what happened while they were away
— "Automaton took your treasure.", "You lost 3 life.", "It's your
turn." — each fact opening the catch-up reel at its moment, read from
the missed steps as the server redacted them for that seat; when
nothing touched them it says what each wizard was up to instead. The
reel gains a timeline: a tick per move in the mover's color, taller
where a turn begins, a blow lands, or gold changes hands, and any tick
jumps the reel there.

The chronicle takes a filter — All, Game, Table talk — with an unread
count on the talk that arrived while the casting panel covered it (a
wizard's own words never count), a peek at the latest line above the
composer while the panel is up, and the composer itself no longer
leaves when a response is owed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 00:22:54 -04:00
Eric WagonerandClaude Fable 5.1 80dd7a7865 Rev 23: POWER DRAIN drains the number played; the troll punches walls; the first-person stack fits
POWER DRAIN's gain is the number played, BLUNTed or ABSORBed or not
(FAQ: the counter blunts the damage done, not the drain), and a wall
drained for its points gives them up too. Older games gave only what
the opponent lost and nothing from a wall, and replay so.

"This rock-hard beast can punch a player (or a wall, etc.)": a commanded
troll now punches a wall line beside it for a D4, once a turn — a new
command, so no old game changes.

Under the first-person pane the board strip could run into the dock on
a short or tall window; the pane now takes no more height than the row
can spare and the strip shrinks beneath it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-17 00:07:34 -04:00
Eric WagonerandClaude Fable 5.1 803c51415e Rev 22: TELEPORT crosses the maze's outer edge anywhere
A teleporter ignores walls, and the outer edge is no more than a wall
to it: a line leaving the maze at any square's edge re-enters at the
opposite edge on the same row or column, one space on. The lettered
openings connect as they always did. Older games crossed the edge only
at the openings, and replay so; U3U2, dealt at rev 21 with no teleport
yet cast, was re-stamped to 22 at its table's request.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-16 23:56:13 -04:00
Eric WagonerandClaude Fable 5.1 7a6aa3d2a1 View controls above the board, decisions below it, the account beside it
The board's controls had three homes: zoom in the corner, the eyes
toggle floating above it, and the turn's actions wrapping into rows
beneath. Now a toolbar hugs the board's top — First-person at the
left; − · level · + · Fit at the right — and a dock sits beneath it in
three groups: what the square offers, the tools (punch a wall, hints,
discard) set quieter, and draw beside End turn pinned at the right.
While a card is aimed the dock leads with the decision in a line —
"Choose a destination · lit squares are within 4 · ends your movement"
— and a cancel, so the lit squares always say what they mean. The
panel beside the board keeps the card and the full account, now with
the instruction first and discarding demoted to a quiet last resort.
A phone keeps the offers and End turn in view and its tools behind
More. With the hand at the left, the columns grow with the cards so
they no longer overlap.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-16 23:47:10 -04:00
Eric WagonerandClaude Fable 5.1 648f6ab8cd Receipts under resolved attacks; the cast line clears; the table holds still; teleport wraps
Each resolved attack now folds a receipt under its line, read off the
engine's own record: the blow as it came in, what each counter left of
it in the order they were weighed, what landed, and whose life moved.
The resolution event carries the incoming damage and duration and the
trail of counters for it. Hotseat chronicles carry the same.

The line a cast was accepted on stayed on the board: its timer compared
a reactive proxy to the object it held. Kept raw, it clears.

The board jumped while walking. The "sending" note added a line beside
End turn and took it away again, and the refusal toast stood in the
flow above the table for five seconds; both now float and move
nothing.

Teleport reaches through the lettered openings in the engine, but the
board dimmed the squares beyond them. The eligibility map follows the
warps as the engine does.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-16 23:32:34 -04:00
Eric WagonerandClaude Fable 5.1 7d0c1c68a3 A cast that resolved at once draws the sight line it was accepted on
The attack on the stack has always shown its line; a creation or a
curse resolved in the same breath showed nothing, so a legal aim
through a Visionstone and out a lettered opening (PPL7, move 309)
looked like a cheat. The line a cast was accepted on — plain, through
the one wall a VISIONSTONE dissolves, or AROUND THE CORNER's two legs —
now draws on the live board for a few seconds and on that move of any
reel, traced after the fact so the cast's own dust cloud cannot blind it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-16 23:05:32 -04:00
Eric WagonerandClaude Fable 5.1 12a655868b The table says when it is out of reach, a finished table can call a rematch, and spells and treasure read plainly
Connection: while the socket is down a notice says so, the hand, board,
and action buttons go quiet, a card left selected stays selected, and
table talk stays in its box. A command that could not leave is named
as not sent; one that left before the drop is named as unconfirmed
until the board answers. A command on its way shows as sending beside
End turn and confirms when the table replies. Talk shows as sending
until the table echoes it, and comes back to the composer if the
socket drops first.

Rematch: anyone at a finished table may call one. The server makes a
new room hosted by the caller, with the same clockwork at the same
tiers and moods (a mystery stays a mystery) and the same expansion
setting, and keeps seats for the last table's other wizards, who find
the call on the finished table and in their lobby ledger and sit with
one click. The old table's replay stays where it was. A solo table
against the clockwork keeps "play again".

Reading the table: an ongoing spell's chip opens its card with a plain
account — what it does, who cast it on whom, and when it ends, in the
rulebook's own terms. Each score row counts the treasures a wizard has
carried home, and marks a wizard one carry from winning.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-16 22:52:55 -04:00
Eric WagonerandClaude Fable 5.1 bc99ee3eb7 Attacks aimed at a bush or the ooze: five points clear the square
A THORNBUSH or ROSEBUSH "will be destroyed" by five points of damage,
and the FAQ lets only fire hurt a KILLER OOZE; the table refused every
attack aimed at one. An attack tapped onto a bush or ooze now lands on
it, the damage accumulating across attackers and turns, and the
fifth point clears the square. A WIZARDBLADE is swung from the square
beside it, as its text asks of a target that fills a square.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-16 22:35:01 -04:00
Eric WagonerandClaude Fable 5.1 23b4a7675e The lobby's outer computer button says "Hide computer options" while its panel is open
So it reads apart from the Add button inside the panel.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-16 22:26:11 -04:00
Eric WagonerandClaude Fable 5.1 f7991ee64f The lobby is a table being assembled
"Gather your wizards" leads, with the room code and the seat count
beneath it. The roster is the picture: each seat's portrait, name, and
role, an empty seat showing what fills it, and beneath it the two ways
to fill one — copy the invite link, add a computer wizard — with the
raw URL folded away for pasting by hand. Your own row carries the
wizard picker, a deliberate three-by-two with a check on the chosen
one, open by itself until you have a wizard. Adding a computer wizard
is a panel with difficulty and personality, a line on what the chosen
personality does, and one explicit button. Readiness and Start sit
together at the bottom: "Waiting for one more wizard" above the
button, "Start game · 2 wizards" once it can flip; the expansion
option is nearby and quiet, and abandoning the room is a small link.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-16 22:18:39 -04:00
Eric WagonerandClaude Fable 5.1 9dee01d393 The help becomes a reference desk: searchable, linkable, and it remembers its place
The rules tab is one body — the condensed rules, the rulebook, the
expansion, and the FAQ — with a contents list, a search that labels
each hit by source, and a link on every section. The rulebook's
emphasis renders, and the (6E: …) notes are set apart from the original
words. The card library gains filters for set, type, and target, ranks
an exact name first, counts its results, and says so when there are
none; a card opens as an entry: the card itself beside reading-size
text with the printed wording, deck counts, the official FAQ, this
table's rulings, and links to the cards it names. The house rulings are
organized by card, in the present tense, with the revision history kept
off the page. Every page and card has a link (/?help=rules/…, /?card=…)
that opens the desk to it, and the desk reopens on the tab, search, and
scroll position it was closed at.

About leads with the worn box and the friends, shows the workshops as a
small gallery with a direct link to the demo reel, and says plainly
what an online ledger keeps and what a passed-around device keeps to
itself. The tally leads with finished games, treasure and combat wins,
and hours played, and explains that wizards are counted by name and
table time by the clock between moves.

Escape closes only the foremost layer and returns focus to the card
that opened it; the tabs wrap on a phone instead of clipping.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-16 22:13:44 -04:00
Eric WagonerandClaude Fable 5.1 4c2a253723 The tester's second pass: the rule as written, advice that follows the board, the fold, the story on the replay page, and one click to begin
- Help said "walk, then act"; the rules let moves and cards come in any
  order, and now the help does too.
- The council's advice is derived from the live view while its panel is
  open, so a Number just played for movement is no longer recommended.
  It rests when the turn is not yours; "ask again" had nothing to add.
- The landing puts the name and the ways in before the clip, and beside
  it on a desktop: at 1280x720 the play button and Create/Join are above
  the fold.
- The replay page opens with the same deed the share card promises, and
  "play free" stands beside the reel instead of after the history.
- In hotseat the "pass the device" scrim stood above the roll-off, so the
  first click on "begin" landed on the handoff card. The handoff waits
  for the dice.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-16 21:43:12 -04:00
Eric WagonerandClaude Fable 5.1 3d88f629b7 The face-up hands at game's end keep to their frame and fold away
On a desktop the table is pinned to the window and the board's row may
shrink to nothing; four hands of cards beneath it did exactly that in
room 7S6C, and nothing put them away. The reveal now scrolls inside a
capped frame and its header carries a fold button.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-16 00:36:57 -04:00
Eric WagonerandClaude Fable 5.1 6e49fc9020 Credibility pass: comments say what the code can't, and the seams are gone
Engine: pit-rim exits live in one helper (pitRimExits) shared by the
resolver and the automaton; chargeReach names the six-stride cap; dust
sight is inDust + dustAtEnd; PushPending is exported once; the force-field
counter builds its events in one list; drawUnderSlowDeath says what it
draws under. Test groups are named for the rule they pin, not the
revision that introduced it.

Client: one smoothstep; one edgeScar per battle-scarred edge; one
board-zone rule (which also seats the caption strip on phones); the
compass names live in SIDE_NAMES; net.flash() is the one toast; MediaQuery
replaces two hand-rolled matchMedia listeners; sprites carry their sizes
as plain numbers and their CSS in one rule each; canvas helpers are
formatted like the rest of the tree. Comments that told how a cel or a
fallback used to look now say what it draws. The actions-over notice no
longer blames a pickup when slime ended the turn.

Server and ops: dataRoot() is the one data directory; headlineOf builds
its deeds without a cast; the rollup and skills read the same way the
code behaves.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-16 00:21:34 -04:00
Eric WagonerandClaude Fable 5.1 85690f0e23 Rev 21: LIFESAVER saves, and FORCE FIELD stands for the turn
An audit of every card in the deck, prompted by the Alter Ego, found
two more whose cast worked but whose promise was never kept.
LIFESAVER — "immune to the effects of losing both of your treasures"
— was cast and remembered and never asked where a wizard is
eliminated for exactly that; twenty-three recorded casts never
mattered. FORCE FIELD stopped the spell and vanished, though the card
keeps it standing until the opponent's turn ends, barring them from
entering its caster's square or casting on or past them. Both are
honored from rev 21, the field on every side where the card says one.
Older games replay as they were played. Tests pin both readings.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-15 23:57:38 -04:00
Eric WagonerandClaude Fable 5.1 10d5c5815d The Alter Ego casts from its own square; the first-stride cue leaves the maze
Randy raised his double, selected it, and could cast nothing through
it: the card's whole point — "it may use any of the spells in your
hand, and you need not be in its L.O.S." — had never been wired. A
cast may now name the double, and the double's square becomes the
spell's origin: sight, reach, the launch point the reel films, and
the direction a knockback or rout pushes. The hand, the attack, and
every answer to it stay the caster's. Spells that move the caster's
own body — a goat's charge, a swap — do not travel through it. On the
board, the double's sight lights the eligible squares; selecting the
double and then a card aims from where it stands. A test hides the
caster and fires through the double.

The first-stride caption sat on the maze and hid the walls beside the
wizard; it now stands above the board with a color chip for "you."

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-15 23:38:58 -04:00
Eric WagonerandClaude Fable 5.1 5f58a0955a A notice taller than the screen scrolls inside its frame
Preferences on a phone ran off the bottom with no way to reach the
rest. Every notice now caps at the window's height and scrolls within.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-15 23:29:18 -04:00
Eric WagonerandClaude Fable 5.1 ff35e8ef8e The table fits the window: the hand stays in reach, the maze takes the height
On a desktop the game grid is now exactly the window's height. The
board and the paper rail share the top row, the rail scrolling in
place, and the hand with its End turn sit pinned beneath — nothing a
first turn needs is ever below the fold. The board's window fills
whatever height the row allows instead of a fixed subtraction. A
wide, short window — a laptop in landscape — stands the hand beside
the board on its own until the player chooses a side, since a tall
maze under a bottom hand left a postage stamp. A short window shrinks
the bottom hand's cards a little. The eyes toggle floats over the
board's corner so it costs no height, and the masthead's "invite
friends" hides on phones where it wrapped.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-15 23:19:59 -04:00
Eric WagonerandClaude Fable 5.1 4cc0423846 The first minute, for a stranger: what the game is, what to do, and how to join
The landing says the pitch before it asks for a name — steal treasure,
blast through walls, outwit your friends — and states the goal. The
coach says "select a card, then choose its target," which is what the
cards actually want. The turn banner counts treasures home beside the
moves left. The council speaks once when its three voices agree. A
friend arriving on an invite link meets "Join Eric's game," a name
field, and a seat, with the gallery an afterthought; the masthead
says "invite friends" beside the room code. The first-person view has
a toggle beside the board instead of a checkbox in preferences. How
to play opens with winning. And a shared moment's card is titled by
the turn's story — the treasure carried home, the blow that landed,
the spell cast — instead of whose turn it was.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-15 23:03:17 -04:00
Eric WagonerandClaude Fable 5.1 a071494f4a Reduced motion is honored everywhere the table moves
One shared motion policy: the OS's reduce-motion setting, read live
through Svelte's own media query, folds into the flourishes switch.
Under it the board plays no flourishes, the reel skips its die
interlude and slate wipes, bodies jump between squares instead of
gliding, the canvas holds its ambient shimmers still, and the camera
cuts wherever the director would have panned — in the cockpit as in
the reel, so the eye still lands on what the director chose to watch.
Timers and animation frames are cleared when the policy flips or the
pane closes. A first turn and two reels stepped clean under the
setting with no errors.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-15 22:42:08 -04:00
Eric WagonerandClaude Fable 5.1 65e88df523 The step light is for a first game's first turn, then by choice
It lit every turn of the first game. Now a browser's first game lights
its first turn on its own, and the preference is an explicit switch
that keeps it on every turn for anyone who wants it. The old
preference key retires with it, so nobody is left lit by accident.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-15 22:21:22 -04:00
Eric WagonerandClaude Fable 5.1 53b6b01582 The workshops wear the masthead, with the door marked
The token, flourish, and eyes workshops opened as bare rooms with no
way back. The masthead now heads each, wordmark linking home, with
the table, the clips, and the other workshops a tap away.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-15 13:44:12 -04:00