Eric Wagoner and Claude Fable 5.1
979891bdcb
The template's cap on address notes is keyed by the seat's token, so a seat given a new token is noted afresh at once
...
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx
2026-11-10 21:34:45 -05:00
Eric Wagoner and Claude Fable 5.1
210db2d5c3
The template notes a seat's address at most once in ten minutes, so a seat open on two networks writes no line per request
...
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx
2026-11-10 21:32:27 -05:00
Eric Wagoner and Claude Fable 5.1
1a46d611a0
The template's lost-seat search has a limit of its own
...
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx
2026-11-10 21:30:43 -05:00
Eric Wagoner and Claude Fable 5.1
11a206e97d
The template's seat endpoints answer only this site's own pages, in JSON
...
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx
2026-11-10 21:24:21 -05:00
Eric Wagoner and Claude Fable 5.1
e3f8a03215
The template's lost-seat search counts the tables it cannot give back rather than naming them, leaves a seat a bot stands in for to the host, and the keeper's door looks a name up across tables
...
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx
2026-11-10 21:20:27 -05:00
Eric Wagoner and Claude Fable 5.1
dcb18b2b7e
The template banks a browser's seats in a cookie the server sets, and gives a lost seat back by name to the address it was last used from
...
A seat lived in the browser's storage alone, and Safari clears that after a week away, or at a word from the person on another device. Now every seat taken is banked as well in an HttpOnly cookie the server writes, which such clearing leaves alone, and the hall takes its seats back from the bank on arrival. For a browser that lost even the cookie, the ledger notes the address each seat was last used from, as a salted hash, and a name given in the hall or at the table gets its seats back from the same address, with a new token; where the address differs, or two people at the table share it, the table is named so the host can mint a phrase.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx
2026-11-10 21:16:51 -05:00
Eric Wagoner and Claude Fable 5.1
6a9dc5a496
Visits are counted by GoatCounter, the blog's own, as host and path: a table's code never reaches the count, and a page reached without a reload is counted too
...
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx
2026-11-10 19:55:54 -05:00
Eric Wagoner and Claude Opus 5.5
ee7b1d68ec
From Hnefatafl: a link counts as shared when a preview app fetches a page, not when Meta's crawlers or robots.txt checks pass by
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01GwFKMuQnPAEHJ5yA1q4orh
2026-11-06 20:02:52 -05:00
Eric Wagoner and Claude Fable 5.1
c6366853cd
The root address is rewritten to index.html, since try_files passes the root over as a directory and served the shell in place of the hall
...
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
2026-10-29 11:22:35 -04:00
Eric Wagoner and Claude Fable 5.1
647e8cb2bf
The hall's game cards no longer lift on hover or end in "Play X →" and a domain line, and the first game, the one newcomers are pointed at, takes the whole width with its art beside the words, so five games fill the grid without an orphan; the template renders the hall, the rules and the guide at build time behind a fallback named shell.html, and its deploy renders the Caddy site file from the template each time; the family list carries Wyrm and Dip's larger maps; the tally heading and the hosting line are said plainly; and the writing checklist names one sentence shape for a whole list as a tell
...
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
2026-10-29 10:37:40 -04:00
Eric Wagoner and Claude Fable 5.1
75428b5a9b
The template's room server guards a stale room once, by name; the test's tick helper is named for what it waits on; the port list and the hall's tally lose a set that was always empty
...
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx
2026-10-26 22:38:08 -04:00
Eric Wagoner and Claude Fable 5.1
62cb00be33
The template's bots move once the player's request is answered: a slow bot no longer holds up the reply to the move it is answering
...
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx
2026-10-26 17:32:23 -04:00
Eric Wagoner and Claude Fable 5.1
dcd2293b42
The template's lobby reads well with no KEEPER set: challenge the keeper, not the keeper, the keeper
...
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx
2026-10-26 17:20:02 -04:00
Eric Wagoner and Claude Fable 5.1
cbe85d2d31
The template no longer links a favicon.ico it does not ship, which failed a new game's first build at prerender
...
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx
2026-10-26 16:56:18 -04:00
Eric Wagoner and Claude Opus 5.5
e91d209cbe
The keeper can say a word at a table through the keeper's door, signed as the keeper and heard whether or not the gallery may talk, so a call answered too late, after the game began, can still be answered; <slug>-say.sh sends it
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
2026-10-20 13:21:24 -04:00
Eric Wagoner and Claude Opus 5.5
8c37cc5210
The host is asked before beginning while a seat is still held for someone on their way, since the seat goes once the game begins; and the gallery says the game began before they arrived, so whoever was called and finds the table under way knows why there is no seat
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
2026-10-20 13:04:28 -04:00
Eric Wagoner and Claude Opus 5.5
09a8b675ad
The host has a hand on the other seats: once the game begins, Seats makes a transfer phrase for another person's seat, which gives it a new token when claimed, and gives the seat of a player who cannot go on to a bot, which plays the move the seat owes at once and speaks nothing in their name; the person's token opens nothing while it stands in, their page goes to the gallery with the reason and a claim box, and a rematch holds their seat without the stand-in; the server pings every socket and closes one a dead browser left open
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
2026-10-16 19:04:33 -04:00
Eric Wagoner and Claude Opus 5.5
c439c15e36
A seat link replaces a held seat only when the server refuses the held token, not when the connection drops, so a link cannot take a working seat away on a bad connection
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01MbtUPJ24P6vc6tE1x6RS3m
2026-10-13 18:31:36 -04:00
Eric Wagoner and Claude Opus 5.5
7b4080c91f
The keeper's door asks for a key only root and the game's user can read, so another service on the host cannot re-seat anyone; the deploy makes the key once and the reseat script sends it from a file descriptor; and a seat link is taken out of the address bar with the browser's own call, since the page reads it before the router starts
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01MbtUPJ24P6vc6tE1x6RS3m
2026-10-13 18:27:13 -04:00
Eric Wagoner and Claude Opus 5.5
4721b0e97b
A seat a link carries is kept only once the server takes it, and never over a seat this browser holds that still opens, so a link someone else sends cannot take a working seat away
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01MbtUPJ24P6vc6tE1x6RS3m
2026-10-13 18:22:54 -04:00
Eric Wagoner and Claude Opus 5.5
ecab471122
The keeper can bring back a seat a browser lost: a new token on the ledger, the old one refused, and a link that carries it in the fragment, minted by <slug>-reseat.sh through a /keeper door Caddy does not proxy; a spectator at a game in play is told both ways back, and the hall asks before forgetting a game in play
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01MbtUPJ24P6vc6tE1x6RS3m
2026-10-13 18:20:36 -04:00
Eric Wagoner and Claude Opus 5.5
98e61dc756
The hosting line says what it promises: chipping in unlocks nothing, and nothing is held back without it
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01MbtUPJ24P6vc6tE1x6RS3m
2026-10-13 09:23:44 -04:00
Eric Wagoner and Claude Fable 5.1
60435fef84
The hall keeps the night on the shared host: one job runs every game's rollup and backup and checks in with Sentry once for each
...
Eight cron monitors, two per game, watched eight scripts that run on the
same box at the same two minutes. hall-nightly.sh now runs the hall's own
rollup and every game's rollup at 00:12, and every game's backup at 07:23,
finding the games by their scripts in /usr/local/bin, and checks in once
for each job to the gamehall project's hall-rollup and hall-backup
monitors. The template's rollup and backup say by their exit status
whether they managed, the skipped backup included, and its deploy leaves
the game's own cron file off a host the hall schedules.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com >
2026-10-12 10:07:05 -04:00
Eric Wagoner and Claude Opus 5.5
bbbe8ec312
Writing for players: the editing passes' lessons, and the template written by them
...
The conventions gain a list of the habits players read as generated text
(a semicolon in every paragraph, statement-colon-explanation, "The" plus
an abstract noun as a heading, clipped fragments in threes, closing
aphorisms, "X, not Y", the page talking about itself), and of the errors
that come from inherited text: hidden information where there is none,
points where there are none, "both" at a larger table, unchecked claims,
and ledger-stored words reworded. new-game.sh points at the list.
The template follows it: the about link loses 'a labor of love', the
tabs are Origins and Games so far, and the hall, lobby, room, report
slip, table talk, guide and demo board read as Waving Hands' and
Hnefatafl's now do. The landing page and family.json carry the two
games' new taglines and lose their semicolons and the tip jar's aphorism.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
2026-10-11 10:34:08 -04:00
Eric Wagoner and Claude Opus 5.5
f5b7416a9e
From Hnefatafl's second credibility pass: traffic.py parses each request once and counts visits one way, the rollup's check-in has one comment, and the hall's tally drops its leftovers
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01GwFKMuQnPAEHJ5yA1q4orh
2026-10-11 10:18:10 -04:00
Eric Wagoner and Claude Opus 5.5
f0d7237c2b
The rollup and the backup check in once, when they end, with the run's duration
...
A start and a finish sent seconds apart can reach Sentry in either order,
and a start that lands second is never closed, so a fast rollup was
reported as a timeout on nights it succeeded. Hnefatafl's monitor did so
nine nights in fifteen. One check-in at the end cannot race; a run that
hangs sends nothing and is marked missed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01GwFKMuQnPAEHJ5yA1q4orh
2026-10-10 17:44:43 -04:00
Eric Wagoner and Claude Opus 5.5
96ec6861d5
A notice the whole hall shows: hall-announce on the host, served by every game's site, shown at the top of each page
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 13:03:15 -04:00
Eric Wagoner and Claude Opus 5.5
59494aa29f
A settled move may be taken back as a draft while the round still waits on others
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 12:26:32 -04:00
Eric Wagoner and Claude Opus 5.5
60b3c0e60a
A deploy waits for the game server to answer and fails with its journal if it does not; a report id is checked whole; the backup's notes say what it keeps
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 12:25:38 -04:00
Eric Wagoner and Claude Opus 5.5
f78ff3ef8c
The hall puts games in play first for someone coming back, finished ones further down, and reads a game looking up as looking, not unreachable
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 12:25:07 -04:00
Eric Wagoner and Claude Opus 5.5
f131f292ae
A dialog in a short window scrolls within it, the tabbed one stays put as its tabs change, and the report slip closes with Escape
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 12:21:27 -04:00
Eric Wagoner and Claude Opus 5.5
d97d709212
A game may count its own lines from every game begun, not only those finished
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 12:20:03 -04:00
Eric Wagoner and Claude Opus 5.5
403232087d
Bots that play on alone do it at a pace to watch, a round every two seconds after the first few, and a seat may hurry them to the end
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 12:19:38 -04:00
Eric Wagoner and Claude Opus 5.5
99a0b23f59
A game may give its bots words: they speak as a round opens and when spoken to, remember by notes nobody sees, and read the talk when they move
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 12:18:46 -04:00
Eric Wagoner and Claude Opus 5.5
8c99126aee
A table may ask each seat to rank its choices before the deal, in secret; the start line keeps the rankings and create reads them
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 12:17:18 -04:00
Eric Wagoner and Claude Opus 5.5
eca8c92964
Table talk may be private, to the seats named and never the gallery, and a line says the round it was said in
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 12:16:08 -04:00
Eric Wagoner and Claude Opus 5.5
8e35d3a3a6
A seat's view carries its own move in waiting and its move in the last round it played
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 12:15:05 -04:00
Eric Wagoner and Claude Opus 5.5
927e49cf79
A game may take drafts: an input it does not call settled can be replaced, and the round waits for settled ones
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 12:14:33 -04:00
Eric Wagoner and Claude Opus 5.5
6133a2469a
A table's options and its size are read one way, in spec.ts, by the server, the tally and the replay; a game may seat fewer for some options
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 12:13:54 -04:00
Eric Wagoner and Claude Opus 5.5
faa2845e70
A room whose ledger cannot be read is logged and left unloaded, not the server down; the server has tests of its own
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-29 12:13:11 -04:00
Eric Wagoner and Claude Opus 5.5
2810076677
The template's about panel is a TabbedDialog, opened by its address
...
About.svelte goes; #about opens the panel through the router, so it
closes and reopens cleanly and a tab can be linked to.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-28 14:49:39 -04:00
Eric Wagoner and Claude Opus 5.5
c3fca6c5c7
TabbedDialog and the boxed tab strip, as Dip has them; the tally's comment describes the tally
...
TabbedDialog keeps its own backdrop here, since the template has no
shared one; a game that has one may drop it. The template's hall still
opens its about panel with About.svelte.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-28 14:47:11 -04:00
Eric Wagoner and Claude Opus 5.5
6039b6c248
Tabs.svelte: the about panel's strip, shared with long reading pages
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-28 13:52:15 -04:00
Eric Wagoner and Claude Opus 5.5
c55534dbd6
dev:all stops both sides when the server's port is taken
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-28 13:43:15 -04:00
Eric Wagoner and Claude Opus 5.5
cf5af67505
npm run dev:all starts the server and the site together
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-28 12:37:56 -04:00
Eric Wagoner and Claude Opus 5.5
d10c17da9b
The about panel no longer credits its making
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-27 20:58:53 -04:00
Eric Wagoner and Claude Opus 5.5
7207cd9c29
The tally is told as Wiz-War tells it: the game's own story on cards, then the ledgers in detail
...
A few counts that are the game's story (games finished, how they were
won, hours at the table) stand large on cards in the accent color, the
rest follow in a column of figures, then the fine print: Tally.svelte,
shared through the kit, with each game choosing its counts and words.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-27 20:48:05 -04:00
Eric Wagoner and Claude Opus 5.5
813d111bbd
The about panel is a dialog of tabs, as Wiz-War's is, not a wall of text
...
"About this game — a labor of love" opens a dialog with the game, the
tally, more games and a way to send word each on a tab of its own
(About.svelte, shared through the kit), instead of one long fold at the
foot of the hall. Arrow keys walk the tabs; Escape or a click outside
closes it; a link to #about opens it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-27 20:40:39 -04:00
Eric Wagoner and Claude Opus 5.5
ae904aa88c
Traffic counts what matters: rooms opened from the site, where links were shared, scanners and monitors as bots
...
- A room opened with Play now never loads /join: the API's answer to
POST /api/rooms is counted as rooms opened here.
- Link previews (Slack, Discord, Facebook, iMessage, WhatsApp and the
rest) are reported as where the link was shared, since the people who
click them arrive with no referrer. WhatsApp's fetcher is a bot now.
- An address that asks for a scanner's paths, or keeps coming back
without opening a game, is a bot's all day; so is a browser that loads
pages at a steady interval from a new address each time, never
playing. A declared bot is still judged request by request.
- The site's own addresses, sslip.io included, are not referrers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-27 09:59:36 -04:00
Eric Wagoner and Claude Opus 5.5
e521a66f5c
A socket's own error closes that socket, not the server
...
A message over the size limit or a malformed frame raised an error on
the socket, which had no listener, and Node ended the process: one
message from anyone could take the server down until systemd restarted
it. The socket is terminated instead. Messages are capped at 1 KB, since the server never reads them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-27 01:21:44 -04:00