Inspiration
Every idle game we loved eventually became a spreadsheet with a background image. The numbers went up, the art stopped mattering, and the "world" turned out to be a menu.
Two games are named here on purpose: Minecraft and Terraria. What we took from them is the shape, a 3D world made of blocks, grown from a seed, big enough to wander and yours to change. What we did not want was a third one of those on a touchscreen. Both of those games make you the protagonist, the world is raw material, and the verbs are mine, craft, build, fight.
So Vivarium keeps the 3D block world and takes the protagonist out of it. There is nothing to mine, nothing to fight, and nothing that obeys you. The ground, the weather, the plants and the creatures run whether you are watching or not, and what you get is a handful of levers, wind you can lean on, structures you can place, and the consequences you did not ask for. No score. No timers. No energy bar. No daily login. A thing under glass you keep, the way you keep a terrarium on a windowsill, you perturb it, and you watch what it says back.
What it does
Vivarium is a 3D voxel biome living behind your phone's screen.
The ground, the weather, the plants and the creatures are one simulation, not four systems faking each other. Green spreads where soil and water allow it. Herds follow the green. Hunters follow the herds. When a stand of plants exhausts the soil beneath it, the whole picture has to move somewhere else.
- The phone is the instrument. Tilt it and the wind leans with it. Shake it and a gust crosses the land, scattering seed if the ground is ready and stripping it if it is not. Turn it face down and the light goes out early, hold it there and the world files an eclipse in its own chronicle.
- Buildings are levers, not decorations. All 30 structures are a two-sided bargain. A hedge shelters the green behind it from storms, and stops it spreading. A lure stone gathers the grazers, so the hunters come too, and the ground is stripped bare. A beacon lets plants grow at night, and nothing can sleep in the light.
- It runs without you. Close the app and the biome keeps its own time. Come back and it walks the missed days past you, one at a time, so you watch what happened instead of reading a number. A volcano you left mid-eruption is still mid-eruption a week later.
- Every world is a seed. Nine characters make a world, and the same nine characters make it again (same land, same species and same weather). Type any word and see the world that word makes.
- The frontier moves when you push it. Raise an obelisk at the edge and the land opens further, and new ground brings new landmarks and species the world was not wide enough to hold before. The free game grows to 20 tiles. Vivarium Extended, the one paid unlock that touches the simulation, raises that ceiling to 999.
- Hand a world to a friend through a QR code. Hold your screen up to another phone's camera and the entire biome crosses over: its age, its structures, its herds, its chronicle, its notice boards. A big world is fountain-coded into a stream of codes that plays on the glass while the other camera watches. The world travels as light between two screens.
- It remembers. A chronicle written in a naturalist's hand, a field guide that fills in as you meet things, an almanac of peaks and losses, named places you can travel back to, and share cards and animated postcards you can export.
Eleven in-app languages, 39 localized App Store listings, a day piece and a night piece of music for each of the four seasons, and full offline play.
How we built it
We've used React Native 0.76 on Expo SDK 52 with the New Architecture, TypeScript end to end, about 74,000 lines of it. Two things are worth naming:
The renderer is ours. The 3D world is drawn by a WebGL renderer we wrote ourselves rather than by a game engine, and the whole visible world reaches the GPU in a single draw call: 8,064 terrain cubes plus every creature and structure in view, all stamped from one master cube, with the light of that hour of that season carried as three numbers. That is what keeps it at 60fps on phones several years old while a full ecosystem runs behind the glass. And when it cannot draw, it says so out loud, every path that would otherwise end in a black screen falls back to a 2D Skia renderer, because a blank screen that cannot explain itself is worse than no 3D at all.
The simulation never learns that money exists. The part of the app that runs the world does not import the part that sells things, or any native code at all. It is handed a number for how far the world is allowed to reach and has no idea where that number came from. That one rule is what lets the entire world run headless in a terminal, a dozen small test harnesses fast-forward thousands of in-world years with no phone, no simulator and no store attached, which is the only reason an economy this slow could be balanced at all.
How we used RevenueCat
RevenueCat runs the whole shelf. Eight products, three bought once (Vivarium Extended, which lifts the frontier from 20 tiles to 999; The Other Glass, which adds a second and a third world slot; The Threefold Hand, which makes every resource you pick up count three times) and five consumables (the resource packs Windfall Seeds and Cornerstone Ores, and three gem packs), with the catalogue, the purchases, the restores and the reconciliation all going through RevenueCat's React Native SDK. Everything in the app that needs to know whether something has been bought asks one place, and that place is RevenueCat.
Two decisions behind it:
Nothing on the shelf is a wall. A gem is exactly one minute of waiting, and the free game pays out 154 of them across 24 milestones against roughly 716 minutes of waiting that the free frontier costs. A player is told so up front, the very first gem anyone earns arrives with a card explaining what a gem is, what it buys and where it comes from, shown once in a player's life. A pack shortens a wait and never raises a ceiling, so a player who buys nothing can still complete everything the free world has. That is the constraint every price was written against: the smallest gem pack is deliberately sized below what the full 24 milestones pay, because any bigger and the milestone page turns into loose change. And the packs are named after the wait they buy rather than the count they hand over: The Hour, The Afternoon, The Day, because a gem is a minute, so "sixty gems" and "an hour" are the same sentence and only one of them is about somebody's evening.
What RevenueCat says is on the device before the first frame is drawn. This is a game built to work with the radio off, and the very first thing it has to settle, before anything is drawn at all, is how far the world is allowed to reach. So whatever RevenueCat last told us is kept on the device beside the world's own save and read back at launch, which is what makes that answer available on frame one and available at thirty thousand feet. A player who paid in June and is on a plane in December still owns what they own, and what is stored is only ever what RevenueCat said: a record of a purchase, never a grant.
Promotional codes are ordinary purchases: the SDK presents Apple's redemption sheet, Apple validates against the offer, and what comes back is a purchase at 100% off that RevenueCat reconciles like any other. That is the whole of how the codes work, no separate unlock path.
Challenges we ran into
A silent configuration mismatch, which is the expensive kind. Game Center achievements simply never arrived. No error, no warning, no crash, nothing to chase. The cause was one key name in a module manifest, written in a form Expo's autolinking step does not read: the pod compiles, the binary ships, nothing complains, and the native module is never registered at runtime. Our own code read that silence as "this device has no Game Center", which is the right answer to a false question and is why no symptom pointed anywhere. Version 1.0.226 shipped that way. The fix is one line, pinned in a patch and reported upstream, plus a check in our release list so this class of failure is loud next time.
Moving to 3D without throwing the 2D away. We started Vivarium first as a flat top-down picture painted cell by cell on the CPU, 8,064 of them every frame on the JS thread using Skia. The 3D renderer sends instances instead and lets the GPU do the shading, where the light of the hour is three uniforms and a sunset costs nothing to redraw. The hard part was keeping the old renderer alive as a fallback: for a while the same world had two descriptions and they drifted, and the landmark catalogue came apart twice. What fixed it was deciding which one is the truth. The boxes are the source and the flat picture is a projection of them, so the raster cannot say anything the 3D view does not.
Balancing an economy you cannot playtest in real time. Nineteen obelisks and a thousand in-world years do not fit in an afternoon. That is what the headless harnesses are for: the economy was tuned by running the simulation forward in a terminal, and the gem ledger alone carries 214 assertions that run in under a second.
Accomplishments that we're proud of
- A 3D world simulation that a player can genuinely surprise, in a phone app, at 60fps, in one draw call.
- Handing a whole living world to another phone with nothing but a camera and a sequence of QR codes on a screen with no account, no server and no upload.
- Shipping 39 localized store listings and 11 in-app languages as a very small team.
- A monetization shelf we can defend line by line: no timers, no energy, no subscription and nothing paywalled that the free game needs.
What we learned
- Decide what the app believes with no network before you need the answer. "What does this game hold to be true on a plane?" is a product decision, not an error handler, and leaving it to the error handler means deciding it under pressure.
- Silence is the expensive failure mode. Our code behaved correctly given a false answer, which is exactly why nothing pointed at the cause. Anything that can quietly answer "no" is worth one loud check somewhere.
- When two things describe the same world, say which one is the truth. We kept a 2D renderer alongside the 3D one, and every time they disagreed it was because a shape had two descriptions instead of one source and one projection of it.
- Name the thing you sell after what the buyer gets back. Nobody wants "120% of the materials for your next obelisk". They want Cornerstone Ores.
What's next for Vivarium - Life Sandbox Sim
- Ship the Android build that already exists in the tree.
- More frontier landmarks and species, and a second pass on the chronicle's voice.
- Keep the promise the listing makes: no ads, no timers, no daily login, ever.
- An underground world with different creatures.
Built With
- cloudflare-workers
- decimen-optical-transfer
- expo-camera
- expo-gl
- expo.io
- fountain-codes
- game-center
- gamedev
- glsl
- in-app-purchase
- ios
- javascript
- mmkv
- node.js
- procedural-generation
- qr-code
- react-native
- reanimated
- revenuecat
- skia
- storekit
- typescript
- voxel
- webgl



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