How live scoring works
What happens between a goal going in and your total changing — match windows, per-fixture scoring, and why live and final must mean the same thing.
The single worst experience in fantasy football is watching your total change after the games have finished. You end the weekend on 71, come back on Tuesday, and you are on 66 with no explanation.
Avoiding that is mostly an engineering problem, and it shaped a lot of how ours is built.
One engine, two moments
The core rule we hold ourselves to: live and final must mean the same thing.
That sounds obvious. It is easy to get wrong, because the natural implementation is two code paths — a fast approximate one for live updates, and a careful authoritative one for finalisation. The moment those two paths exist, they drift, and your total changes on Tuesday.
So there is one scoring engine. It is a pure function: given a player’s statistics for a fixture and the league’s rules, it returns points and a per-rule breakdown. The live path and the final path call the same function over the same data. The number you watch is the number you get.
Polling only when football is on
A naive implementation polls the data provider constantly while a gameweek is open. A gameweek is “open” for several days, most of which contain no football at all.
Instead we compute match windows from the fixture calendar — a window around each kickoff — and poll only inside them. Outside a window, zero external requests. Within one, a cheap status check first, and the expensive per-player statistics call only for fixtures actually in play, just finished, or finished but never captured.
That last case matters: it means a missed window self-heals rather than leaving a gameweek permanently wrong.
Per fixture, not per gameweek
Everything resolves per fixture, and this is more consequential than it looks.
Conditions are evaluated against a single match’s statistics. Milestones are measured within one match. Bonus is ranked across one fixture’s players.
In a double gameweek, a player’s two matches are scored independently and added. A condition can hold in one and fail in the other. A milestone can be cleared twice. Aggregating to gameweek level first would quietly get all three wrong, and the errors would be invisible — plausible numbers, subtly incorrect.
Provisional bonus
Bonus ranks all players in a fixture against each other, so while a match is in play the ranking genuinely moves. A defender leading on BPS at 70 minutes can be overtaken by a substitute’s goal.
We show it, label it provisional, and let it settle at full time. The alternative — hiding it until the whistle — is less honest, not more.
Substitutions wait
Automatic substitutions and vice-captain promotion are resolved only at finalisation, not provisionally mid-gameweek.
This is a deliberate asymmetry. Provisionally auto-subbing a starter who has not kicked off yet would inflate your live total with points from a substitution that has not happened and probably will not. The live number stays conservative and true; the substitution applies when the gameweek is genuinely over.
Finishing a gameweek
A gameweek stays live until its last fixture finishes — which, given fixtures spread across several days, is often long after the first. It completes only when every match is done.
Before completion, closing statistics are captured for each finished fixture. This picks up two things: stoppage-time events that a mid-match poll might have missed, and post-match corrections from the data provider, which are more common than you would like. If that capture fails, the gameweek is held open and retried rather than frozen with incomplete data.
There is also an hourly database-only sweep that catches any gameweek stuck in a live state, so a missed window can never leave one hanging indefinitely.
Show the working
Every point traces back to a named rule and a raw statistic. The per-player breakdown lists every scoring category your league has — including the ones that paid zero, and including rules suppressed by a condition, annotated as such with the raw value still visible.
Fantasy football generates enough arguments without the scoring being a black box. When someone asks why a player only got six, the answer should be on screen rather than in a support ticket.
Read more about live scoring, or start a league.