Table talk keeps its place in the chronicle

Live chat interleaved correctly, but a reload sank every past message
to the bottom: the rejoin sent the whole game history first and the
chat history after. Talk is now a tableTalk event in the room's event
stream at the moment it was said — the room file already preserved
the interleaving, since chat lines append between command lines — so
rejoining players read the banter between the battle lines where it
happened. The separate chatHistory message retires; unread counting
rides the event stream instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-16 16:00:51 -04:00
co-authored by Claude Fable 5
parent ef661c79ad
commit 5802e1df05
5 changed files with 60 additions and 16 deletions
+9 -12
View File
@@ -145,6 +145,7 @@ export function humanize(e: GameEvent): string | null {
case "objectPickedUp": return `${e.player} picks up the ${cardDef(e.card.cardId).name} — actions over.`;
case "wardSet": return e.armed ? "Your ward is set — the next thief bleeds." : "Your ward stands down.";
case "chaosShielded": return `${e.player} raises a FULL SHIELD and sits out the chaos.`;
case "tableTalk": return `\u{1F4AC} ${e.player}: ${e.text}`;
case "dieRolled": return `\u{1F3B2} ${e.player ?? "The maze"} rolls a ${e.roll}${e.purpose}.`;
case "pushed": return e.player
? `${e.by} shoves ${e.player} down the corridor!`
@@ -320,12 +321,19 @@ class Net {
case "catchUp":
this.catchUp = msg.steps;
break;
case "events":
case "events": {
let talk = 0;
for (const e of msg.events as GameEvent[]) {
if (e.type === "tableTalk") talk++;
const line = humanize(e);
if (line) this.log = [...this.log, line];
}
if (talk > 0) {
this.chatCount += talk;
if (this.roomId) this.markChatSeen();
}
break;
}
case "transferCode":
this.transferCode = { code: msg.code, expiresAt: msg.expiresAt };
break;
@@ -342,17 +350,6 @@ class Net {
if (this.roomId) this.markChatSeen();
break;
}
case "chatHistory": {
this.log = [
...this.log,
...(msg.messages as { player: string; text: string }[]).map(
(m) => `\u{1F4AC} ${m.player}: ${m.text}`,
),
];
this.chatCount = msg.messages.length;
if (this.roomId) this.markChatSeen();
break;
}
case "stats": {
this.stats = msg.stats;
break;