From 29025f2ccba70d274f85f3891200504865250d9e Mon Sep 17 00:00:00 2001 From: Eric Wagoner Date: Fri, 30 Oct 2026 18:01:04 -0400 Subject: [PATCH] A rejoin's replayed chronicle replaces the one the table already holds When a socket dropped and came back, the server sent the whole chronicle again and the client appended it, so every turn was counted twice and the instant-replay eyes asked for turns the server had not reached ("no such turn yet"). The talk count doubled the same way and never reset between rooms; it now resets with the chronicle. Co-Authored-By: Claude Opus 5.5 --- packages/web/src/net.svelte.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/web/src/net.svelte.ts b/packages/web/src/net.svelte.ts index ced9c7f..2a72ca6 100644 --- a/packages/web/src/net.svelte.ts +++ b/packages/web/src/net.svelte.ts @@ -640,6 +640,11 @@ class Net { break; case "events": { let talk = 0; + // A replay is the whole chronicle from the deal, sent on every + // (re)join: it replaces what we hold, or a dropped socket's return + // would count each turn (and each line of talk) twice and the eyes + // would ask for turns the server has not reached. + if (msg.replayed) this.resetChronicle(); if (!msg.replayed) this.onFx?.(msg.events as GameEvent[]); for (const e of msg.events as GameEvent[]) { if (e.type === "tableTalk") { talk++; this.lastTalkBy = e.player; } @@ -1085,6 +1090,7 @@ class Net { private resetChronicle(): void { this.log = []; this.turnCounter = -1; + this.chatCount = 0; } /** Summon one turn's reel by its chronicle turn number. */