Inspiration
- Gunpla runners, blind-box toys, and fidget toys. The joy is in the fingers: the snip of a part coming off the sprue, the click when it seats.
- Day-one rule: opening a kit should feel like opening a beautifully designed little present, not pulling a slot machine.
- Shipaton was the deadline that turned a RealityKit weekend experiment (first commit July 22) into a shipped app.
What it does
- Unbox. Tap the carton, the flaps fold back, pull out the collector card and the runner.
- Snip, Snap, Collect Sweep a finger along the sprue and every gate it touches pops loose. Haptics tuned like a fidget toy. Drag each part into its ghost outline. A tick when it aligns. Finished toys line up on your shelf!
- A CAT runs the one-minute tutorial and heckles every unboxing. ("Could be chrome. Could be gold. Will be loved.")
How we built it
Stack
- Swift, SwiftUI, RealityKit, custom Metal shaders (iridescent plastic, crease-edge wireframe ghost via LowLevelMesh), Core Haptics, AVFoundation.
- RevenueCat SDK (StoreKit 2, anonymous users): three coin packs + Nomi Pro monthly, one
Nomi Proentitlement,customerInfoStreamfeeding game state. - RevenueCat Ads: AdMob rewarded through the RevenueCatAdMob adapter, so ad revenue lands in the same RevenueCat charts as purchases.
Content pipeline (one person, 45 3D models, four weeks)
- Animal → SD mecha concept sheets (image model) → Meshy for 1,250-face A-pose models and textures.
- My own local web tool, GLB Lab: Parts Studio splits each model into parts, a sprue generator lays out the runner and gates. Blender CLI turns GLB into USDZ.
- Cards and cartons are printed at runtime in Core Graphics per series. The foil pass is the metal map, so the gold rule actually reflects the room.
Game logic
- One pure reducer:
reduce(state, action, moment, config, rng). 100+ self-checks run at every debug launch. - The economy was tuned in a Python Monte-Carlo before anyone played it: a free player finishes all 45 in about 38 days, everything in about a year; Pro is about 1.4× faster.
[optional]Pair-programmed with Claude Code. I owned art direction, economy, consoles, and taste; Claude wrote most of the Swift.
Challenges we ran into
- App Review 2.1: "unable to locate the ATT permission request." ATT lived inside Google UMP's console-scripted flow, which the reviewer's device never showed. Fix: request ATT directly on the first "Watch AD" tap, then UMP. Resubmitted with a device recording.
- RealityKit in the simulator: scenes stop presenting unless some material value changes every frame, and transform writes on the root entity are ignored. Fix: a hidden light under the shelf that "breathes" by one millimetre.
- AdMob's post-launch ramp: limited fill until the store listing links, the readiness review passes, and app-ads.txt is crawled. Which brings us to the dollar.
Accomplishments that we're proud of
- Shipped. First commit July 22, App Store August 21, 41 commits, solo.
- The RevenueCat Ads chart reads $1.00 lifetime. My first ad dollar, and it flowed through the same pipe as the purchases. The pipe works.
- 5.0 stars from the first 3 ratings!
What we learned
- Consent UX is game design, not a legal checkbox. Ask on the first "Watch AD" tap and nobody feels ambushed.
- RevenueCat's ad adapter makes ads a first-class revenue stream: one placement id, one dashboard, LTV that includes ad revenue, no backend.
- Simulate the economy before shipping it to people. The simulator found a design bug no playtest would have.
What's next for NomiKit: Tiny Things You Build
- Growth: every build is a 30-second satisfying clip. One kit, one video, find the one that travels. App Store featuring nomination.
- Coins → RevenueCat Virtual Currency with server-verified rewarded ads via RevenueCat's AdMob SSV webhook, once the online version lands.
- More series. The pipeline makes a nine-toy volume in an afternoon.


Log in or sign up for Devpost to join the conversation.