Vault Rush
About the project
Inspiration
The Reddit games I actually come back to have one thing in common. The content comes from other people. r/place, the daily guessing games, the little puzzle subs. You open them the next morning not because a studio shipped a new level overnight, but because the community did.
I wanted that feeling inside a fast arcade game you can play with one thumb. Stealth heists turned out to be a perfect fit. A heist is a tiny puzzle box. Dodge the lasers, crack the terminal, grab the loot, beat the clock. You understand it in one glance and it feels good in ten seconds. The idea I kept circling back to was making every player a thief and an architect. Crack today's vault, then build one of your own that's devious enough the rest of Reddit struggles with it.
That became the whole loop. Crack, build, publish, race, and come back tomorrow when there's a fresh one waiting.
What it does
Vault Rush is a mobile-first stealth game that runs entirely inside a Reddit post.
Crack mode is the daily heist. You slip past vision cones and laser grids, solve the lock puzzles, grab the loot, and try to beat the architect's par time. A new vault is featured every morning, with streak tracking and a countdown to the next drop, so there's always a reason to check back.
Build mode is a vault editor with a budget. Walls, lasers, loot, bombs, and puzzles each cost from a fixed pool, so you have to make real trade-offs instead of spamming traps. The important part is the publish gate. You have to clear your own vault before anyone else is allowed to see it. No impossible troll vaults, no untested junk. If you can't beat it, the world never sees it.
Then you race the world. Every published vault has its own live leaderboard, and clearing one first earns a First Blood bonus. Builders get a public architect profile and a reputation that climbs the more their vaults turn out to be feared but fair.
The whole thing was built for portrait touch play first. I tested every screen on a phone-sized viewport before a desktop browser ever entered the picture.
How I built it
The stack is Devvit Web (Reddit's platform) with a Phaser 4 game canvas, a Hono REST API on Devvit's serverless runtime, and Redis for storage. But the real heart of the game is one file: a shared, deterministic, fixed-timestep simulation.
The sim runs in whole ticks at \( \text{DT} = \tfrac{1}{60}\,\text{s} \). It has no Math.random, no wall clock, and no I/O. It's a pure function of the vault layout and the player's inputs. That one property is what everything else is built on:
- The client steps the sim every frame to render your live run, and it records your inputs as it goes.
- The server re-runs the exact same code over those recorded inputs to work out the real score. If the replay doesn't reproduce the outcome the client claimed, the run is thrown out. The client is never trusted with a score.
- The publish gate reuses a winning replay to set a vault's par time.
- The daily generator builds a vault procedurally, then proves it's beatable by pushing a synthetic clear through the same engine before it ever goes live.
Scoring rewards speed. Loot value gets multiplied by a factor that starts high and decays the longer you take:
$$ m(t) = m_{\max} - (m_{\max} - m_{\min})\cdot\min!\Big(1,\ \tfrac{t}{W}\Big),\qquad m_{\max}=2.0,\ m_{\min}=0.5,\ W=60\text{s} $$
So a clean 20-second run is worth far more than a nervous two-minute crawl. That gap is what makes people replay a vault they've already technically beaten.
Architect reputation was the hardest design problem, and it's the part I'm proudest of. Rewarding raw completions just rewards popularity. Rewarding raw difficulty just rewards impossible vaults nobody enjoys. I wanted to reward clever-but-fair. So reputation is capped by a fairness curve built on a vault's escape rate \( e \), meaning completions divided by attempts:
$$ \text{fairness}(e) = \begin{cases} 0 & e \le 0 \ \text{(impossible)} \ e / 0.05 & 0 < e < 0.05 \ 1 & 0.05 \le e \le 0.30 \ \text{(the sweet spot)} \ \dfrac{0.7 - e}{0.7 - 0.30} & 0.30 < e < 0.70 \ 0 & e \ge 0.70 \ \text{(trivial)} \end{cases} $$
A vault nobody can beat and a vault everybody beats both score zero. Only the ones living in that tense middle band push an architect up the titles, from Apprentice to Trapsmith to Architect to Master Architect. It's enforced in pure, unit-tested math that holds no matter how much reach a vault gets.
To keep the puzzles honest and personal, lock answers are seeded per player. The PIN and the circuit order for a given vault come from a deterministic hash of the vault ID, your user ID, and the puzzle index, so no two players ever share an answer, and the server can recompute the expected answer when it validates your replay.
The build tooling is Vite with TypeScript project references. The codebase is backed by 582 unit tests across 79 files in Vitest, plus a Playwright suite that drives real mobile-Chrome (Pixel 5) flows end to end. Phaser is loaded lazily, off the critical path, so the first thing a post paints is a branded loading screen instead of a multi-megabyte engine download.
Challenges I ran into
Inline scrolling is not allowed inside a Reddit post, and the feed itself grabs vertical drags, so native scrolling just dies inside an inline webview. I tried writing a custom touch scroller and eventually deleted it. The right answer was to have the menu expand the post to fullscreen, where native scrolling works properly.
Tap versus scroll versus drag over a Phaser canvas fought me for a while. Phaser captures touch and wheel input by default, which swallows page gestures. In the build editor I had to switch those defaults off and write an explicit tap-or-scroll decision, so placing a wall and scrolling the palette never step on each other.
Shipping a generator that literally cannot produce an unbeatable vault was tricky. Because no human plays a generated daily before it goes live, the generator has to prove each layout by running a greedy clear through the real anti-cheat engine, and reroll if it fails. Getting that to always terminate without an infinite loop took some care.
Legacy data broke things on real devices in ways that never showed up locally. Old vaults saved in Redis were missing fields like bombs or numeric scores, and they surfaced as invisible characters and dead controls on the actual Reddit app. I fixed those at the source by normalizing legacy records when the game loads them, and by hardening every place the UI reads a number.
Making it truly mobile-first instead of mobile-tolerated took real work too. Safe areas, portrait layout, thumb-reachable controls, and a canvas that resizes to fit its parent were all sorted out on a phone viewport before desktop got a look in.
What I learned
Determinism turned out to be a genuine superpower. One pure simulation, shared by the client and the server, gave me live rendering, server-side anti-cheat, par-time setting, and a self-verifying content generator, all out of the same 60 Hz function. Designing for it up front paid off many times over.
I also learned that fairness is a better retention hook than difficulty. The reputation curve, which rewards the clever-but-fair and punishes both the impossible and the trivial, is what turns "I made a level" into "I want to make a better one."
And building on Reddit taught me that the platform's constraints are the design. Inline versus fullscreen, feed gestures, per-user identity, deletion triggers. None of it got in the way of the game. Understanding it properly is what shaped the game.
What's next
Seasonal architect ladders that reset with fresh stakes, themed community build events, and comment-driven vault remixing, so the content Reddit generates keeps feeding the loop.
Built With
- css3
- devvit
- hono
- html5
- javascript
- node.js
- phaser.js
- redis
- typescript
- vite
Log in or sign up for Devpost to join the conversation.