Inspiration

I got hooked on match-3 games for a bit, mostly because of that satisfying feeling when a line clears. I’ve also liked peg solitaire since I was a kid. At some point the idea clicked: what if the hop from peg solitaire and the line clear from match-3 were part of the same move?

In Peg Hop, you jump a peg over another peg into an empty space. If the landing spot completes a line of three or more matching colors, that line pops. The game is basically peg solitaire mixed with match-3: you still have to think a few moves ahead, but you also get the satisfying clears and chain reactions.

I also wanted it to be social, so I built it to run inside Reddit instead of as a standalone web game. Everyone gets the same daily board and can compete directly in the comments.

What it does

A new board drops every day at 05:00 UTC. You hop pegs around the board, clear matching lines, and try to finish with as few pegs left as possible. Your result earns stars based on how well you solve it, and you can also earn a crown if you clear it in the fewest possible moves.

Each day has a different board shape, like a hexagon, triangle, diamond, donut, or star. Playing daily also builds a streak.

The main feature I’m proud of is the ghost race. When someone shares their solve in a comment, another player can open the comment menu and choose “Race this run.” That drops them into the same board with the original solve playing as a ghost. If they beat it, they can reply with their own run. The comment thread turns into a mini leaderboard.

How I built it

  • Phaser 3 client, built portrait-first and mobile-first on Reddit’s Devvit Web platform
  • Hono server on Node 22
  • Redis for streaks, result histograms, and stored runs
  • A shared TypeScript core for the board model, rules engine, and DFS solver

The shared core has no DOM or platform dependencies, so it runs the same way in the browser, on the server, and in offline scripts.

That core does three things. First, it generates and grades the level bank offline. Each seeded board is verified as solvable and assigned a par score. Second, it powers instant feedback in the client. Third, it validates every submission on the server. The client only sends a move list, and the server replays it as the source of truth for the final score.

The ghost race uses a small move encoding. Each move is a cell and a direction. Since the board has at most 19 cells and 6 directions, one move fits into a single byte: 5 bits for the cell index and 3 bits for the direction. That means a 12-move solve is only about 12 bytes, which base64url-encodes to around 16 characters.

Challenges I ran into

The hardest part was making the two mechanics feel like one game. Peg solitaire and match-3 reward different types of thinking, so the pop rules had to be simple, atomic, and unambiguous. I also needed every board to be provably solvable, so I built a solver and fixture tests to make sure rule changes did not accidentally break old puzzles.

The Reddit webview also had some quirks. External network requests are not allowed, so every asset had to be bundled locally. The most annoying bug was on mobile: a clean tap fired a synthesized mouse event right after the touch event, which made every tap double-fire. Pegs would select and instantly deselect, and archive pages would skip. I fixed it by deduplicating the phantom event and handling input on press.

Another issue was that Devvit does not support arbitrary URL params the way I originally planned. My first challenge design assumed the board and ghost could live in a deep link. Since that was not possible, I moved the challenge flow into the Reddit comment context. A comment menu action resolves the run from Redis and sends the player into the race.

I also hit a Web Audio autoplay issue. Ghost replays could start before the player had tapped, which meant sounds were queued against a locked audio context and then all played at once on the first interaction. I had to gate audio until the player actually interacted with the game.

What I learned

This was my first Devvit app, so I learned the platform pretty thoroughly: scheduled daily posts, postData, Redis, menu actions, runAs rules, and the quirks of touch and audio inside a mobile webview.

The biggest lesson was how valuable a single pure core can be. One rules engine and solver powers the client, server, and offline tools, which keeps the game logic consistent and avoids drift between what the player sees and what the server scores.

What’s next

Next I want to add real user-authored challenge comments, tune the difficulty curve using live play data, and add one-tap board remixes so players can make puzzles for each other.

Built With

Share this project:

Updates

Submission history