2026-08-29 · 3 min read
The site said v34 of a game that was on v35
The site was a set of files written once and served to everyone. Three separate flaws, all of the same kind: it described something that was no longer true by the time you read it.
Until a few days ago microgames.dev was a set of HTML files written to disk by a generator and served by nginx. Fast, simple, hard to break.
And, on three separate counts, false.
The first: the game pages didn't exist
The showcase has always pointed its cards at /<language>/<slug>/. The generator, though, produced four pages: showcase, projects, studio, devlog. Nobody wrote the individual game pages.
The only game pages on disk were the old ones, without a language, under a different address.
The result: every "Play" button on the showcase returned a 404. The site's one call to action, on every card, led to a page that wasn't there.
This is not a subtle flaw. It's the kind of thing you find in half a second — provided somebody presses the button instead of looking at it.
The second: the numbers were yesterday's
The generator photographed the database at the moment it ran. Between one release and the next, the site kept reporting the version it had been written with.
A game publishes a new version; the site announces an old one; neither of them is doing anything wrong. It's just that one of them is a photograph.
On a site that publishes "version 43" as evidence that a game is alive, saying 42 isn't a detail: it's the very thing you were trying to demonstrate.
The third: you couldn't see anything
No images of the games. Titles and two lines of description. Dark Cell has 1,879 drawn images and the site showed zero.
A list of titles doesn't distinguish a cared-for project from an abandoned one. Anyone arriving had to take the written word for it.
How it works now
Pages are composed when somebody asks for them, reading the database at that moment. Version, state and progress are the ones from now, not from the last regeneration. The game pages, as a live route, are three lines of code; as static files they would be (games × languages) pages to rewrite on every release.
What does not go through here are the game builds: roughly 40 MB each. nginx still serves those from disk, along with posters, clips and sprites. The service composes HTML and nothing else. Pushing 40 MB through an application process would mean tying up a worker for the length of a download.
The old generator wasn't thrown away
And that's the part we care about most.
The static generator is still there, and still runs on every release. Not because it composes the pages, but because it's the safety net: if the service doesn't answer, nginx serves the files from the last regeneration. The site stays up — a few hours stale, but up.
We verified it by stopping the service: the pages kept answering.
A dynamic site that shows a blank page when it falls over has traded a small flaw (stale numbers) for a large one (nothing). Here the worst case is still the small flaw.
What we take away
- "The site is up to date" and "the site was updated" are two different sentences, and the second one ages.
- A button has to be pressed. Looking at it doesn't count as having tried it.
- Old code being replaced isn't always for deleting: sometimes its new job is holding up when the new thing doesn't.