Inspiration

I love how daily puzzles bring people together. Wordle nails the “one more try” loop, but I wanted a friendlier vibe that’s easy to pick up and share in communities. Emojis felt like the perfect hint mechanic: playful, language‑agnostic, and expressive. WordEmoji blends daily Wordle‑style logic with three‑emoji clues and a lightweight, mobile‑first UI—built to live natively inside Reddit via Devvit.

What it does

  • 10 daily puzzles, shared globally, with words of length 3–6
  • Simple tile feedback (green/yellow/gray) and on‑screen keyboard
  • Three‑emoji hint per puzzle (with “❓❓❓” fallback)
  • Stats and streaks, guess distribution, and a global top‑10 leaderboard
  • Archive to replay past days; “come back tomorrow” gating once you finish
  • Smooth UX: confetti on wins, shake on invalid guesses, and a clean, colorful theme

How I built it

  • Platform: Devvit (Reddit WebView), split into client and server bundles
  • Client: TypeScript + Vite, custom CSS (no frameworks), Google Font “Nunito”
  • Server: Express (TypeScript) + Devvit services (Reddit context, Redis)
  • Data:
    • Client: localStorage for daily progress and personal stats
    • Server: Redis for daily archives and leaderboard
  • Integration:
    • Optional OpenAI (gpt‑4o‑mini) to generate daily word+emoji sets (with caching and validation)
    • Fallback deterministic generation to guarantee playability even if the network or model fails

Architecture at a glance

  • Client pages: index.html (game), stats.html, archive.html
  • Multi‑page build via Vite rollup inputs; assets served through Devvit’s WebView
  • API endpoints: /api/daily, /api/dates, /api/leaderboard, /api/emoji-hint, and simple health/test routes
  • Scheduler: UTC midnight safety to ensure today’s set exists (when using server‑side generation)
  • Auth: Devvit’s webbit_token attached to all /api/* requests, persisted across navigation

Daily challenge mechanics

  • If server generation is available, each day is archived once and shared globally.
  • Otherwise, a deterministic client fallback ensures the day is playable for everyone.
  • Archive lists all previous days (newest first), 4 per page; you can jump directly into any day.

A simple math sketch of the deterministic fallback:

  • Use the UTC date key ( d = \text{YYYY-MM-DD} ).
  • Hash the seed and drive a shuffle: [ s_0 = h(d), \quad s_{n+1} = \text{XorShift}(s_n), \quad \text{index} = s_n \bmod N ]
  • Select the first 10 words after a seeded shuffle, guaranteeing the same set for the same date.

Time‑to‑midnight countdown (local): [ \Delta t = \text{midnight(local, today+1)} - \text{now(local)} ] Displayed as ( h )h ( m )m ( s )s on completion.

Leaderboard and stats

  • Leaderboard stores the top 10 daily performers by total time for all 10 puzzles
  • Users identified by Reddit username (with a safe fallback to “anonymous”)
  • Personal stats stored client‑side: games played/won, streaks, and guess distribution
  • Win rate: [ \text{WinRate} = \frac{\text{wins}}{\text{played}} \times 100\% ]

What I learned

  • Devvit’s WebView and asset pipeline: building multi‑page apps that feel native to Reddit
  • Reliable token propagation: making sure webbit_token is appended to every API request and survives cross‑page navigation
  • Resilient UX: always provide a deterministic fallback when external services (OpenAI, settings) aren’t available
  • Data design for a daily model: archives, no‑repeat logic, and simple, readable Redis structures
  • Prompt engineering for balanced puzzle difficulty and consistent emoji quality

Challenges and how I solved them

  • Token stability: API calls initially failed with “missing webbit_token.” I added a global fetch wrapper that appends the token as both query param and bearer header, plus persisted it in sessionStorage/localStorage so it survives navigation.
  • Devvit settings/secrets and environment drift: Guarded against missing settings, added a “test” panel with explicit status outputs, and allowed a local key header during playtest.
  • Redis API differences: When native set ops weren’t available, I switched to JSON‑array backed helpers to emulate sets reliably.
  • OpenAI model quirks: Some models reject max_tokens; swapped to gpt‑4o‑mini, adjusted parameters, and cached results—with validation of word length (3–6) and uniqueness.
  • UI polish on mobile: Tightened spacing, ensured tiles match word length, added safe‑area padding, and removed blocking loaders in favor of immediate gameplay.

Design choices

  • Friendly, colorful brand: rainbow tile logo, soft backgrounds, bold typography
  • Motion that informs: shake for errors, confetti on win, subtle hover/press states
  • Clear affordances: concise messages, distinct “Stats” (red) and “Archive” (purple), disabled “Play” with “come back tomorrow” when finished

What’s next

  • Community sharing of daily results with emoji tiles
  • Better hint explanations for more challenging words
  • Optional accessibility mode (higher contrast and reduced motion)

WordEmoji aims to be a daily ritual that’s approachable, joyful, and built to thrive inside Reddit’s ecosystem—fast, resilient, and fun.

Built With

Share this project:

Updates

Submission history