SPLIT - shipping a hyper-casual title to Google Play
SPLIT is a hyper-casual mobile title I shipped on Google Play (play.google.com). Different shape of work from Nova: solo launch instead of platform, ad-monetized instead of real-money wallet, public store instead of internal distribution. The interesting parts of a public release aren't the gameplay code - they're the SDK integrations, the build pipeline, and the bugs you only meet after the first installs.
The stack
Hyper-casual lives or dies on time-to-ship and time-to-iterate, so the stack is opinionated:
- Unity URP + 2D pipeline - SpriteShape, Tilemap, Aseprite importer, PixelPerfect. Modern 2D Unity, not the legacy stack.
- UniTask for async/await - coroutines don't compose, and most of the SDK integrations are fundamentally async. UniTask makes ad-load, IAP-validate, and Play Games sign-in legible.
- Addressables for non-critical content - same lesson as Nova: get assets out of the build whenever it's safe, especially for hyper-casual where install size is conversion.
- IronSource LevelPlay for ad mediation - interstitials, rewarded video, banners.
- Unity Purchasing + Google Play Billing for the single remove-ads (ad-free) purchase.
- Google Play SDK suite - Play Games (sign-in, leaderboards), Play Review (in-app review prompt), Play Core.
- Facebook SDK for attribution and analytics.
- External Dependency Manager (EDM4U) to keep Android dependency hell at bay across LevelPlay, FB SDK, Play Plugins, and Unity Purchasing all wanting different versions of the same Google Play Services artifacts.
The release pipeline
Public app stores aren't just "upload an APK." The pipeline that worked:
- Internal testing track first - signed AAB, ten-person tester list, real Play Store install path so the IAP and Play Games sign-in flow can be exercised against production endpoints.
- Closed testing for a wider invite list and the first staged-rollout shape - this is where ad mediation gets its first real fill data, and where the FB SDK starts attributing.
- Open testing when the crash-free session rate is acceptable and the Play Console pre-launch reports come back clean across the device matrix.
- Production with staged rollout (5% → 20% → 50% → 100%), watching crash and ANR rates between each step. Halt and roll back if anything moves.
The most useful tool in that loop wasn't anything Unity-specific - it was the Play Console's pre-launch reports, which run your AAB on a fleet of real devices and surface ANRs and crashes you'd otherwise only see post-launch.
The integrations that fight you
Each SDK is well-documented in isolation; they're documented as if they were the only SDK in your project. They aren't. The real integration work is reconciling them:
- EDM4U is the difference between a 5-minute build and a 5-hour debugging session. LevelPlay, Facebook SDK, Google Play Plugins, and Unity Purchasing all pull in Android Gradle dependencies. Without dependency resolution they collide, the build silently picks one, and you find out at runtime when the Play Games sign-in flow throws on a method that doesn't exist.
- Ad mediation timing matters. Initialize too early and consent flows haven't run; too
late and the first interstitial slot is empty. The fix lives in
UniTask-driven init ordering. - The one IAP is a non-consumable "remove ads" entitlement, which keeps validation simple. Unity's client-side receipt validator is sufficient here because nothing economic is at stake - there's no currency or consumable balance a spoofed receipt could inflate. The entitlement is persisted locally and reinstated through Play Billing's restore-purchases flow on reinstall or a new device.
Live ops
Once it's public, the engineering job changes. Crash and ANR rates are watched daily for the first two weeks; the worst classes of bug are the ones that only happen on specific OEM device skins (Samsung One UI, Xiaomi MIUI) that the Play Console pre-launch fleet doesn't cover.
← Back to Selected Work