Inspiration Every game we could think of hides its failures — deaths get reset, respawns wipe the slate, corpses despawn. We wanted the opposite: what if dying wasn't just feedback for you, but permanent, shared infrastructure for everyone else? Reddit's "one post, one community" format was the other half of the idea — a single subreddit-wide shaft that everyone free-falls through meant deaths could accumulate into something the next player literally collides with. The name came before the mechanic did: a pileup isn't a failure state, it's the point.
What it does PILEUP: DESCENT drops one deadly 3D shaft per subreddit, per day. You steer with a single thumb — drag to steer, release to dive — and any trap kills in one hit. When you die, your named corpse freezes in place as solid, collidable geometry every other player sees and falls past. Enough bodies stacked in one spot become a walkable ledge; enough bodies jammed into a rotor slow the blade down. Every ~250 community attempts, the shaft's deadliest trap decays a notch, so the day is mathematically guaranteed to end in a clear — the shaft gets easier because the community died into it. First player to the floor portal is crowned Today's Survivor, gets flair and a line in the pinned Fall Report, and picks tomorrow's trap mutation. At midnight UTC the day seals into the Hall of Days and a fresh shaft opens. No XP, no currency, no streaks — the only progression that persists is the pile itself, and it belongs to everyone.
How we built it The whole thing runs as a Reddit Devvit Web app: three.js + TypeScript on the client, Hono on the server, Redis for state. The backbone is determinism — rng, levelgen, traps, and the physics sim all live in src/shared/ and run identically on both client and server, so the shaft the client renders is byte-for-byte the shaft the server can re-check. The sim steps at a fixed 120Hz timestep, and each attempt restarts at tick 0 against an identical trap layout, which means a winning run's input trace can be replayed and re-simulated exactly server-side.
Corpses are the core rendering and gameplay trick: the newest 400 bodies live in one InstancedMesh, older corpses get baked into a second frozen InstancedMesh at rollover, and that same depth-bucketed corpse field doubles as the collision index for ledge landings and blade-jam counts — "corpses as mechanism," at no extra storage cost. On the platform side, we hit real Devvit constraints early: Redis on Devvit has no lists or plain sets, so corpses and the Hall are stored as sorted sets instead; scheduler/menu/trigger handlers had to live under /internal/* while gameplay stayed on /api/*; and the server bundle has to ship as CommonJS, not ESM.
Challenges we ran into The hardest design tension was anti-cheat versus honesty about what the server can actually verify. Trap kills depend on live corpse state (a rotor jammed by bodies is less lethal than an empty one), and the server has no way to reproduce that exactly — so trap kills had to be client-side while the shared physics step (gravity, diving, steering, deterministic fan forces, walls, the portal) stayed server-reproducible. That meant clear validation could only ever be a movement-only re-simulation: it proves a submitted input trace physically reaches the portal in the claimed time, without false-rejecting real runs that legitimately used trap or corpse state to survive. We documented the residual risk rather than pretending it away — a sufficiently motivated attacker with the shared sim could in theory craft a physically-plausible trace — but decided that was an acceptable trade for a hackathon-scoped game where the crown is purely cosmetic and there's no currency to exploit.
Getting the crown itself to resolve correctly under concurrency was its own small fight — we used Redis hSetNX so the first valid clear atomically wins even if two players finish within the same tick. And building a full 3D ghost replay of the winning run for the Hall of Days meant re-deriving that day's exact level from its seed and mutation ID client-side, then re-running the shared sim in a fully isolated scene so it could never touch the live game.
Accomplishments that we're proud of Making death feel like progress instead of loss is the thing we're proudest of — a corpse isn't a fail state, it's terrain the next player benefits from. We're also proud that the "guaranteed to clear" promise isn't a script or a timer — it's a real, provable consequence of aggregate community attempts decaying trap lethality, and scripts/selfcheck.ts proves it (deterministic generation, a straight dive that clears the portal, monotonic decay, and exact trace re-simulation) without needing Reddit at all. And we shipped an anti-cheat story we can defend out loud, including exactly where it doesn't cover everything, instead of hand-waving it.
What we learned Shared determinism is worth designing around from day one — putting rng/levelgen/traps/sim in one module that both sides import turned "is this cheatable" from a constant worry into a solvable, bounded problem. We also learned to read the platform's actual primitives before trusting a spec: Devvit's Redis surface (strings/hashes/sorted sets/bitfields, no lists or plain sets) reshaped our data model, and it was cheaper to discover that early than to fight it later. Finally, we learned that being explicit about scope trade-offs — movement-only re-sim, uncompressed ghost traces, no audio yet — kept us moving instead of stalling on edge cases that don't matter at hackathon scope.
What's next for PILEUP: DESCENT Sound design is the most obvious next step — the game is fully playable muted today, but splats, blade-jams, and the crown fanfare deserve real audio. Beyond that: closing the residual anti-cheat gap with server-side corpse-state tracking so trap kills can eventually be re-simulated too, richer trap-mutation choices for the daily Survivor beyond a single pick, cross-subreddit Hall of Days browsing so communities can compare their shafts, and deeper spectator tools for watching a live pile grow in real time as more players drop in.
Built With
- 3d-game
- anti-cheat
- css3
- devvit-web
- eslint
- game-development
- hackathon
- hono
- html5
- javascript
- mobile-web
- multiplayer
- node.js
- physics-simulation
- prettier
- procedural-generation
- real-time-simulation
- reddit-devvit
- redis
- three.js
- typescript
- vite
- web-game
- webgl

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