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>
Each card's players and origin are two lines, the origin a step
smaller. Dip's description is shorter and its players line says "2 to
10, depending on the map". The intro says "start a table" like the list
beneath it, and a line under it points newcomers at Wiz-War. The Waving
Hands picture is re-cropped from the same capture, the grid centered
and the stray edge gone.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The lobby's four-turn grid, captured from the game with each letter
replaced by the game's own hand silhouette, mirrored for the right hand
as the picker draws it. The game itself still writes the grid in letters.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The intro says how to start before the cards. Each card's metadata line
names the house player, the call to action is "Play [Game] →" with the
game's address beneath, and an empty length line waits, hidden, for real
play data. Waving Hands' card shows the lobby's gesture grid instead of
the share card. "How a table works" says Start a table and how a seat
crosses devices, and the credits run in the cards' order. The faint bone
is gone: the metadata lines and the footer use the dimmed bone, 6.5:1
and 7.2:1 where they were 3.7:1 and 4.0:1, and the ko-fi link no longer
wraps.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A deliberate tagline triplet may stay (Wiz-War's), a button may name its
action and its cost, a game may voice a template line its own way, and
the list of load-bearing words grows: client-matched errors, replay
goldens, stored shares, and bot lines told apart by shape. Bots should
not share scaffolding.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
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
From feedback on Waving Hands' BoardGameGeek thread: no label-and-colon
lines or abstract headings around the game; histories read oldest
first; the move and its button stay together and in view; warn before
a wasted move rather than after; let a move be typed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
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
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
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
"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
- 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
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
gamehall/ops holds the traffic counter, the visitors digest and the
nightly rollup, installed by gamehall/deploy.sh; the gamehall-visitors
skill reads them. The hall now sends its origin as referrer, so a game
can tell who came from it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
The landing page was a static page in the blog, served by the Yunohost
box through an nginx drop-in and an SSOwat rule. It now lives in
gamehall/site beside family.json, is served by Caddy on the shared host
with the games (gamehall/gamehall.caddy), and publishes with
gamehall/deploy.sh. Its share image is its own, not the blog's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
The room counts rounds played and sends the count in its view; a page
sends it back with each move, and the server refuses a move whose count
is behind (a slow connection, a second click, a stale tab), or that has
no count at all (an old page, told to reload). Before, such a move was
taken as the move for the next round. Found in Dip's acceptance run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG