One function for game-over

Moving the Daily challenge game-over lifecycle out of a reactive effect and into one function with a fixed order, delivered through an umbrella branch.

When a Daily challenge game ended, one reactive effect did most of the work: it recorded the attempt as the day’s result, updated the streak and the all-time best, synced a signed-in account, decided whether the score was submitted automatically, and scheduled the notify-hour update. The guard against recording a game twice was a flag local to the page. A past bug, since fixed, had come from the effect reading its own prior write, which made the recap show the wrong best-of-day framing. This change moved the whole lifecycle behind one function.

A fixed order behind a small interface#

The function takes the finished game’s state and log, the attempt’s submission status, the current time, and the storage and account sync it needs. It then does four things in a fixed order: it builds the day’s result, records the attempt exactly once, syncs the account, and returns the facts the recap needs along with whether the score should be submitted automatically. The page keeps everything the player sees and everything that touches the network. The function records each attempt at most once. A reset runs when a new attempt starts, so the recording guard lives in one place rather than in a flag on the page.

The fixed order is the part that matters. The recap has to compare the finished game against what was stored before that attempt, and the ordering that makes that true was previously spread across an effect where an edit could easily break it. Putting it in one function makes the order something a test can assert.

The change was checked against the existing completion tests, which pass without modification, and sixteen new tests cover the module. The whole suite passed at 3,220 tests across 257 files.

An umbrella branch for the work#

The work went onto an umbrella branch, with each constituent ticket as its own pull request targeting that branch rather than main. Only a human merges the umbrella into main.

Where this leaves the all-time best#

The all-time best this function records is the value an earlier post caught in review before merge: stored and tested, but invisible to the player until the headline showed it. This change only touches how that value is recorded. What it adds is a single place where the order of recording, syncing and deciding is fixed. The record-once guard now belongs to the completion module rather than the page, so new logic on the game-over path goes behind it.