Lex Run
A daily word roguelite, playable right inside Reddit.
Inspiration
I've been fascinated by Balatro and how it turns a familiar card game into something you can't put down. I wondered what would happen if I applied that roguelite formula to something even more familiar than poker: a word game.
That became Lex Run. You build words from a rack of seven letter tiles across four rounds of increasing difficulty, picking buff cards between rounds that stack into absurd score multipliers. Everyone plays the same seeded daily challenge and competes on a shared leaderboard, so there's always a "one more run" reason to come back tomorrow.
How I built it
I was new to almost everything in this stack: new to Phaser, new to Devvit, and honestly new to Reddit as a platform. Devvit's Phaser template was a huge head start, shipping with the frontend and backend already wired together.
- Frontend: Phaser 4 + Vite in Devvit's webview, with tap-to-select tiles.
- Backend: Hono routes on Devvit's serverless Node environment, with Redis for storage.
- One source of truth for scoring: a single shared
scoreWordfunction is called by both the client (for instant feedback) and the server (as the authority that verifies every run before it touches the leaderboard). - Seeded daily challenges: each day's racks and buffs derive from a seeded RNG keyed by the date, so every player gets the same run and the server can verify scores by replaying the seed.
Claude was my pair programmer throughout, and I reworked the entire look and feel with the help of Claude's design capabilities. For the trailer, I learned Remotion: the whole video is React code, so recutting the master into shorter and square variants is just another build step.
Challenges I ran into
Making it fun before making it big. The word-roguelite mash-up only clicked after prototyping how buffs, scoring, and escalating targets feed into each other. Most of my polish time went into juice: animations, sound, and satisfying feedback on every tap.
Performance on real devices. Drawing rounded rectangles at runtime was slow, so I replaced them with sprites drawn in Inkscape and packed into a single texture atlas at build time.
Keeping client and server honest. Optimistic client scoring plus an authoritative server means any drift causes rejected runs. The fix: all scoring, rack, and buff logic lives in one shared module both sides import.
What I learned
- A good template is worth days of setup.
- Juice is the feature: polish on the core loop beats adding another system.
- Share logic, don't duplicate it: one scoring function used by both client and server eliminated a whole class of bugs.
- Seed-driven design makes shared dailies, leaderboards, and score verification almost free.
- AI is a genuine force multiplier for a solo dev: design, code, and even the trailer pipeline.
What's next
Porting Lex Run to mobile with Capacitor
Built With
- devvit
- phaser.js
Log in or sign up for Devpost to join the conversation.