Inspiration: My grandmother's CRT TV in Glen Innes, NSW. Early 90s. A green ball bouncing between two white paddles, and that satisfying beep on every hit. I wanted to rebuild that feeling — but for a phone you hold in one hand on a bumpy bus ride. Not a clone. A reimagining.
What it does: Whisper Ball is a portrait-mode table-ball game with 50 campaign levels, daily seeded challenges, local 2-player mode, and adaptive AI that intentionally makes mistakes so it feels human, not robotic. The "1972" CRT phosphor theme unlocks after a 50-hit rally. Physics run on the UI thread at 60fps via Reanimated worklets — zero frame drops, even on old Android devices.
How we built it: React Native + Expo + EAS for the build pipeline. The physics engine uses shared values and worklets so collision detection, ball curve calculation, and paddle velocity tracking never touch the JS thread. Campaign levels are JSON-defined with parameters for ball speed, paddle size, CPU skill, obstacle count, and multi-ball mode. Daily challenges use a deterministic seeded RNG so every player worldwide gets the same level on the same UTC date.
RevenueCat integration powers our monetization: Remove Ads ($4.99 one-time) — removes banner and interstitial ads Premium Pack ($6.99 one-time) — removes ads + instant 1972 theme unlock + unlimited daily retries Restore Purchases support for cross-device entitlement recovery Google Mobile Ads provides banner ads during gameplay, frequency-capped interstitials between games, and rewarded video ads for "continue after close loss" — all respecting the user's purchase status via RevenueCat entitlements.
Challenges we ran into: Google Play Console rejected our package name three times and locked the original upload key. Had to request a key reset and wait days for approval. The ball curve mechanic — perpendicular acceleration based on paddle velocity — broke collision detection repeatedly until we implemented continuous collision detection (CCD) to prevent ball phasing through paddles at high speeds.
RevenueCat integration was straightforward, but getting the entitlement checks to sync with AsyncStorage for offline play took iteration. We cache purchase status locally and validate against RevenueCat on app launch, so users never see ads they've paid to remove — even without internet. And as a solo developer running a photography business and raising kids, every line of code was written after 11pm.
Accomplishments that we're proud of: 50 campaign levels with 3-star scoring and progressive unlocks
Deterministic daily challenges using UTC-date seeding — same level, same day, worldwide Real-time ball curve physics with CCD, running entirely on the UI thread Ethical monetization: banner ads, frequency-capped interstitials, rewarded video "continue," and two-tier IAP via RevenueCat Built by one person in regional Australia with no formal CS background
What we learned: Monetization is harder than game design. Integrating AdMob, RevenueCat, and making sure paying customers never see ads while non-paying users get a fair experience took longer than building the physics engine. We learned that RevenueCat's entitlement system is the cleanest way to handle "Remove Ads" — one check, one truth, cached locally for offline resilience.
We also learned that regional Australia isn't a handicap — slow internet forces asset optimization, and working alone forces you to build systems that actually run without you.
What's next for whisper ball: Multiplayer: Online ranked matches via Supabase real-time
Level editor: Community-created levels, curated weekly Seasonal themes: Halloween, Christmas, and location-based skins More games: Block City Saga (block-fitting puzzle) is already in the pipeline, built on the same Expo + EAS + RevenueCat architecture
Built With
- admob
- android
- android-studio
- arcade
- async-storage
- eas
- expo.io
- gaming
- google-mobile-ads
- javascript
- linear-gradient
- mobile
- mobile-game
- offline-first
- physics
- react-native
- react-native-gesture-handler
- react-native-reanimated
- revenuecat
- typescript
- ui-design
Log in or sign up for Devpost to join the conversation.