The Peanut Gallery and table talk

A room's link without a seat is now a place in the gallery: a tokenless
view that withholds any gesture hidden from anyone at the table, counted
for the table and the lobby. Seated wizards can talk; each line is a
ledger line, shown in the rail and in the lobby, and the hall counts
what was said while you were away. The hall's pitch no longer says two
wizards.

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 09:50:06 -04:00
1 parent 75c2dc9241
commit 8e7376d59a
19 files changed
+488 -80

No files matched your search

+14 -3
View File
@@ -3,7 +3,7 @@
// describe those gestures are withheld too. Spells cast are always visible, as
// the rules say.
import { visibleHistory, type GameState, type WizardId } from './state';
import { hiddenFromViewer, visibleHistory, type GameState, type WizardId } from './state';
export function viewFor(state: GameState, viewer: WizardId): GameState {
const view = structuredClone(state);
@@ -11,16 +11,24 @@ export function viewFor(state: GameState, viewer: WizardId): GameState {
if (id === viewer) continue;
view.wizards[id].history = visibleHistory(state, viewer, id);
}
view.log = view.log.filter((l) => !l.hiddenFrom?.includes(viewer));
view.log = view.log.filter((l) => !hiddenFromViewer(l.hiddenFrom, viewer));
return view;
}
/** What a seated player is told by the server. Other seats' moves and tokens never leave it. */
/** One line of table talk. Only seated wizards speak; the gallery listens. */
export interface ChatLine {
id: WizardId;
text: string;
at: number;
}
/** What a seated player, or the gallery, is told by the server. Other seats' moves and tokens never leave it. */
export interface RoomView {
roomId: string;
seq: number;
/** The most seats the table will take. */
size: number;
/** The viewer's seat, or SPECTATOR for the gallery. */
me: WizardId;
/** The wizard who opened the table and may begin the duel. */
host: WizardId;
@@ -28,4 +36,7 @@ export interface RoomView {
/** Seats that still have to move before the turn resolves. */
waitingOn: WizardId[];
state: GameState | null;
chat: ChatLine[];
/** How many watch from the Peanut Gallery. */
audience: number;
}