This site used to claim the game had 190 clubs across 10 leagues, 145 event cards and 36 nationalities. Every one of those numbers was true on the day somebody typed it. None of them was true this morning.
The real figures, read straight out of the shipped data: 1,055 clubs, 36 countries with a league of their own and 91 divisions between them, 38 playable birth nations, and 609 written event cards of which 460 carry a decision. The page was understating the game by a factor of five in places.
Why it drifted in one direction
Worth noticing that every error ran the same way. Nothing on the page overstated anything — the drift was uniformly downward, because a landing page is written once, early, when the numbers are small, and then the game keeps growing while the page does not. Nobody re-reads a sentence they wrote themselves to check whether it is still true; they read it to check whether it still sounds right, and "190 clubs" sounds exactly as right at 1,055 as it did at 190.
That is the failure mode worth naming, because it is not laziness and it is not a process gap you can fix by being more careful. It is that the sentence and the fact live in different files, in different languages, edited by different intentions, and nothing connects them.
What we did instead of being more careful
There is now a tool in the simulator package,
tool/site_numbers.dart, whose entire job is to print the
figures this site quotes, computed from the data the game actually ships.
Running it takes a few seconds and prints something like this:
CLUBS total 1055 | invented 105 | real-data 950
LEAGUES countries 36 | divisions 91 | deepest 3 | cups 36
NATIONS playable birth nations 38
CARDS 14 packs | 609 cards | 460 decisions
SHOP 120 items / 5 catalogues
OTHER 55 parent job strings | 8 sponsors
It is the counterpart of the tool that produces the published odds, and the rule is the same: no number goes on this site that a tool cannot print.
The part we deliberately did not automate
The obvious next step is to have the build inject those figures into the HTML, so the page can never be wrong again. We are not going to do that, and the reason is worth stating.
The numbers do not sit in a table. They sit inside sentences — "1,055 clubs that want you, or don't" — and a template that substitutes a variable into prose produces prose nobody reads afterwards. One of the fixes this week was not a number at all: a paragraph listed the six regions the transfer market covered, by name. At 36 countries that sentence had stopped being a list and become a sample, and no amount of interpolation would have noticed. It needed rewriting, by a person, because what changed was the meaning.
So the tool tells the truth and a human writes the sentence. Automating the first half is worth it. Automating the second half is how you end up with a page that is technically accurate and completely dead.
Two ways to miscount, both silent
The measurement tool itself shipped with two bugs, and both are the kind worth remembering because neither produces an error — they produce a plausible number, which is far worse.
The first: the cards were counted by looking for a choices key.
The actual key is choice, singular, and it holds an object
rather than a list. The count came out as zero. A zero in a column of real
figures reads as "this feature does not exist yet", not as "the query is
wrong".
The second: parent jobs are stored as a map keyed by the family's wealth tier. Asking that map for its length gives 4 — the number of tiers — rather than the 55 job descriptions inside it. Four is a completely believable number of anything. It would have gone onto the site unchallenged.
The lesson we are taking is that a tool written to stop numbers rotting has to be checked against a number you already know, at least once. Both bugs were caught only because someone had a rough idea of the right answer and the tool disagreed with it.