feat(chat): a message to a disguised robot opponent is born read
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 49s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m21s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 49s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m21s
A pooled robot substituted into an ordinary (non-AI) game never opens the chat, so a text message to it would linger unread forever — skewing the unread count and the publish-to-read metric. Clear its recipient bit at PostMessage time (robotRecipients via account.IsRobot), so the message is born read. The human sender never had their own message unread, so this is invisible to them; a nudge to a robot already self-clears when the robot answers by moving.
This commit is contained in:
@@ -524,7 +524,9 @@ disguised robot stays indistinguishable from a person.
|
||||
- **Read receipts**: each `chat_messages` row carries an `unread_seats` bitmask — a set
|
||||
bit per recipient seat that has **not** yet read it (the sender's own bit is never set).
|
||||
A text message seeds the bits of every seated recipient; a nudge seeds only the awaited
|
||||
player's. A seat's bit clears when that player **opens the move history or the chat**
|
||||
player's. A **disguised robot opponent's bit is never set** — it never opens the chat, so
|
||||
a message to it is **born read** (it would otherwise linger unread forever); a nudge to a
|
||||
robot instead clears when the robot answers by moving, as for a human. A seat's bit clears when that player **opens the move history or the chat**
|
||||
(`POST /games/:id/chat/read`, which the client sends only when it holds unread, so a
|
||||
history open is not a constant backend call), and a **nudge additionally clears when its
|
||||
recipient answers by moving** (the move path calls a wired `NudgeClearer`). The mask is
|
||||
|
||||
Reference in New Issue
Block a user