First



# The Interrogator — Development Log
## ๐ฎ Project Overview
**The Interrogator** (Ukrainian: โะกะปัะดัะธะนโ) is an AI-powered detective game where players interrogate suspects to solve murder cases. Built as a single-page web application with a Cloudflare Worker backend.
- **Live Demo**: https://sashko1391.github.io/interrogator
- **Tech Stack**: Vanilla JS, Cloudflare Workers, Claude Sonnet 4, SDXL Lightning (Replicate)
- **Languages**: Ukrainian / English
-----
## ๐ Development Timeline
### Session 1: Foundation (v1.0 - v2.0)
**Initial concept:**
- 3 pre-built cases (Easy/Medium/Hard difficulty)
- Single suspect per case
- 10-question energy system
- Film noir aesthetic
**Key decisions:**
- Single HTML file architecture (no build tools)
- Cloudflare Worker as API proxy (keeps keys secure)
- Claude Haiku for NPC responses (later upgraded to Sonnet 4)
-----
### Session 2: AI Generation (v3.0)
**Major pivot: Dynamic case generation**
Instead of pre-built cases, the game now generates unique mysteries on-the-fly.
**New features:**
- `/generate` endpoint creates full case with Claude Sonnet 4
- 3 suspects per case (up from 1)
- Random guilt patterns: ONE / TWO / ALL / NONE guilty
- Tabbed UI for switching between suspects
- Per-suspect chat history and suspicion tracking
**Architecture:**
```
User โ Frontend โ Worker โ Claude API โ JSON Case
โ Replicate API โ Portrait Images
```
**Challenges solved:**
- JSON parsing from LLM (smart quotes, trailing commas)
- Guilty logic validation (auto-fix mismatches)
- Image generation polling (SDXL Lightning via Replicate)
-----
### Session 3: Hardening (v4.0)
**Security audit revealed critical issues:**
|Problem |Solution |
|-----------------------------------|--------------------------------------------|
|`/chat` as open Claude proxy |Validate game markers in system prompt |
|NERVOUSNESS: 999 injection |Clamp to 0-100, only increase |
|Image flooding (9 generations/user)|45s cooldown + cache by emotional state |
|JSON parsing failures |Brace counting, quote normalization |
|Guilty pattern mismatch |Auto-correct based on actual isGuilty values|
**Added:**
- Content-Length limit (50KB)
- Message length limit (1000 chars)
- Conversation length limit (50 messages)
- Request validation for all endpoints
-----
### Session 4: Scaling Features (v5.0)
**Cost optimization:**
1. **Case Caching**
- Store generated cases in KV
- New users get random cached case with fresh ID
- ~95% reduction in `/generate` Claude calls
1. **Smart Token Management**
- Questions 1-5: 500 tokens (full responses)
- Questions 6+: 200 tokens + โbe briefโ instruction
- ~60% token savings after question 5
**New features:**
1. **Daily Case**
- Same case for all users each day
- `GET /daily?lang=ua`
- Enables community discussion & comparison
1. **Streamer Mode**
- Unlimited questions (โ)
- Hidden guilty hints (no spoilers for chat)
- Toggle on start screen
1. **Statistics**
- Track plays and correct verdicts per case
- Show โYouโre in top X%โ after verdict
-----
### Session 5: Monetization (v6.0)
**Model: Freemium with soft limits**
|Tier |Limits |Price|
|---------------|--------------------------|-----|
|Free |3 cases + 50 questions/day|$0 |
|Daily Case |Unlimited |$0 |
|Premium 7 days |No limits |$5 |
|Premium 30 days|No limits |$10+ |
**Implementation:**
1. **IP-based daily limits** (stored in KV)
1. **Premium tokens** (format: `PRO-XXXXXXXXXXXX`)
1. **Email lookup flow** (no webhooks needed):
```
User donates โ Admin adds to KV โ User enters email โ Gets token
```
**Why not PayPal webhooks?**
- Donate button has no callbacks
- Would need PayPal Business account
- Manual flow works for indie scale
-----
### Session 6: Polish & UX Fixes
**Visual improvements:**
- 3-column category grid on desktop
- Daily Case card full-width below categories
- Case files open by default (player sees context immediately)
**Removed spoilers:**
- Guilty hint (โะะธะฝะฝั ะดะฒะพัโ) removed from header
- Players must deduce without hints
**Fixed last question bug:**
- Was: Question 15 โ instant โFAILโ (never see answer)
- Now: Question 15 โ see NPC response โ โTime to make verdict!โ โ player decides
-----
## ๐๏ธ Final Architecture
### Frontend (index.html)
```
โโโ Start Screen
โ โโโ Rules display
โ โโโ Category cards (War/History/Hollywood)
โ โโโ Daily Case card
โ โโโ Streamer Mode toggle
โ โโโ Limits display
โ โโโ Premium button
โโโ Loading Screen
โโโ Game Screen
โ โโโ Case header + ID
โ โโโ Energy & Suspicion bars
โ โโโ Case files (collapsible)
โ โโโ Suspect tabs (3)
โ โโโ Suspect panel (photo + profile)
โ โโโ Chat log
โ โโโ Input + Send
โ โโโ Action buttons (Verdict/Share/Restart/Reveal)
โโโ Modals
โโโ Result (Win/Lose)
โโโ Share
โโโ Verdict (checkboxes)
โโโ Premium
โโโ Limit reached
```
### Backend (worker.js)
```
GET /daily โ Daily case (free, unlimited)
GET /case/{id} โ Shared case lookup
GET /limits โ User's daily limits
GET /stats/{id} โ Case statistics
POST /generate โ Create new case (rate limited)
POST /chat โ NPC conversation (rate limited)
POST /image โ Portrait generation
POST /verdict โ Submit result for stats
POST /validate-premium โ Check token validity
POST /lookup-premium โ Get token by donor email
```
### KV Storage Structure
```
{caseId} โ Full case JSON (TTL: 2 weeks)
cache-{cat}-{lang} โ Array of cached case IDs (TTL: 4 weeks)
daily-{date}-{lang} โ Daily case (TTL: 2 days)
stats-{caseId} โ { played, correct, percentCorrect }
limits-{IP}-{date} โ { casesGenerated, questionsUsed }
premium-{token} โ { email, amount, created }
donor-{email} โ token string
```
-----
## ๐ Cost Analysis
### Per-session costs (estimated):
|Action |Model/Service |Cost |
|------------------|----------------------------------|----------|
|Generate case |Claude Sonnet 4 (~3K tokens) |~$0.02 |
|15 questions |Claude Sonnet 4 (~5K tokens total)|~$0.03 |
|3 portraits |Replicate SDXL |~$0.01 |
|**Total per game**| |**~$0.06**|
### With caching:
- 95% of `/generate` calls use cache โ $0.001
- Effective cost per game: **~$0.04**
### Break-even:
- $5 donation = 125 games covered
- $10 donation = 250 games covered
-----
## ๐ฏ Key Learnings
### What worked well:
1. **Single-file architecture** — Easy to deploy, no build complexity
1. **Cloudflare Workers** — Fast, cheap, global edge deployment
1. **Claude for NPCs** — Surprisingly good at staying in character
1. **NERVOUSNESS tag** — Simple but effective game mechanic
1. **Daily Case** — Community feature with zero extra cost
### What was tricky:
1. **LLM JSON output** — Always needs sanitization
1. **Image generation latency** — 10-25 seconds is rough UX
1. **PayPal integration** — Donate buttons have no callbacks
1. **IP-based limits** — Mobile networks share IPs
### What Iโd do differently:
1. Start with caching from day 1
1. Use tool/function calls for structured LLM output
1. Consider pre-generating image variants
1. Add fingerprinting alongside IP for limits
-----
## ๐ Future Ideas
### Near-term:
- [ ] PayPal webhooks for auto-premium
- [ ] Pre-generated daily cases (cron job)
- [ ] Leaderboard for daily case
### Medium-term:
- [ ] Multiplayer mode (same case, compare results)
- [ ] Case difficulty rating based on solve rate
- [ ] Achievement system
### Long-term:
- [ ] White-label for training/HR
- [ ] Mobile app (React Native)
- [ ] Voice input/output
-----
## ๐ File Structure
```
/interrogator
โโโ index.html # Complete frontend (single file)
โโโ worker.js # Cloudflare Worker backend
โโโ bg-landscape.jpg # Background (16:9)
โโโ bg-portrait.jpg # Background (9:16)
โโโ background.mp3 # Ambient music
โโโ p_machine.mp3 # Typewriter sound effect
```
-----
## ๐ Credits
- **AI Models**: Claude Sonnet 4 (Anthropic), SDXL Lightning (Stability AI)
- **Hosting**: GitHub Pages (frontend), Cloudflare Workers (backend)
- **Design**: Film noir aesthetic, Playfair Display + Crimson Pro fonts
-----
*Last updated: January 31, 2026*
*Total development time: ~ 18 hours across multiple sessions*
Files
The Interrogator
An AI-powered detective game where suspects lie, remember, and crack under pressure.
| Status | Released |
| Author | Sashko1391 |
| Genre | Interactive Fiction |
| Tags | Detective, Meaningful Choices, Noir |
Comments
Log in with itch.io to leave a comment.
First release is live.
Feedback on difficulty and suspect behavior is especially welcome.