Sky City
A cozy 3D merge puzzle built with React Native and three.js, live on Google Play.
React Native gamelocal Kotlin Expo modulePlay Games Services

The product
Merge three buildings into the next tier and grow a floating island from Campsite to World Capital, rendered as a living diorama with day cycles, fog and per-world ambient systems. No timer, no lives, no energy: nothing moves until you place a building.
Under the cozy surface: over 70,000 lines of TypeScript, about 1,000 Jest tests, a game engine in plain TypeScript with no React or three.js imports, Play purchases verified by Firebase Cloud Functions, and Play Games leaderboards through a small local Kotlin module for Expo.
Under the hood
THE ENGINEERING
- 01
Engine and render split: game logic is plain TypeScript with no React, three.js or Expo imports, tested with Jest on Node and driven by a seeded random generator for fair daily challenges
- 02
A strict performance budget: each building is one merged geometry and one draw call, repeated effects are instanced, and nothing is allocated per frame
- 03
Purchases verified server-side by Firebase Cloud Functions; all-time and daily leaderboards through a local Kotlin Expo module for Play Games
- 04
A seeded daily challenge with a streak, 57 missions and 82 challenges, a coin economy and city ranks
- 05
Local reminder notifications on a decaying cadence, at an hour learned from the player's own sessions, never in quiet hours
- 06
Every sound procedurally synthesized: 61 WAVs from a 57 KB script, zero audio licences
- 07
Built with an AI-first workflow: past 70,000 lines I used AI coding agents to trace and fix state bugs across the codebase; GitHub Actions builds an installable APK
In the product





Next case study
Spindle →