Inspiration

I wanted the smallest possible puzzle action to feel physical. Ripples uses a familiar toggle-your-neighbors rule (the Lights Out family), so the question was never “what's the rule?” but “how good can one tap feel, and how deep can a simple rule go?”

What it does

Tap a pool: it flips along with its orthogonal neighbors. Leave the board dry. The campaign spans 10 worlds, with boards growing from 3×3 to 7×7:

  • Barriers: walls block a ripple's spread.
  • Crosscurrents: ripples travel diagonally.
  • Race the Tide: a countdown ring flips a random pool every 3–10 seconds (scaled to board size).
  • Frozen Pools: the first hit cracks the ice, the second drains it; Frozen Tide combines both.

Every wave is seeded, deterministic and verified by a solver for its true minimum move count, so difficulty is real rather than random scrambling. Earn 30 of 48 stars in a world to open the next. The first ten waves are free practice.

The Daily Challenge is one shared puzzle per UTC day: one attempt, no undo, no hints, timed, and ranked on a worldwide Game Center leaderboard. There are 14 Game Center achievements, play streaks, missions, and a hidden “Still Pond” survival mode for the curious.

The board is a canvas. Liquid and Chalkboard are free; Ink, Bloom and Firefly are unlocked with Bubbles earned by playing or bought. Each look changes art, motion and sound, but never the puzzle.

The full game also runs on Apple Watch with the same engine, synced progress, and a play lock so a wave can't run on two devices at once.

How I built it

Native SwiftUI for iPhone, iPad and Apple Watch. A pure-Swift package, RipplesKit, owns rules, topology, a reverse-BFS/GF(2) solver, seeded level generation, scoring and assistance. It is shared by phone and watch and covered by 91 tests in 21 suites. The Liquid board is a Metal metaball shader; other packs have their own renderers and per-pack synthesized audio, with haptics on every tap. RevenueCat powers six consumable IAPs (three Bubbles pouches, three bundles). Bubbles are credited through RevenueCat's In-App Currency and reconciled into the local wallet instead of trusting the purchase callback. Optional rewarded ads (AdMob) sit behind RevenueCat Ads. Progress is local-first with private iCloud (SwiftData + CloudKit) sync; the watch syncs over WatchConnectivity.

Challenges I ran into

Making a chain reaction readable: a ripple has to show exactly what a move caused, in every visual pack. Certifying difficulty on 7×7 boards and variant rules without brute-forcing impossible state spaces. Designing Race the Tide so the timer adds pressure without making boards unsolvable. And making purchases, rewarded ads and two devices agree on one wallet.

Accomplishments that I'm proud of

Every campaign wave has a verified minimum. Five genuinely different ways to feel the same puzzle, with two of them free. A full Apple Watch campaign. An economy where assistance costs you stars, so mastery can't be bought.

What I learned

Polish is game design: if a ripple doesn't show cause and effect, the puzzle gets harder in the wrong way. A solvable level isn't automatically a good teaching sequence. Monetization fits a calm puzzle game best when it funds looks and convenience, not wins.

What's next for Ripples

Watch real players' first minute (time to first solve, mistaken taps, Drops confusion) and tune onboarding and world pacing. After that: new mechanics already sketched (stones, mirror ponds, fog) and more interaction packs.

Built With

  • admob
  • avfoundation
  • cloudkit
  • gamekit
  • ios
  • metal
  • posthog
  • revenuecat
  • storekit
  • swift
  • swift-package-manager
  • swiftdata
  • swiftui
  • watchconnectivity
  • watchkit
  • watchos
Share this project:

Updates

Submission history