Inspiration

There's a Turkish idiom, iğneyle kuyu kazmak: "digging a well with a needle." It means doing something enormous with a tool that is absurdly small, slowly, on purpose. Everyone in Turkey knows it. Nobody had ever taken it literally.

So I did. You get a sewing needle. The water is about twelve meters down. Every tap moves you 0.2 mm.

$$\frac{12\,\text{m}}{0.2\,\text{mm/tap}} = 60{,}000 \text{ taps with the needle alone}$$

The joke only works if the game respects it, so the rules came before the code:

  • No ads, no timers, no energy bars, no daily streak to lose.
  • Tools are found, never sold. The earth hands things back: an old coin, a bone, a shard. You trade them for a safety pin (2×), a nail borrowed from a fence (5×), grandmother's good spoon (20×) and, eventually, a bucket that keeps digging while the app is closed.
  • You can buy more ground, never a faster needle.

What it does

Impossible to Dig (İmkansız Kazı in Turkish) is a calm, offline idle/tap game. You dig a well in cross-section through topsoil, clay, gravel and bedrock until the water rises. When it does, you get your depth, your day count, your tap count, and a share card: the whole well as one narrow strip, sky at the top, water at the bottom.

The first well, Old Yard, is free from the first scratch to the last drop. One one-time purchase unlocks the rest of the village, Kuyuköy: four more plots, each with its own ground hardness, its own colour of earth and its own buried keepsakes.

Version 1.2 brings the village to the well:

  • Villagers arrive at the well head as you finish wells. They stretch how long the offline bucket works (8 h → 14 h), but nothing digs faster.
  • A one-line village gossip strip with 63 lines about your layer, your tool and your pace. It never cares whether you came back yesterday.
  • A glitter in the earth every few hundred taps that pulls the next find closer, then pushes the one after back, so the well takes exactly as long as before.
  • Three calendar days a year (grape harvest, first snow, April rain) that change the sky and add a keepsake. Missing one costs nothing.

How I built it

Solo, part-time, native Apple only, no game engine:

  • Swift 6 with strict concurrency, SwiftUI for the UI and SpriteKit for the dig scene
  • Sound generated at runtime: every tool's scratch is synthesized from a resonant band whose centre frequency is the size of the tool. The app ships with no audio files.
  • StoreKit 2 for the one non-consumable purchase, now running through the RevenueCat SDK (StoreKit 2 mode, Current offering → $rc_lifetime package, unlock_all entitlement)
  • Game Center (an optional leaderboard and ten achievements), iCloud key-value sync so two devices keep the same well, a home screen widget, and iPhone + iPad
  • XcodeGen, and a test suite of 419 tests in 64 suites (Swift Testing)

I built it with an AI pair programmer (Claude Code) doing much of the implementation, measurement and verification, while I made the design calls.

RevenueCat, done the offline way

The game promises it works in a basement with no signal. So the integration keeps a strict split:

  • RevenueCat handles the purchase and restore. It buys through the Current offering's package when one is available, so every transaction is tied to the offering on screen.
  • Ownership is still read on-device from Transaction.currentEntitlements. A player who bought the village never needs anyone's server to keep digging in it.
  • With no key, or under XCTest, the plain StoreKit path runs unchanged, so the purchase tests stay deterministic.

Challenges

  • Making slow feel good, not broken. Most of the work was "juice" that adds no power: four tools with four distinct strikes (the needle swings 5° in 130 ms, the spoon swings 12° in 225 ms and brings up a clod the colour of the layer you're in), dust and a layer name when you break into clay or bedrock, finds that fly out of the hole, and a tool that starts to ring after 20 taps in a row without digging any faster.
  • Keeping generosity honest. Every feature had to pass one test: does this let money or grinding outrun real time? The glitter is literally a loan. The taps it pulls forward are booked as a debt and paid back after the next find, and a test proves the find schedule is identical with and without it.
  • Measuring instead of eyeballing. Several bugs were invisible in screenshots. The harvest sky moved the picture by one RGB unit. A sparkle could spawn in the sky above a brand-new well. I only caught these with arithmetic and averaged pixel bands.
  • App Review. An early build was rejected under Guideline 2.3.8 because the home-screen name showed in Turkish on every device. The fix was a per-locale InfoPlist.xcstrings.

What I learned

  • Restraint is a feature. "No streaks, no timers" is not an absence. It is the design, and it has to be defended in every commit.
  • A monetization model can be one sentence: buy more wells, not a faster needle. When the pitch is that honest, the paywall can say so right in its footer.
  • Verify what the player sees, not just what the code does. A strike animation that moved perfectly was still drawing a needle when the player held a spoon.

What's next

More plots and keepsakes for the village, and deeper use of RevenueCat's offerings for regional pricing experiments. None of it will ever sell speed.

Built With

Share this project:

Updates

Submission history