Pause: Hold Still
A native iOS stillness game: hold your phone as still as possible for 20 seconds and get scored 0 to 100, with a live seismograph trace, global leaderboards, and a share card generated after every run.
- React Native
- Expo
- TypeScript
- Supabase
- Built in
- 2 days
Overview
Pause has one mechanic. Hold your phone as still as possible for 20 seconds and get scored 0 to 100. The whole concept is meant to click in under five seconds, with no tutorial and no onboarding. I built it solo, and designed it to feel like an Apple-made fitness app rather than an arcade game.
What was built
A 3-2-1 countdown leads into the 20-second run, where a live "seismograph" trace drawn from smoothed accelerometer and gyroscope data renders perfect stillness as a flatline and any movement as a spike. Results show the score, an estimated or live percentile, and a condensed replay of that trace. Every run auto-generates a share card that mirrors the results screen, cropped square so it survives iMessage, Instagram, TikTok, Discord, and X inline previews without losing the score. Leaderboards split Global and Country across Today, This Week, and All Time, and profiles use DiceBear avatars, 12 presets plus 3 hidden ones you can unlock through redeem codes. Guest play never creates an account, and signing in with Apple or Google is entirely opt-in, migrating local history over instead of replacing it.
Architecture
The Expo/React Native app is local-first. AsyncStorage holds best score, run history, and best-score reconciliation regardless of sign-in state, and it's what Play Again reads even when a Supabase submission fails silently in the background. Guest runs never leave the device, only a real signed-in account gets a row written to Postgres, and auth is Apple/Google only with no anonymous accounts. A Realtime subscription pushes live leaderboard movement, an Edge Function running under service_role handles account deletion by deriving the id from the caller's own verified JWT (satisfying Apple's in-app deletion requirement), and a pg_cron job checks America/Los_Angeles wall-clock boundaries every 15 minutes to push leaderboard-reset notifications straight from Postgres to Expo's Push API through pg_net, with no extra Edge Function in the path. Aptabase tracks just the funnel that matters: launched, played, finished, shared.
Fighting the obvious cheat
The obvious way to beat a stillness game is to just set the phone down. Three layered checks close that off. The player has to press and hold the screen through the countdown and the entire run, an orientation check rejects a run where the phone reads as lying flat rather than held up, and a movement floor rejects runs whose overall movement is suspiciously below what a real hand's physiological tremor can produce, regardless of angle. That floor's original value (0.4) was calibrated against just two genuine held runs, and it turned out to sit too close to real elite play. Production data later showed genuine top-20 runs clustering right against that wall, between 0.40 and 0.56, meaning it was clipping legitimate exceptional stillness instead of catching props. It's since been lowered to 0.2, alongside a small on-device-only log of rejected attempts (never synced, never sent to analytics) so the floor can keep getting recalibrated against real data instead of guesswork.