Inspiration

I wanted to make something that could only exist on Reddit.

Mario Maker is great, but it's a game with a level editor bolted on. Reddit is already a machine for competition, arguments, and public humiliation — it just didn't have a game shaped like that. So: what if every level was a post?

That's Trapmaker. You build a lethal platformer level, you have to prove you can beat it, and then you publish it as a Reddit post. Strangers scroll past, play it in-feed, and die. And every time one of them dies in your trap, you get paid.

You're the villain and the hero. You rage at someone else's level, then go build your revenge.

What it does

Every post in the subreddit is a playable level.

  • Raid — a precision platformer. Spikes, saws, dart cannons, crumbling floors, and ghost blocks that look exactly like real terrain until you stand on one and fall through it into a spike pit.
  • Build — an in-post editor with a piece budget, so you can't just spam spikes. You have to beat your own level before you can publish it.
  • Compete — clear times feed a leaderboard on every post. You see your rank, the fastest runs, and how many people died trying.
  • The heatmap — as the author, you can see exactly where everyone died in your level. Watching a cluster of deaths form on the one jump you knew was evil is the best feeling in the game.

How I built it

Devvit Web — Phaser 3 client, Hono server, Redis. Each published level is a real Reddit post (submitCustomPost), with the level struct and its stats keyed in Redis by post ID.

The one decision everything else hangs off: the physics are hand-rolled. I don't use Arcade Physics. The game runs a fixed-timestep 60Hz simulation with my own AABB collision, and movement is never delta-scaled.

That's because the sim has to be deterministic. Clear times go on a public leaderboard — if the same inputs can produce different results on different hardware, the leaderboard is a lie. Fixed timestep means identical inputs always produce an identical run. (It also means ghost replays would be almost free later: record the input stream, replay it exactly.)

Everything else is Phaser: rendering, scenes, input, animation, audio, particles.

The slime has 10 animation states driven off flags the sim already tracks — idle, run, jump, fall, land, skid, wall-press, and a spring-launch pose that fires off the same flag the physics uses for a fixed-height bounce.

And I had no audio assets, so I synthesized all 12 sounds from scratch in Python/NumPy.

Challenges

Reddit's mobile app is portrait-locked, and my game is landscape. There is no orientation API in Devvit. You cannot make the phone rotate. So I rotate the entire app 90° in CSS and let the player turn their device.

That broke two things. Phaser's Scale.FIT measures its parent with getBoundingClientRect(), which returns the rotated bounding box — so it computed a completely wrong, overflowing canvas. I had to drop to Scale.NONE and size the canvas by hand. And every touch landed in the wrong place, so I overrode Phaser's InputManager.transformPointer to undo the rotation before converting to game coordinates. Verified it by driving a real touch event through Chrome DevTools Protocol onto a rotated button.

The slime was 22MB of GPU texture. The sprite sheets were beautiful and enormous, for a character that renders at about 30 pixels. Worse, they're not power-of-two, so they can't be mipmapped and aliased horribly. I wrote a Pillow pipeline that detects frame counts by finding the transparent gaps between frames, then generates optimized downscales — all sheets sharing one scale factor, because the squash-and-stretch depends on their relative sizes. 22MB → 1.4MB.

I got 31fps on my iPhone and spent an hour hunting it. It was Low Power Mode capping requestAnimationFrame to 30. My code was fine.

What I learned

The platform shapes the game more than the design doc does. Portrait-lock, iOS codec support, case-sensitive servers, non-power-of-two textures — none of that is in a GDD, and all of it changed what I shipped.

Make a GDD Please. Also, Stick to it !! Saved me from my habit of feature creeping when the urge kicked in

What's next

  • Ghost replay — race the record. The deterministic sim already makes this cheap; I just ran out of time.
  • Plate + door triggers, so levels can be puzzles and not just reflex tests.
  • Death report digests, a daily gauntlet, and leaning harder into the villain framing — the drama is the product.
Share this project:

Updates

Submission history