One round, one clock
In a room, a phone that sees the start late joins the round in progress with the time that's left, and a phone still playing when the tally is out stops, so the round ends for everyone at the same moment.
Context
A room's round starts on the shared server clock (3.19.7): the host writes a start 4.5s out, and each guest learns of it from a poll every 1.5s. Since 3.19.8 a guest that found less of the countdown left than it expected (more than 2.8s gone) took its clock to be wrong and counted the 4.5s lead from the moment it saw the start instead. That fixed a phone whose sync had measured wrong.
It also caught a phone that was simply late. Ru, after a room game: "some players had the ability to keep playing", and "the aftermath of the game is off". A phone that sees the start late, because the app was in the background through the countdown or the network was slow, got a whole round of its own. It played on after everyone else, and the host, which waits 10s for stragglers before it tallies, sent the results without its last words.
Options
Reproduced with three phones (a host and two guests) on a stand-in for the database, holding one phone's requests the way an iPhone holds them in the background.
| Option | What it does | Result |
|---|---|---|
| As shipped | a start seen late means a wrong clock; count a fresh round | 22s late: that phone played until 64s; the others had results at 56s, without its last words |
| Wait longer for stragglers | the host waits a whole round for a late phone | Weighed, not built: everyone sits on "Collecting words…" while one phone plays a round of its own |
| Trust a synced clock, cap the rest | a synced phone trusts the start however late it sees it and joins with the time left; a phone still playing when the tally is out stops | Built: every phone ends at the same second |
Decision
A phone with a synced clock trusts the room's start as long as the start is no older than the time since it last saw the room before it went live (its last lobby or results read, plus 0.8s for the read that saw it go live). It skips the countdown and plays the time that's left. Only a start that can't be squared with that, or a clock that never synced, falls back to counting from the signal.
Three guards go with it:
- During a live round a guest reads the room's state every 4s (
meta/state, a few bytes). If the tally is out, or the host has started the next round, its round ends: it sends its words and opens the results. - A guest waiting for a tally the host has moved past (Next round deletes the results) follows the room to the lobby instead of waiting for good.
- A room check is a string of reads. One that finishes after the round has begun stops there instead of starting the round again, which reset the words found so far.
The clock also trusts a sync whose round trip is under 4s (it was 2.5s), and a phone that joins just before the start counts as having seen the lobby. Room protocol 3, so every phone in a room runs this.
Evidence
Three phones, a 30s round, on a stand-in database:
| Case | Before (3.25.6) | After |
|---|---|---|
| All on a normal network | all end at the same second | the same |
| One phone 12s late to see the start | it ends 10s after the others | all end at the same second |
| One phone 22s late | it plays until 64s; the others' results at 56s, without its last words | all end at the same second; its words count |
| One phone at 2.5s a request | it ends 8s after the others | all end at the same second |
| One phone late with no clock sync | not run | it stops when the tally is out, 11s after the others |
| Next round, then a second round | — | all back in the lobby; the second round ends together |
| A trivia room, one phone 22s late | — | all end at the same second |
Consequences
- A late phone gets less of the round, never more, and never a round of its own.
- A phone that joins late skips the countdown and opens on the board mid-round.
- Each guest reads a few bytes every 4s during a round.
- A phone whose clock can't be synced still counts from the signal, so it can end up to 10s after the others before the cap stops it.