Inspiration

Trap platformers where the level fights back are endlessly replayable. I wanted to bring that to Reddit, where the community can compete and challenge each other through comments.

The difference: every run randomizes where traps fire. Play the same level 50 times and the floor will vanish in a different spot each time. You can't memorize it. You have to react.

What it does

CAUGHT OUT is a 30-level trap platformer that runs as a Reddit interactive post.

The levels look safe. Simple platforms, clear path to the exit. Then you step into an invisible trigger zone and things go wrong. The floor disappears. A blade sweeps the screen. Your controls flip. The exit door relocates. You die in 0.3 seconds and respawn immediately.

30 levels, 3 worlds, 7 trap types, randomized positions each attempt. Ghost replays let you race the best player's shadow. Daily challenges pick a new level each day for the community to compete on. You can challenge specific players through Reddit comments.

Other stuff: points for forward progress (lose some on death), leaderboard across levels, 10 secret keys hidden for completionists, skip button after 10 deaths so nobody's stuck forever. There's a COMPETE mode with a single long level for score competition, and a built-in tutorial that walks new players through controls and mechanics.

How we built it

The game runs on Devvit Web. Phaser 3 handles rendering inside the webview. Everything is drawn procedurally with Phaser's Graphics API. No sprites, no image files, no fonts loaded externally.

The server is TypeScript on Devvit's backend. Redis stores leaderboards, ghost replays, death markers, and player progress. The webview talks to the server through postMessage.

Sound effects are procedural too. Web Audio API oscillators. Zero audio files in the project.

The full stack: Devvit Web, Phaser 3, TypeScript, Redis, Web Audio API, vanilla JS. No bundler. Script tags in an HTML file.

Challenges we ran into

Making randomized traps that never softlock the player was the hardest part. If a floor vanish removes the only path forward and the player can't die (god mode for demos) they get stuck in a loop. The rule we landed on: traps kill you (causing respawn), they never block all progress.

Devvit's webview iframe has constraints. No confirm(), CSP blocks inline event handlers, the canvas needs explicit tabIndex and focus() for keyboard events to fire. Each of these took a few rounds to diagnose.

A variable naming conflict between two script files crashed the entire game silently for hours. const T = 32 in one file collided with function T() in another. Browser showed a blank screen with zero error messages.

Accomplishments

The randomization actually works. Two consecutive runs on the same level feel different. The door betrayal mechanic (exit moves when you're one step away) is genuinely surprising even when you know it exists, because you don't know which run it'll trigger.

The social loop landed well. Challenge posts create comment threads of people one-upping each other. The daily challenge gives a reason to come back.

Everything renders with zero assets. The player, tiles, hazards, blades, ghost, exit door, secret keys are all Graphics API calls.

What we learned

Short levels with instant respawn keep people playing longer than long levels with checkpoints. Invisible traps create better surprise than visible danger you can plan around. Reddit comments work as a competition layer.

What's next

More trap types. A level editor so the community can build and share levels. Seasonal events. True real-time multiplayer racing through Devvit's realtime channels once we've stress-tested latency.

Built With

Share this project:

Updates

Submission history