PopSkip
A puzzle played on sheets of bubble wrap. You pop one bubble, then jump to the next, and try to clear the whole sheet without trapping yourself.
Free in any modern browser, on a phone or a computer, in nine languages. No ads in the browser. The iPhone and Android apps are in testing.
How to play
- Pop every bubble. Start on any bubble that glints.
- Straight: skip two bubbles and land on the third, up, down, left or right.
- Diagonal: skip one and land on the second.
- You can never land on a bubble you have already popped. The glowing bubbles are the ones you can reach next, but not every one of them leads to a finish.
Undo takes back your last move. Hint shows a safe next move, and when you are already stuck it offers to take you back to a point from which the roll can still be finished.
What is in the game today
- A painted trail that grows chapter by chapter, from a meadow and a forest to lakes and snowy passes. Every roll on it is proven solvable before it ships.
- A daily roll, the same for everyone on a given day; Today’s Climb, one try a day; and a 60-second Sprint.
- Treats earned by playing, spent on undos and hints. In the apps, an optional video earns more.
- A streak, two small goals a day, fourteen badges, and a share card that shows your result without giving away the route.
- Nine languages. Progress stays on your device, and once the game has loaded it plays without a connection.
Having trouble? See PopSkip help.
One rule, a solver that checks every board, and no server
- My role
- Game design, product, architecture
- Built with
- Claude Code and Codex agents I direct
- Stack
- TypeScript, React, canvas, Capacitor
- Runs on
- Browser; iPhone and Android in testing
- Server
- None yet: it all runs on the device
- Hosting
- Azure Static Web Apps, GitHub Actions
- Tests
- 328 unit tests, browser tests in CI
- Languages
- Nine
The problem
PopSkip is meant for a few quiet minutes on a phone, often without a signal. That puts two demands on the software. Every roll has to be finishable, because a player who gets stuck needs to trust that a full solution exists. And help has to be honest: a hint should point to a move that really can still finish the roll, and it has to work offline.
Where each part runs
My part
I designed the game and its rule, and I make the product and architecture calls. The code is written by AI coding agents, Claude Code and OpenAI Codex, working under my direction; I keep responsibility for the architecture, the validation, the tests and what goes to production. Every decision goes into a numbered log with its reasons, more than two hundred of them so far. Changes go through CI, and I play each build on my phone before it ships.
Decisions, and what each one cost
A few of the decisions from that log, with the alternative each one turned down. The first is easier to see than to read:
-
Decision log · D-0044 · D-0095
Hints are proven on the phone, within a fixed budget
- Problem
- Hints have to work offline and at once, but a full search can take too long on a phone in the middle of a game. About one position in nine runs out of budget.
- Decision
- A depth-first search with Warnsdorff ordering, in a Web Worker, capped by a node count rather than a time limit, so every device gives the same answer. Only a proven hint costs anything.
- Turned down
- Hints from a server; charging for a hint that was only a guess.
- Cost
- The game is sometimes openly unsure. I chose that over a hint that is sometimes quietly wrong.
-
Decision log · D-0062 · D-0090 · D-0137 · D-0171
Every board is proven before it ships, and its difficulty is measured
- Problem
- A stuck player must be able to trust that a finish exists, and difficulty has to rise in a way players can feel.
- Decision
- The generators keep a board only if the solver proves a full route. Each roll is rated by how many of 4,000 random games finish it, and the trail is laid out in waves by that measure. The current pack builds rolls as chains, so a route exists by construction.
- Turned down
- Generating boards on the device; rating difficulty by the number of bubbles, which turned out to matter less than the shape.
- Cost
- The rating comes from a bot, not from people, until there is enough play data to check it against.
-
Decision log · D-0058 · D-0034 · D-0214
One rule engine, in plain TypeScript
- Problem
- The rule lives in the game today and will also live on a server that checks scores. Two implementations would drift apart.
- Decision
- game-core is pure TypeScript with no screen, storage or network code, pinned down by shared test fixtures. The server, when it comes, imports the same package.
- Turned down
- A second engine in C# on .NET, which the original plan called for.
- Cost
- It sets aside my usual .NET choice for the server side.
-
Decision log · D-0094 · D-0168 · D-0204
The client is not trusted, and the one exception is written down
- Problem
- Without accounts, everything a player owns lives on the device, and anything on a device can be changed.
- Decision
- A game that used help is flagged and will never rank. The build refuses to ship solution routes: there were 491 in the bundle, now there are none. Rewards for a video are credited on the device as a named exception until there is a server wallet, which brings AdMob’s server-side check with it.
- Cost
- A forged reward is possible today. It harms no one else, and the decision says when it has to end: before anything is sold.
-
Decision log · D-0134
Capacitor, not a native rewrite
- Problem
- The game had to reach iPhone and Android without a second codebase.
- Decision
- The same web build inside a Capacitor shell, with native plugins for video ads, notifications, haptics, sharing and review prompts.
- Turned down
- React Native or Unity, both a rewrite of the board and the screens; a thin web wrapper, which fails Apple’s guideline 4.2 and does not work offline.
- Cost
- WebView speed on mid-range Android, a Mac for every iPhone build, and WebView quirks: sound on iPhone failed until media requests sent a Range header.
-
Decision log · D-0199 · D-0202
Retention measured without identifiers
- Problem
- Launch decisions depend on how many players come back after a day and after a week, but the game has no accounts and I did not want device IDs.
- Decision
- Aptabase, which keeps no device ID or cookie and drops the IP address, plus one event a day that carries the number of days since first play, queued while offline.
- Turned down
- Firebase Analytics.
- Cost
- Counts are per device, and a reinstall looks like a new player.
In numbers
- On the full 10 × 10 sheet, a finishing route is proven from every one of the 100 starting bubbles.
- 4,000 random games are played against every roll to rate its difficulty.
- A year of daily rolls ships inside the game, so the daily works offline.
- 328 unit tests across the rules and the client, and browser tests on every change.
- The sound a new player downloads first went from 10.8 MB to 1.7 MB.
What comes next
- The App Store and Google Play releases. The iPhone app is in TestFlight and the Android app in closed testing.
- A server that replays each move list before any ranking or leaderboard exists, and keeps progress in the cloud.
- New chapters for the trail.
Updated 20 October 2026.