DEV Community

Cover image for I built a mobile game end to end, alone. Here's what that actually took
Muhammed Mubashir
Muhammed Mubashir

Posted on

I built a mobile game end to end, alone. Here's what that actually took

A few months ago UNJAM! was a single question in my notes: who moves first?

Today it's a finished puzzle game on Google Play with 1000 levels across ten themed chapters. I built all of it myself: the game, the levels, the art, the sound, the website and every store asset. This post is about what "end to end" turned out to mean, and the decisions I'd make again.

The game: one rule

Every piece on the board, I call them Jammers, faces a direction. A Jammer can only slide out of the board the way it's facing, and only if nothing is in its path. Tap them in the right order and the board clears. Tap one that's blocked and you lose a heart. Three hearts per level, no timer.

That's the whole rulebook. The first three levels are hand-made to teach it without a single line of tutorial text.

The engine: Flutter + Flame

I come from Flutter, so the game is a Flame game inside a normal Flutter app. The board, the animations and the particles live in Flame; the menus, the HUD and the dialogs are plain Flutter widgets on top. That split kept the game loop simple and let me build the UI with tools I already knew well.

There are no image assets for the characters. Every Jammer, with its eyes, arrows and moods, is drawn with Canvas in code. Every sound effect is synthesised. That meant no licensing questions, and changing a colour for a new chapter is a one-line change.

The levels: solver first

The decision I'm proudest of is building the solver before the levels.

Removing a Jammer can only free others, never block them. So a board is really a graph of "who is blocked by whom", and it's solvable exactly when that graph has no cycle. A generator creates candidate boards, the solver rejects impossible ones and scores the rest, and the test suite re-proves all 1000 levels on every build.

Because of that, going from 100 levels to 1000 took a weekend, not a year. (I wrote a separate post about the algorithm.)

Ten chapters

A thousand puzzles in a row is a chore. So every 100 levels you enter a new chapter: Twilight, Sunset, Ocean, Forest, Candy, Midnight, Desert, Aurora, Volcano, Galaxy. Each one restyles the background, the board and all the Jammer colours. The rules never change; the place does.

Privacy: nothing to collect

UNJAM! has no ads, no accounts and no internet permission. It physically cannot send data anywhere. That made the privacy policy short, the Play Store Data safety form a single "no data collected", and the code simpler.

The part nobody warns you about

The game was maybe half the work. The other half:

  • a store listing, screenshots for phones and tablets, a feature graphic
  • a privacy policy and terms
  • a website (Astro, in Docker, self-hosted)
  • a promo video, YouTube Shorts and a playable ad

I automated as much as I could. A capture mode in the game records real gameplay, and scripts turn it into screenshots and videos. When I added 900 levels, updating every store asset was one command.

What I learned

  1. The last 20% takes as long as the first 80%. Plan for launch work from day one.
  2. Build the thing that says "no" first. The solver made volume cheap.
  3. Test on small phones early. My first layout broke on a 360-pixel-wide screen.
  4. Decide on privacy up front. Collecting nothing is a feature and less work.
  5. Automate the boring parts. Anything you'll do twice, script.

Try it

UNJAM! is free on Google Play, with no ads: Get it on Google Play

If you play it, I'd love to hear which level stopped you. And if you're building your own first game: ship it. It's worth it.

Top comments (0)