Inspiration
I wanted to make a match-3 game that felt physical: less like moving sweets around a grid and more like bringing down a mine. That idea became Boulder Bash - a game of rock, dynamite, pickaxes, buried ore, ice, fossils, spreading water and rising lava.
The familiar match-3 foundation makes it immediately playable, but the mining theme changes how every action reads. A match breaks stone. A cascade becomes a cave-in. A special-piece combination feels like setting off a chain of charges underground.
What it does
Boulder Bash is a portrait mobile puzzle game with 100 levels across five distinct digs: Mountain Mine, Arctic Dig, Fossil Beds, Sunken Trench and Volcano.
Players match coloured boulders, collect ore and excavate fossils while dealing with cracked rock, ice, chains, water and lava. Four crafted special pieces - Dynamite, the Dynamite Crate, Pickaxe and Colour Charge - can be combined in ten different ways. Those combinations include 5×5 blasts, three-cell-wide crosses, targeted explosions and a full-board clear. Chain reactions are deliberately uncapped because they are the most satisfying part of the game.
Progression includes one-to-three-star scores, coins, five regenerating lives, pre-level boosters, two aimed rescue tools, 48 achievements and optional Google Play Games cloud saves. There is no Boulder Bash account, and the complete game remains playable offline.
How I built it
The app is built with Flutter and Flame. Flutter handles the home screen, map, menus, settings and store; Flame renders the board and its animation layer.
The rules live in a separate pure-Dart engine with no Flutter or Flame dependency. Given the same level, random seed and moves, it produces the same result and the same ordered event stream. The renderer does not inspect game state halfway through an animation; it replays events such as swaps, clears, falls, special triggers and hazards. That separation made complex chain reactions testable without a screen.
Levels are data-driven JSON rather than hard-coded scenes. I built a solver that plays every board hundreds of times, then used its results to tune goal counts and star thresholds. Each normal level targets a measured 40–70% win-rate band, while tutorial levels deliberately run easier. The same measurement approach exposed mechanics that looked interesting but barely affected play, and helped rebalance them before launch.
RevenueCat powers the one-time Remove Ads purchase and its entitlement. The wider monetization design combines carefully paced interstitials with optional rewarded videos, while keeping all in-game currency earnable through play.
Challenges
The hardest technical problem was keeping a long animated cascade visually identical to the deterministic engine underneath it. Small omissions in an event such as a new piece identity or the final state of a shuffled board could make the animation drift even though the rules were correct. Treating the event stream as an API, and testing the rendered board against the engine after complete games, made those bugs reproducible.
Balancing 100 levels was the other large challenge. Intuition was not enough: an obstacle could look dangerous while having almost no measurable effect, and a mathematically fair level could still be too short to be fun. The solver, mechanic-removal comparisons and real playtesting became complementary tools rather than substitutes for one another.
Shipping also meant solving the unglamorous product work: billing, purchase restoration, cloud-save reconciliation, consent-aware analytics, age-appropriate advertising routes, accessibility, real-device performance and store review. Those systems had to fail safely without stopping an offline puzzle game from opening.
What I learned
The biggest lesson was to measure assumptions without designing only for the metric. Simulation can prove that a board is beatable and expose a useless mechanic, but it cannot decide whether a move feels good. Real-device playtesting found visual, pacing and onboarding problems that every automated test missed - I estimate I've played the game for at least 50 hours through testing and making sure it plays well and feels good.
I also learned that monetization is part of the interaction design. The best version was not the one with the most purchase surfaces. It was the one whose rules a player could understand: one permanent purchase, optional rewards, no paid currency and no advert during a move.
What's next
The Android app is live on Google Play, with IOS currently in review. Next I plan to use launch analytics and player feedback to refine difficult levels and onboarding, finish the iOS release, and expand the mine with new modes and levels without compromising offline play or the measured difficulty curve.
Built With
- appodeal
- codemagic
- dart
- firebase
- flame
- flutter
- google-play
- google-play-games-services
- revenuecat
- unity-ads
Log in or sign up for Devpost to join the conversation.