Inspiration

The idea clicked when I stopped asking, “How do I put a game on Reddit?” and started asking, “What kind of game only makes sense inside a subreddit?”

A lot of interactive posts are still solitary experiences. You open them, play something, close them, and leave no trace. The community is standing around the game instead of living inside it.

Hard platformers have the opposite problem. They create incredible stories, but the game throws most of them away. You miss a jump, reset, and the failure disappears.

Reddit does not forget failure. People talk about the cursed ledge, the impossible jump, the stranger whose terrible run accidentally revealed the right route.

So I made that physical.

In Fallstack, failed attempts become part of the level. Your bad jump can raise a foothold for the next climber. Enough bad jumps can corrupt that help into a hazard. A clean climb can stabilize the damage.

It is not a leaderboard attached to a platformer. The community is inside the geometry.

The level is made out of everyone else’s failures.

What it does

Everyone in one subreddit climbs the same daily tower.

It is a finite precision climb with 154 route platforms, 12 zones, and three visual strata: the Lower Ruins, Bell Shaft, and Moon Roof. On desktop, you move with the arrow keys, hold Space to charge, then release to leap. Mobile uses the same commitment-based movement through fixed touch controls.

When someone falls, Fallstack records where the jump failed and why. Short jumps, overjumps, wall hits, and repeated dependence on existing help all affect the tower differently.

Those failures aggregate into physical artifacts:

  • Corpse Stacks turn repeated failure into a foothold.
  • Mercy Nails create tiny emergency landings at brutal gaps.
  • Ghost Platforms reveal temporary rescue routes.
  • Cursed Bricks make overused landings unstable.
  • Lantern Trails preserve successful paths without becoming solid ground.

Failure helps at first. Accumulated failure starts to distort the route. Clean clears push damaged zones back toward stability.

Another climber can see those changes without reloading. If a new artifact arrives while they are mid-jump, Fallstack waits until they land before changing the collision geometry. The shared tower stays alive without moving the floor under someone’s feet.

At the summit, Tower Memory turns the day into a community record: the worst scar, the strongest stabilizer, the highest climber, and a result players can carry back into the Reddit discussion.

How we built it

Fallstack is a Devvit Web application built with TypeScript, Phaser, React, Hono, Redis, and Devvit Realtime.

The Reddit post has two entrypoints. The inline view stays lightweight and explains the daily hook without loading the game engine. Opening the full experience loads the Phaser climb, React shell, mobile controls, sound, and live community board.

I kept the project split into three clear layers:

  • Pure TypeScript generates the tower, derives artifacts, validates routes, resolves mutation thresholds, and produces receipts.
  • Phaser owns movement, collision, camera behavior, rendering, and local gameplay events.
  • The Devvit server owns identity, Redis state, contribution limits, daily board authority, Realtime updates, and post lifecycle.

The client never chooses a username, Redis key, community, or mutation site. It sends a bounded observation of what happened. The server resolves the real impact point and applies the event through a watched Redis transaction.

That transaction handles duplicate protection, contribution caps, counters, revision numbers, achievements, history, and expiration together. One fall cannot count twice because two tabs submitted it, and a failed transaction cannot leave half a mutation behind.

Realtime does not send an entire replacement world. It only announces that a newer board revision exists. Clients fetch the authoritative snapshot, compare revisions, and apply geometry at a safe point.

The tower is generated deterministically from constrained route rules. Every daily layout keeps an artifact-free path to the summit, so community help can create alternatives but is never required to finish.

Most of the visual world is drawn directly in Phaser. The damaged arches, bound platforms, artifacts, and tiny relic bearer all follow one compact cursed-diorama system. That kept the art readable at mobile scale and kept visual edges aligned with the actual collision bodies.

Challenges we ran into

The hardest problem was not making a platformer. It was letting many people change one platformer without breaking it.

A community mutation can change collision. That sounds simple until the update arrives while another player is airborne. Applying it immediately can create a platform inside the player, remove their landing, or turn a fair jump into nonsense. Fallstack now defers newer geometry until a landing, recovery, or checkpoint makes the swap safe.

