Karma Kriminals

Inspiration

Reddit already has a thriving culture of community detective work - from r/UnresolvedMysteries to collaborative ARGs to the classic "Reddit solves it" moments. We wanted to channel that energy into a structured daily game that brings communities together.

The core idea: what if every day, your subreddit got a new mystery to solve together? Not just a quiz - a proper investigation where you examine evidence, interrogate suspects, weigh alibis against motives, and make your accusation before the clock runs out. The social element is key: evidence stays classified until enough community members vote, so participation directly unlocks new clues for everyone.

We drew inspiration from daily games like Wordle (the "one puzzle per day" cadence that keeps people coming back), social deduction games like Among Us and Mafia (the accusation and voting mechanics), and detective shows where you piece together evidence before the big reveal.

What It Does

Karma Kriminals is a daily mystery game that lives natively inside Reddit posts. Every day, a new case drops with:

  • Evidence to examine - Physical evidence, witness accounts, forensic analysis, and red herrings. Each piece is categorized and expandable. Some classified intel stays locked until enough players vote, creating a community-driven unlock mechanic.
  • Suspects to interrogate - Each suspect has a name, motive, alibi, and background. Players review the profiles and make their accusation.
  • A countdown timer - When time runs out, the case is revealed with a dramatic phased animation showing the guilty party, full explanation, and how the community voted.
  • Streaks and leaderboards - Correct guesses earn points with streak bonuses for consecutive daily solves. Weekly and all-time rankings keep competition alive.
  • An inline splash card - The post appears directly in the subreddit feed showing the case number, difficulty, detective count, and countdown, drawing players in.

How We Built It

Stack: Devvit Web (React 19 + Tailwind CSS 4 + Hono + TypeScript)

The app uses Devvit's two-entrypoint pattern:

  • splash.html renders as an inline Reddit post showing the case overview and a call-to-action
  • game.html opens in expanded mode with the full investigation UI (tabbed interface with Evidence, Suspects, Case File, and Rankings)

Server: Hono handles four API endpoints (/mystery, /vote, /leaderboard, /reveal). All state is stored in Devvit Redis using hashes and sorted sets - vote counts, user votes, investigator tracking, user stats (streak, accuracy, total played), and leaderboard scores.

Key architecture decisions:

  • Mystery content is a static bank of 7 handcrafted cases that rotate daily based on a start date. No external API dependencies means zero downtime.
  • Scoring happens server-side in the /reveal endpoint with deduplication (each user is scored exactly once per day). Streak bonuses reward consecutive correct guesses.
  • Evidence unlock thresholds are tied to total community votes, not individual progress - this incentivizes participation.
  • The inline splash fetches lightweight data to show real-time stats (detective count, timer, vote count) without loading the full game.

Challenges We Faced

Asset caching on existing posts. This was the biggest headache. After uploading new versions, existing Reddit posts kept serving old cached client assets. We went through five version uploads wondering why our UI changes weren't showing up. The fix was discovering npx devvit playtest which creates a fresh session with live-reloading - but this wasn't obvious from the docs and cost us hours of debugging.

Devvit Redis limitations. The Redis API doesn't support Set operations (sAdd, sCard, etc.), only hashes, sorted sets, and basic key-value. We had to rethink our data model - tracking unique investigators with hSet + hLen instead of sAdd + sCard, and using zRange with { by: 'rank', reverse: true } for descending leaderboard queries.

No emoji rendering consistency. Early versions used emoji for evidence types, suspect avatars, and the tab bar. Rendering was inconsistent across platforms and looked unprofessional. We replaced everything with inline SVG icons and CSS-based visuals (color-coded initials for suspects, type-specific icons for evidence), which gave us full control over the look.

Timing the reveal cycle. Getting the daily reveal mechanic right was tricky. The reveal needs to happen at a consistent time (10 PM UTC), scoring needs to be idempotent (can't double-count if a user refreshes), and the client countdown needs to stay synced with the server's reveal state. We solved this with server-authoritative reveal checks and a scored hash to prevent duplicate scoring.

What We Learned

  • Devvit Web is genuinely powerful for building interactive Reddit experiences, but the developer experience around deployment and caching has sharp edges that need patience to work through.
  • Daily games create a compelling retention loop. The "one mystery per day" constraint is what makes it feel special - you can't binge, so you come back tomorrow.
  • Community-driven mechanics (vote-to-unlock evidence) add a layer of engagement that purely single-player puzzles miss. It turns passive scrolling into active participation.
  • Keeping the tech stack simple (static mystery bank, no external APIs, pure Redis state) eliminates entire categories of bugs and makes the app reliable from day one.

What's Next for Karma Kriminals

  • Community-submitted mysteries - Let subreddit mods create custom cases themed to their community
  • Difficulty-based scoring - Higher point multipliers for hard cases
  • Suspect interrogation mechanic - Ask suspects questions that consume a limited number of "interview tokens"
  • Cross-subreddit tournaments - Weekly competitions between communities
  • Achievement badges - Unlock Reddit flair based on solve streaks and accuracy

Built With

  • devvit
Share this project:

Updates