The first game I shipped was Capital Punishment. One game, one HTML file, one set of decisions about fonts and colors and how the buttons should look. When something was wrong I fixed it. When something looked good I kept it.
By the time Renter's Revenge shipped, there were eight games. Each one has its own aesthetic. Terminal is a CRT monitor running DOS in 1994. Redundancy is a corporate memo printed on beige paper. Renter's Revenge is a brick wall. 25th Amendment is red, white, and blue. They're supposed to feel different from each other.
The problem is they all live on the same site.
The consistency problem
Every game has a nav. Every game has a footer. Every game has a "More Games by Will" link somewhere. Every game that has a leaderboard renders it in roughly the same way. None of this is hard to standardize in theory. In practice, each game was built at a different time, with slightly different decisions, and those decisions compound.
The leaderboard in Renter's Revenge showed entries as chunky bordered cards. The leaderboard in Redundancy used tight dotted rows. Both displayed the same data. One looked like it belonged to a different site entirely. Getting them to match meant auditing every game that had a leaderboard, deciding which pattern was right, and applying it consistently.
The same thing happened with the "More Games" link. Some games had it. Some didn't. Some had it on the title screen, some only on the end screen, some with an emoji, some without. Redundancy was the reference. Every other game got updated to match. That audit is invisible work. Nobody who plays the games will notice it. But it's real work, and it takes time.
The bug that took a month
There's an iOS Safari behavior where tapping a button fires the click handler while your finger is still physically on the screen. New content renders underneath your finger. The next button inherits the active state. It looks like the wrong answer is being selected automatically.
This is not a CSS problem. Removing the active state styles doesn't fix it because the touch is still live. requestAnimationFrame delays don't fix it. pointer-events:none doesn't fix it. All of those address what the button looks like. None of them address the fact that a finger is still on the screen when the new content renders.
The fix is to switch from onclick to touchstart. touchstart fires when the finger lands, so by the time the answer is processed and new content appears, the finger has already lifted. A flag prevents double-firing on devices where the ghost click still comes through anyway.
That took weeks to land on. Not because the fix is complicated, it's about fifteen lines of code. Because every wrong fix looked plausible, worked on desktop, and failed silently on iOS Safari in ways that were hard to reproduce consistently.
Then it had to be applied to every game. Each game had implemented buttons differently. Capital Punishment creates buttons dynamically in a render function. 25th Amendment uses static buttons that get reused every turn. Each pattern needed a slightly different implementation of the same fix. Getting it wrong in one place broke a different game.
What solo development actually looks like
The games look like eight separate things. From the inside they're one thing that keeps getting more complicated to maintain. A decision that makes sense for one game becomes a constraint for the next. A bug in the touch layer affects every game that has buttons. A style choice in the leaderboard has to be reconciled across four different games.
None of this is unique to making browser games without a development background. It's just what happens when you build a collection of anything over time. The individual pieces are manageable. The surface area grows.