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
This commit is contained in:
Eric WagonerandClaude Opus 5.5 committed 2026-10-20 13:21:24 -04:00
1 parent 21de94869d
commit 82107f73eb
10 files changed
+50 -3

No files matched your search

+6 -1
View File
@@ -229,6 +229,11 @@ export class Rooms<State, Input> {
this.commit(room, { t: 'galleryTalk', at: Date.now(), on, by: seat.id });
}
/** The keeper of the site says a word at a table from the keeper's door, whether or not the gallery may talk: the answer to a call they could not take up. */
keeperSays(room: Room<State>, raw: unknown): void {
this.commit(room, { t: 'chat', at: Date.now(), id: SPECTATOR, name: this.keeper.name, text: this.cleanTalk(raw), keeper: true });
}
/** A word from the Peanut Gallery, when the host allows it: signed with a name no seat holds. */
sayFromGallery(room: Room<State>, rawName: unknown, raw: unknown): void {
if (!room.galleryTalk) throw new RoomError('The gallery listens at this table; the host has not let it talk.', 403);
@@ -599,7 +604,7 @@ export class Rooms<State, Input> {
room.resolved += 1;
break;
case 'chat':
room.chat.push({ id: line.id, text: line.text, at: line.at, ...(line.name ? { name: line.name } : {}) });
room.chat.push({ id: line.id, text: line.text, at: line.at, ...(line.name ? { name: line.name } : {}), ...(line.keeper ? { keeper: true as const } : {}) });
if (room.chat.length > CHAT_KEEP) room.chat.splice(0, room.chat.length - CHAT_KEEP);
break;
}