The tower generator also humbled me.

The first serious version produced a 659-platform route. It was finite on paper and miserable in practice. Some landings depended on brushing the world wall. Checkpoint undersides caught valid jumps. Decorative obstacles occasionally blocked the route they were meant to decorate.

I cut the tower to 154 route platforms, preserved the opening jump, rebuilt checkpoint approaches, made checkpoints passable from below, added side margins, and sampled generated routes across many seeds. Then I drove a real-input browser agent from the floor to the summit instead of trusting reachability math alone.

Shared persistence created a different class of problems. Duplicate tabs, retries, contribution caps, stale daily boards, and two players crossing an artifact threshold at the same time all had to resolve cleanly. The solution was to treat each mutation as a complete state transition, not a loose collection of Redis writes.

Mobile forced equally blunt decisions. At 375 pixels wide, every label competes with the jump. One early mutation message literally covered the player’s spawn. I moved feedback out of the flight corridor, kept controls fixed, added reduced-motion behavior, and switched to a Canvas renderer after automatic WebGL selection fell onto a slow software path in testing.

I also had to keep the opening honest. A new daily board needs visible scars before a community has generated traffic; otherwise, the hook is invisible. Fallstack tracks generated opening scars separately from real community activity. It never pretends those starting marks came from people.

Accomplishments that we're proud of

The moment I am proudest of is small: one climber falls, the First Gap crosses a threshold, and another climber sees a Mercy Nail appear after landing. No reload. No fake multiplayer. One person’s failure has become useful level geometry for somebody else.

The proof behind that moment is substantial:

  • Two signed-in Reddit clients reconciled the same hosted board from revision 37 to revision 39 without reloading.
  • A complete real-input run crossed all 154 route platforms and reached the summit in 2 minutes and 43 seconds.
  • The final closeout suite passes 135 automated tests covering generation, validation, persistence, concurrency, progression, touch input, and Reddit post behavior.
  • Mobile rendering held a 16.7 ms median frame time during the final browser pass.
  • Duplicate-event tests submitted the same mutation 100 times and persisted it once.
  • The inline Reddit entrypoint stays lightweight and does not load Phaser until the player opens the full game.

More than any individual number, I am proud that Fallstack stayed focused. It became a finished shared toy instead of a pile of game modes, progression systems, cosmetics, and promises.

What we learned

I learned that “Reddit-native” has nothing to do with adding a mascot, karma counter, fake comments, or familiar colors.

Reddit becomes load-bearing when the community owns part of the state, when that state changes what people do next, and when the result naturally creates something worth discussing.

I learned that asynchronous multiplayer can feel deeply social. Players do not need to occupy the same frame. They need to feel each other’s consequences.

I learned that fairness has to be engineered. “The jump is mathematically possible” is not the same as “the jump feels fair.” A generated tower needs route validation, collision margins, real playthroughs, and the humility to delete 505 platforms.

I learned to stop treating tests as the finish line. Tests caught race conditions and impossible states. Browser playthroughs caught bad pacing and visual obstruction. Hosted Reddit checks caught behavior the local environment could not reproduce.

Most importantly, I learned that failure can be a contribution without becoming pity or punishment. The right failure system creates gratitude, blame, comedy, and tension at the same time.

What's next for Fallstack

The immediate next step is not more features. It is putting the current loop in front of more first-time players.

I want to finish the physical iPhone pass, run the structured five-player comprehension test, and pilot a real daily tower inside an active subreddit. That will show whether people understand the shared mutation within seconds, whether artifact thresholds feel alive at real community scale, and where the climb becomes frustrating instead of funny.

After that, I want to expand the library of validated daily seeds, tune mutation thresholds from real play, and make Tower Memory an even stronger record of what the community did that day.

No shop. No inventory. No stack of disconnected modes.

Fall. Leave a mark. Come back tomorrow and see what everyone did with it.

Built With

Share this project:

Updates