Gallery talk, the keeper's bell, rematches, seats that travel by phrase, and seats doubted before dropped

Brought over from the game kit, where they were ported from Wiz-War. The
host may let the Peanut Gallery talk; a watcher signs a name no seat
holds. A seated wizard may challenge Kestrel, the keeper: a seat is held,
the call rings Sentry once per table, and the lobby says what hour it is
where the keeper lives. A finished table may call for a rematch with the
same company and bots, seats held. Transfer seat mints four words good
for ten minutes and one use; the hall claims them. The hall forgets a
held seat only on the second refusal in a row.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
This commit is contained in:
Eric WagonerandClaude Fable 5.1 committed 2026-09-23 12:27:21 -04:00
1 parent 5b169d7131
commit e5c240d970
11 files changed
+576 -32

No files matched your search

+15 -1
View File
@@ -15,11 +15,12 @@ export function viewFor(state: GameState, viewer: WizardId): GameState {
return view;
}
/** One line of table talk. Only seated wizards speak; the gallery listens. */
/** One line of table talk: from a seat, or from the Peanut Gallery when the host allows it (id SPECTATOR, signed with `name`). */
export interface ChatLine {
id: WizardId;
text: string;
at: number;
name?: string;
}
/** What a seated player, or the gallery, is told by the server. Other seats' moves and tokens never leave it. */
@@ -39,4 +40,17 @@ export interface RoomView {
chat: ChatLine[];
/** How many watch from the Peanut Gallery. */
audience: number;
/** The host lets the gallery talk. */
galleryTalk: boolean;
/** The keeper of the site was called to a seat, and by whom. */
challenge: { by: WizardId; at: number } | null;
/** Names with a seat held who have not yet sat: the last table's wizards, or the keeper. */
expected: string[];
/** A finished table's rematch: where it went, and who called. */
rematch: { to: string; by: WizardId } | null;
/** The table this one is the rematch of. */
rematchOf: string | null;
/** The keeper of the site, and where they live, for a table that calls them. */
keeper: string;
keeperZone: string;
}