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
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
8e35d3a3a6
commit
eca8c92964
@@ -9,8 +9,9 @@ import { cleanOptions, SPECTATOR, tableSize, type GameSpec, type SeatId, type Ta
|
||||
import type { ChatLine, RoomView } from '../../src/lib/net/view';
|
||||
import type { LedgerLine, Store } from './store';
|
||||
|
||||
/** The longest line of talk. A game of long negotiation raises this, and the talk box's maxlength with it. */
|
||||
const CHAT_MAX_LENGTH = 300;
|
||||
/** Lines of talk kept and sent; the ledger keeps them all. */
|
||||
/** Lines of talk kept and sent; the ledger keeps them all. A game that runs for weeks of talk raises this. */
|
||||
const CHAT_KEEP = 200;
|
||||
export { SPECTATOR };
|
||||
|
||||
@@ -394,10 +395,18 @@ export class Rooms<State, Input> {
|
||||
return this.game.settled ? this.game.settled(input as Input) : true;
|
||||
}
|
||||
|
||||
/** Table talk, from a seat to everyone at the table and in the gallery. */
|
||||
say(room: Room<State>, token: string | undefined, raw: unknown): void {
|
||||
/**
|
||||
* Table talk, from a seat: to everyone at the table and in the gallery,
|
||||
* or, naming seats, privately to them alone. A private line is never
|
||||
* shown to anyone else, the gallery included.
|
||||
*/
|
||||
say(room: Room<State>, token: string | undefined, raw: unknown, rawTo?: unknown): void {
|
||||
const seat = this.seatOf(room, token);
|
||||
this.commit(room, { t: 'chat', at: Date.now(), id: seat.id, text: this.cleanTalk(raw) });
|
||||
const to = Array.isArray(rawTo)
|
||||
? [...new Set(rawTo.filter((id): id is SeatId => typeof id === 'string' && id !== seat.id && room.seats.some((s) => s.id === id)))]
|
||||
: [];
|
||||
if (Array.isArray(rawTo) && rawTo.length && !to.length) throw new RoomError('Nobody at this table answers to that.');
|
||||
this.commit(room, { t: 'chat', at: Date.now(), id: seat.id, text: this.cleanTalk(raw), ...(to.length ? { to } : {}) });
|
||||
}
|
||||
|
||||
private cleanTalk(raw: unknown): string {
|
||||
@@ -435,7 +444,8 @@ export class Rooms<State, Input> {
|
||||
state: room.state ? this.game.view(room.state, seatId) : null,
|
||||
yourInput: seated && seatId in room.pending ? room.pending[seatId] : null,
|
||||
yourLastInput: seated && seatId in room.played ? room.played[seatId] : null,
|
||||
chat: room.chat,
|
||||
// Private lines only to their sender and the seats they name; a note is the sender's own memory, never sent.
|
||||
chat: room.chat.filter((line) => !line.to || line.id === seatId || (seated && line.to.includes(seatId))).map(({ note: _, ...line }) => line),
|
||||
audience: this.gallery.get(room.id) ?? 0,
|
||||
galleryTalk: room.galleryTalk,
|
||||
challenge: room.challenge,
|
||||
@@ -522,7 +532,15 @@ 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,
|
||||
...(room.state ? { turn: this.game.turn(room.state) } : {}),
|
||||
...(line.name ? { name: line.name } : {}),
|
||||
...(line.to ? { to: line.to } : {}),
|
||||
...(line.note !== undefined ? { note: line.note } : {})
|
||||
});
|
||||
if (room.chat.length > CHAT_KEEP) room.chat.splice(0, room.chat.length - CHAT_KEEP);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user