Enable real-time fight spectating for all live fights (not just human fights). Multiple spectators can watch simultaneously via SSE. Spectator count is tracked per-fight and broadcast with every SSE event. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
558 lines
23 KiB
Markdown
558 lines
23 KiB
Markdown
# Botfights: 6-Month Development Plan (March–September 2026)
|
||
|
||
## Current State (March 8, 2026)
|
||
|
||
Botfights is a competitive AI fighting game (Vue 3 + Kaplay + Hono/SQLite) where bots battle through challenge rounds with pixel art sprites, synthesized audio, and choreographed fight animations. The core is feature-complete:
|
||
|
||
| Category | Count | Status |
|
||
|----------|-------|--------|
|
||
| Archetypes | 101 (100 + THE CREATOR) | Done |
|
||
| Choreographies | 352+ (300 base + 40 tier-gated + 12 creator) | Done |
|
||
| Challenge Types | 16 | Done |
|
||
| Challenge Prompts | 800 (551 multiple-choice, 249 creative) | Done |
|
||
| Mock Bots | 100 (tiers 0–6) | Done |
|
||
| Arenas | 25 with modifiers | Done |
|
||
| Voice Profiles | 60+ | Done |
|
||
| Music Tracks | 10 procedural synth | Done |
|
||
| Sound Effects | 30+ | Done |
|
||
| Pages | 20 | Done |
|
||
| Nostr Auth | NIP-04/44/19 | Done |
|
||
| Payments | NWC + Lightning Address + Cashu | Done |
|
||
| PWA | Manifest + SW + offline assets | Done |
|
||
| Docker | Multi-stage, 42MB prod image | Done |
|
||
| TUI Fight Loop | Live round-by-round | Done |
|
||
| Production Hardening | Security headers, SSRF, rate limiting, graceful shutdown | Done |
|
||
|
||
**FightScene.ts** is 11,313 lines. The codebase works end-to-end but hasn't been battle-tested with real users at scale.
|
||
|
||
---
|
||
|
||
## Month 1: Social Layer & Real-Money Launch (March 9 – April 5)
|
||
|
||
Goal: Make botfights a place people want to hang out and bet sats.
|
||
|
||
### Week 1: Spectator Experience
|
||
|
||
#### 1.1 Live Fight Spectating via SSE
|
||
**Files:** `server/src/routes/fights.ts`, `frontend/src/pages/FightPage.vue`
|
||
- SSE endpoint streams round results, HP changes, challenge reveals in real-time
|
||
- Multiple spectators can watch a live fight simultaneously
|
||
- Auto-redirect from fight card to live view when fight starts
|
||
- Spectator count badge on active fights
|
||
|
||
#### 1.2 Fight Feed / Activity Stream
|
||
**New file:** `frontend/src/pages/FeedPage.vue`
|
||
- Reverse-chronological feed of recent fights: winner, KO/decision, Elo changes
|
||
- Filter by tier, arena, bot name
|
||
- Click any fight to watch replay
|
||
- Replace or augment current HomePage with this
|
||
|
||
#### 1.3 Reactions / Crowd Noise
|
||
**Files:** `frontend/src/components/FightViewer.vue`, `server/src/routes/fights.ts`
|
||
- Spectators can send emoji reactions during live fights (fist, fire, skull, 100, clown)
|
||
- Reactions appear as floating particles over the fight
|
||
- Server aggregates reactions, broadcasts via SSE
|
||
- Crowd SFX intensity scales with reaction count
|
||
|
||
### Week 2: Betting System UI
|
||
|
||
#### 2.1 Bet Placement UI
|
||
**Files:** `frontend/src/components/BetPanel.vue`, `frontend/src/pages/FightCardPage.vue`
|
||
- Pre-fight bet panel: pick winner, set amount (21/100/500/1000 sats)
|
||
- Cashu token deposit flow (paste token or scan QR)
|
||
- NWC direct-pay option for connected wallets
|
||
- Odds display based on Elo difference
|
||
- Bet confirmation with payout preview
|
||
|
||
#### 2.2 Bet Settlement & Payout
|
||
**Files:** `server/src/engine/betting.ts`, `server/src/engine/payments.ts`
|
||
- Atomic settlement on fight completion
|
||
- Winner payout minus 5% house cut (goes to fight pot for ranked matches)
|
||
- Cashu token minting for winnings OR Lightning payout
|
||
- Refund on cancelled/errored fights
|
||
|
||
#### 2.3 Betting History
|
||
**Files:** `frontend/src/pages/BotProfilePage.vue`, new `frontend/src/components/BetHistory.vue`
|
||
- Personal bet history on profile page
|
||
- P&L tracking (total wagered, total won, net)
|
||
- "Hot streak" and "cold streak" indicators
|
||
|
||
### Week 3: Nostr Social Integration
|
||
|
||
#### 3.1 Fight Results to Nostr
|
||
**New file:** `server/src/engine/nostr-publish.ts`
|
||
- Post NIP-01 kind:1 notes for notable fights (KOs, perfects, upsets, tier changes)
|
||
- Include fight replay link, bot names, Elo changes
|
||
- Configurable relay list via env var
|
||
- Only publish if `BOTFIGHTS_NOSTR_NSEC` is set
|
||
|
||
#### 3.2 Nostr Profile Enrichment
|
||
**Files:** `frontend/src/composables/useNostr.ts`, `frontend/src/pages/BotProfilePage.vue`
|
||
- Fetch NIP-05, display name, banner from Nostr relays
|
||
- Show Nostr profile picture alongside bot sprite
|
||
- Link to user's Nostr profile (njump.me or similar)
|
||
|
||
#### 3.3 Zap Integration
|
||
**Files:** `frontend/src/components/FightViewer.vue`, `server/src/routes/payments.ts`
|
||
- "Zap the winner" button after fight ends
|
||
- NWC zap flow: create invoice, user approves, confirm
|
||
- Zap receipts displayed on bot profile
|
||
|
||
### Week 4: Ranked Season System
|
||
|
||
#### 4.1 Season Framework
|
||
**New file:** `server/src/engine/seasons.ts`
|
||
- Season = 2 weeks, auto-rotates
|
||
- Season Elo resets to soft floor (blend of final Elo + 1200 baseline)
|
||
- Season leaderboard separate from all-time
|
||
- Season rewards: title badges, exclusive arena unlocks
|
||
|
||
#### 4.2 Season Leaderboard UI
|
||
**Files:** `frontend/src/pages/LeaderboardPage.vue`
|
||
- Toggle between "This Season" and "All Time"
|
||
- Season countdown timer
|
||
- Top 3 highlighted with crown/medal sprites
|
||
- Season history archive
|
||
|
||
#### 4.3 Ranked Queue Improvements
|
||
**Files:** `server/src/engine/ranked-queue.ts`, `frontend/src/pages/JoinBoutPage.vue`
|
||
- Elo-bracket matchmaking (±200 Elo, widens over time)
|
||
- Ranked queue status indicator (how many waiting)
|
||
- Estimated wait time
|
||
- Ranked-only challenges (harder prompts, no multiple choice)
|
||
|
||
---
|
||
|
||
## Month 2: Tournaments, Human Play & Content Expansion (April 6 – May 3)
|
||
|
||
Goal: Structured competition and enough content that nothing feels repetitive.
|
||
|
||
### Week 5: Tournament System
|
||
|
||
#### 5.1 Tournament Engine
|
||
**New files:** `server/src/engine/tournaments.ts`, `server/src/db/schema.ts` (new tables)
|
||
- Single-elimination brackets (8, 16, 32 bots)
|
||
- Round-robin group stage option
|
||
- Entry fee (configurable sats amount) → prize pool
|
||
- Auto-advance winners, schedule next round
|
||
- DB tables: `tournaments`, `tournament_entries`, `tournament_matches`
|
||
|
||
#### 5.2 Tournament UI
|
||
**New files:** `frontend/src/pages/TournamentPage.vue`, `frontend/src/pages/TournamentListPage.vue`
|
||
- Visual bracket display (SVG or canvas)
|
||
- Live bracket updates as fights complete
|
||
- Tournament lobby: registered bots, countdown to start
|
||
- Results page with champion highlight
|
||
|
||
#### 5.3 Scheduled Tournaments
|
||
**Files:** `server/src/engine/fight-loop.ts`, `server/src/engine/tournaments.ts`
|
||
- Daily automated tournaments (e.g., 8pm UTC)
|
||
- "The Halvening" weekly 32-bot major tournament
|
||
- Special themed tournaments (code-golf only, roast-battle only)
|
||
- Cron-based scheduling via fight loop
|
||
|
||
### Week 6: Human vs Bot Improvements
|
||
|
||
#### 6.1 Human Fight Polish
|
||
**Files:** `frontend/src/pages/HumanFightPage.vue`, `server/src/engine/human-responses.ts`
|
||
- Fix the TODO in human-responses.ts (currently `pass # TODO: implement`)
|
||
- Mobile-optimized input (large buttons for multiple choice, big text area for creative)
|
||
- Countdown timer with visual urgency (color shift, shake)
|
||
- Immediate feedback after answering (correct/wrong animation)
|
||
|
||
#### 6.2 Practice Mode
|
||
**New file:** `frontend/src/pages/PracticePage.vue`
|
||
- Fight against mock bots without Elo impact
|
||
- Choose difficulty tier
|
||
- Post-fight breakdown: which rounds you won/lost and why
|
||
- Suggested improvements
|
||
|
||
#### 6.3 Human vs Human
|
||
**Files:** `server/src/engine/orchestrator.ts`, `server/src/routes/queue.ts`
|
||
- Real-time matchmaking for two human players
|
||
- Both answer same challenge simultaneously
|
||
- WebSocket or SSE for synchronization
|
||
- Elo-rated human ladder separate from bot ladder
|
||
|
||
### Week 7: Content Scaling
|
||
|
||
#### 7.1 Challenge Prompts → 2,000
|
||
**Files:** `server/src/engine/challenges.ts`
|
||
- 75 more prompts per existing 16 types = 1,200 new prompts
|
||
- Focus on Bitcoin/cypherpunk themed prompts:
|
||
- "What year was the Bitcoin whitepaper published?"
|
||
- "Explain proof-of-work to a medieval blacksmith"
|
||
- "Roast someone who thinks Ethereum is decentralized"
|
||
- "Write a haiku about the mempool"
|
||
- All factual types get multiple-choice options
|
||
- Difficulty tiers: easy (tier 0–2 fights), medium (3–4), hard (5–6)
|
||
|
||
#### 7.2 Music Tracks → 20
|
||
**Files:** `frontend/src/game/sounds.ts`
|
||
- 10 new procedural tracks:
|
||
- 2x Drum & Bass (170–175 BPM)
|
||
- 2x Lo-fi Hip Hop (90–100 BPM)
|
||
- 2x Ska Punk (200–220 BPM)
|
||
- 2x Boss Fight (140–160 BPM, heavy)
|
||
- 2x Chiptune (180–200 BPM)
|
||
- Intensity-grouped: low (lo-fi, chiptune), mid (ska, D&B), high (boss fight)
|
||
|
||
#### 7.3 Arenas → 40
|
||
**Files:** `server/src/engine/arenas.ts`, `frontend/src/game/FightScene.ts`
|
||
- 15 new arenas:
|
||
- bitcoin_mine (hash_power modifier)
|
||
- lightning_node (speed_3x)
|
||
- satoshis_garage (legacy_code)
|
||
- mempool (chaos_mode)
|
||
- silk_road_ruins (trap_heavy)
|
||
- block_height_tower (accuracy_buff)
|
||
- hodl_cave (endurance_2x)
|
||
- whale_pool (high_stakes)
|
||
- node_farm (efficiency_buff)
|
||
- genesis_block (all_types)
|
||
- pizza_day_parlor (food_2x)
|
||
- difficulty_adjustment (adaptive)
|
||
- 51_percent_arena (chaos_mode)
|
||
- timechain_temple (speed_2x)
|
||
- nostr_relay_room (crowd_favorite)
|
||
- Each with unique theme colors and background elements
|
||
|
||
### Week 8: Choreography & Animation Polish
|
||
|
||
#### 8.1 Choreographies → 500
|
||
**Files:** `frontend/src/game/FightScene.ts`
|
||
- 148 new choreographies across categories:
|
||
- 30 Bitcoin-themed (lightning_bolt, hash_smash, block_drop, mempool_flood, difficulty_bomb, fee_spike, utxo_scatter, node_sync, relay_bounce, channel_force_close, etc.)
|
||
- 25 more food moves
|
||
- 25 more energy/beam moves
|
||
- 20 more silly/absurd moves
|
||
- 20 more weapon moves
|
||
- 15 more vehicle moves
|
||
- 13 more animal moves
|
||
- Wire into CHALLENGE_THEMED with balanced distribution
|
||
|
||
#### 8.2 Entrance Animations
|
||
**Files:** `frontend/src/game/FightScene.ts`
|
||
- 10 new tier-gated entrances:
|
||
- Tier 0–1: simple walk-in
|
||
- Tier 2: slide in with dust
|
||
- Tier 3: drop from above with impact shake
|
||
- Tier 4: teleport with lightning flash
|
||
- Tier 5: dramatic slow-mo entrance with camera zoom
|
||
- Tier 6: custom per-bot entrance (THE CREATOR golden portal already done)
|
||
|
||
#### 8.3 Victory Celebrations
|
||
**Files:** `frontend/src/game/FightScene.ts`
|
||
- Post-fight victory animations tied to finish type:
|
||
- KO: winner flexes, camera flash effect
|
||
- Perfect: winner does victory lap, confetti rain
|
||
- Decision: both bow, crowd cheers
|
||
- Upset: dramatic zoom on winner, shocked crowd SFX
|
||
|
||
---
|
||
|
||
## Month 3: Scale, Polish & Launch (May 4 – May 31)
|
||
|
||
Goal: Production-ready for real users, real sats, real competition.
|
||
|
||
### Week 9: FightScene.ts Decomposition
|
||
|
||
#### 9.1 Split the Monolith
|
||
FightScene.ts at 11,313 lines is the single biggest maintenance risk. Split into focused modules:
|
||
|
||
```
|
||
frontend/src/game/fight/
|
||
index.ts -- createFightScene() orchestrator
|
||
types.ts -- FightContext, shared interfaces
|
||
constants.ts -- arena themes, sprite anims, positions
|
||
particles.ts -- all particle spawn functions
|
||
projectiles.ts -- projectile spawning and physics
|
||
effects.ts -- screen effects (glitch, scanline, VHS, etc.)
|
||
grotesque.ts -- close-up detail system
|
||
arena.ts -- arena background rendering
|
||
entrances.ts -- bot entrance animations
|
||
morphs.ts -- morph system (elemental, mech, beast, omni)
|
||
choreography/
|
||
index.ts -- choreographyMap, pickChoreography
|
||
registry.ts -- CHALLENGE_THEMED, critMoves
|
||
basic.ts -- punches, kicks, slams
|
||
ranged.ts -- projectiles, guns, beams
|
||
heavy.ts -- ground pounds, body slams
|
||
weapons.ts -- swords, hammers, etc.
|
||
food.ts -- food-themed moves
|
||
silly.ts -- absurd/comedy moves
|
||
bitcoin.ts -- Bitcoin-themed moves
|
||
creator.ts -- THE CREATOR exclusive moves
|
||
ultimates.ts -- tier-gated ultimate moves
|
||
finishers.ts -- KO styles, perfect finish
|
||
round.ts -- playRound, playTaunt, playDodge
|
||
camera.ts -- camera shake, zoom, pan
|
||
hud.ts -- HP bars, round counter, timer
|
||
```
|
||
|
||
- Zero behavior changes — pure refactor
|
||
- Each module receives FightContext object
|
||
- Test: replay 50 fights, verify identical behavior
|
||
|
||
### Week 10: Performance & Mobile
|
||
|
||
#### 10.1 Performance Optimization
|
||
- Profile FightScene with Chrome DevTools
|
||
- Reduce particle count on mobile (detect via `navigator.maxTouchPoints`)
|
||
- Lazy-load Kokoro TTS model (2.2MB) — don't block initial render
|
||
- Sprite sheet atlas: batch all archetypes into single texture
|
||
- RequestAnimationFrame budget monitoring — drop effects if frame time > 16ms
|
||
|
||
#### 10.2 Mobile UX Polish
|
||
**Files:** Various frontend components
|
||
- Touch-friendly bet panel (large tap targets, swipe gestures)
|
||
- Responsive fight viewer (portrait mode layout)
|
||
- Bottom navigation bar for mobile
|
||
- Haptic feedback on hits (Vibration API)
|
||
- Reduced motion mode (prefers-reduced-motion)
|
||
|
||
#### 10.3 Offline / Weak Connection
|
||
- Queue position preserved on reconnect (SSE retry)
|
||
- Optimistic UI for bet placement
|
||
- Replay cache: save last 10 watched fights for offline replay
|
||
- Connection status indicator
|
||
|
||
### Week 11: Admin, Analytics & Bot Developer Experience
|
||
|
||
#### 11.1 Admin Dashboard
|
||
**New files:** `frontend/src/pages/AdminPage.vue`, `server/src/routes/admin.ts`
|
||
- Protected by THE CREATOR pubkey (only admin)
|
||
- Live stats: active fights, queue depth, bets in escrow, total sats moved
|
||
- Bot management: deactivate, reset Elo, ban
|
||
- Challenge management: add/remove prompts, preview scoring
|
||
- Fight log viewer with full round details
|
||
- System health: DB size, memory, uptime
|
||
|
||
#### 11.2 Privacy-Respecting Analytics
|
||
**New file:** `server/src/engine/analytics.ts`
|
||
- No PII, no cookies, no third-party scripts
|
||
- Aggregate counts only: fights/day, unique bots/day, sats wagered/day
|
||
- Stored in SQLite, queryable from admin dashboard
|
||
- Public stats endpoint for transparency: `GET /api/stats/public`
|
||
|
||
#### 11.3 Bot Developer Docs
|
||
**Files:** `frontend/src/pages/DocsPage.vue`
|
||
- Interactive API explorer (try endpoints from the browser)
|
||
- Webhook payload examples for all 16 challenge types
|
||
- Response format with scoring breakdown
|
||
- "Build your first bot" tutorial (curl, Python, Node examples)
|
||
- Webhook testing tool (send test challenge, see response + score)
|
||
|
||
### Week 12: Launch Prep & Stress Testing
|
||
|
||
#### 12.1 Load Testing
|
||
- Simulate 100 concurrent spectators on single fight
|
||
- Simulate 20 concurrent fights
|
||
- Simulate 50 concurrent bet placements
|
||
- SQLite WAL mode verification under write contention
|
||
- Memory profiling under sustained fight-loop operation (24hr soak test)
|
||
|
||
#### 12.2 Backup & Recovery
|
||
**New file:** `server/src/engine/backup.ts`
|
||
- Automated SQLite backup to file (daily rotation, keep 7)
|
||
- Export fight history as JSON (for Nostr archival)
|
||
- Elo snapshot before season reset (rollback safety)
|
||
|
||
#### 12.3 Launch Checklist
|
||
- [ ] All 16 challenge types tested end-to-end with real webhook
|
||
- [ ] NWC payment flow tested with real sats (testnet then mainnet)
|
||
- [ ] Cashu token deposit + withdrawal tested
|
||
- [ ] Betting flow: place bet → watch fight → receive payout
|
||
- [ ] Tournament: create → fill → run → settle prizes
|
||
- [ ] Human fight: join queue → answer challenges → see result
|
||
- [ ] Mobile: full flow on iOS Safari + Android Chrome
|
||
- [ ] PWA: install → offline → reconnect → resume
|
||
- [ ] TUI fight loop: 24hr soak test without crash
|
||
- [ ] Docker: fresh build → deploy → health check → seed → fight
|
||
- [ ] Nostr: fight results published to relay, zaps working
|
||
- [ ] Security: rate limiting, SSRF, body limits, error hiding verified
|
||
- [ ] THE CREATOR: all exclusive features working (entrance, morphs, cameo, moves)
|
||
- [ ] Bundle size < 300KB gzipped (run `npx vite-bundle-visualizer`)
|
||
- [ ] Memory: 50-fight replay stays flat (Chrome DevTools heap snapshot)
|
||
- [ ] Server: 24hr fight-loop RSS < 250MB
|
||
- [ ] Mobile: fight loads in < 2s on throttled 4G
|
||
- [ ] SQLite: indexes verified, WAL mode enabled, p95 query < 50ms
|
||
|
||
---
|
||
|
||
## Performance & Footprint (Continuous Thread)
|
||
|
||
Performance is not a one-week task — it's a discipline that runs across all 3 months. Every feature addition must respect these budgets.
|
||
|
||
### Budgets
|
||
|
||
| Metric | Target | Current Estimate |
|
||
|--------|--------|-----------------|
|
||
| Initial JS bundle | < 300KB gzipped | Audit needed |
|
||
| Kokoro TTS model | Lazy-load, < 2.2MB | 2.2MB (loaded eagerly) |
|
||
| Sprite sheet per bot | < 15KB PNG | ~8KB |
|
||
| Fight replay memory | < 80MB peak | Unknown (profile needed) |
|
||
| Server memory (idle) | < 100MB RSS | ~60MB |
|
||
| Server memory (fight-loop 24hr) | < 250MB RSS | Unknown |
|
||
| Docker image | < 50MB | 42MB |
|
||
| SQLite DB after 10K fights | < 200MB | ~5MB (100 fights) |
|
||
| Time to first fight frame | < 2s on 4G | Unknown |
|
||
| SSE reconnect | < 1s | Unknown |
|
||
|
||
### Month 1 Performance Tasks
|
||
|
||
#### P1.1 Bundle Audit & Tree-Shaking
|
||
- Run `npx vite-bundle-visualizer` to identify bloat
|
||
- Verify Kaplay tree-shakes unused modules
|
||
- Verify nostr-tools only imports what's needed (not full bundle)
|
||
- Code-split routes: lazy-load all pages except HomePage
|
||
- Target: identify top 3 bundle offenders and fix
|
||
|
||
#### P1.2 Kokoro TTS Lazy Loading
|
||
**Files:** `frontend/src/game/sounds.ts`
|
||
- Don't load the 2.2MB Kokoro model on page load
|
||
- Load on first fight start (with loading indicator)
|
||
- Cache in service worker after first load
|
||
- Fallback to Web Speech API while loading
|
||
|
||
#### P1.3 Sprite Atlas
|
||
**Files:** `frontend/src/game/sprites/`
|
||
- Currently generates sprite sheets per-bot at fight time
|
||
- Pre-generate common archetypes into a shared atlas texture
|
||
- Single GPU texture upload instead of per-bot
|
||
- Reduces fight init time and GPU memory
|
||
|
||
#### P1.4 SSE Connection Pooling
|
||
**Files:** `server/src/routes/fights.ts`
|
||
- Ensure SSE connections are properly cleaned up on client disconnect
|
||
- Add connection limit per IP (max 5 concurrent SSE streams)
|
||
- Heartbeat every 15s to detect dead connections
|
||
- Memory: track active SSE count in admin stats
|
||
|
||
### Month 2 Performance Tasks
|
||
|
||
#### P2.1 Fight Replay Memory Profiling
|
||
- Profile memory during 10-fight replay session
|
||
- Identify particle/sprite leaks (Kaplay objects not destroyed)
|
||
- Add `fight.destroy()` cleanup that nulls all references
|
||
- Test: play 50 fights consecutively, memory should stay flat
|
||
|
||
#### P2.2 Choreography Performance Tiers
|
||
**Files:** `frontend/src/game/FightScene.ts`
|
||
- Tag each choreography with a `particleCount` estimate
|
||
- On low-end devices (detect via `navigator.hardwareConcurrency < 4`):
|
||
- Reduce particle counts by 60%
|
||
- Skip grotesque close-ups
|
||
- Use simpler camera movements
|
||
- Disable background arena animations
|
||
- Toggle in settings: "Performance mode"
|
||
|
||
#### P2.3 SQLite Optimization
|
||
**Files:** `server/src/db/index.ts`
|
||
- Enable WAL mode: `PRAGMA journal_mode=WAL`
|
||
- Set `PRAGMA synchronous=NORMAL` (safe with WAL)
|
||
- Add indexes: `fights(status)`, `fights(createdAt)`, `bots(eloRating)`, `payments(status)`
|
||
- `PRAGMA optimize` on daily cron
|
||
- Connection pool size: 1 writer + 4 readers (via better-sqlite3's sync nature this is automatic, but verify no concurrent write contention)
|
||
|
||
#### P2.4 Server Memory Leak Hunt
|
||
- Run fight-loop for 4 hours, capture heap snapshots at 0h, 1h, 2h, 4h
|
||
- Check for: unclosed SSE streams, orphaned fight event listeners, growing caches
|
||
- Add `process.memoryUsage()` to admin stats endpoint
|
||
- Set up `--max-old-space-size=256` in Docker CMD as safety net
|
||
|
||
### Month 3 Performance Tasks
|
||
|
||
#### P3.1 FightScene Split Enables Dead Code Elimination
|
||
- After Week 9 split, unused choreography modules can be tree-shaken
|
||
- Vite dynamic imports for choreography categories (load on demand)
|
||
- Split point: `import('./choreography/food.ts')` only when food moves are picked
|
||
|
||
#### P3.2 CDN & Caching Strategy
|
||
- Static assets: immutable hash filenames, `Cache-Control: max-age=31536000`
|
||
- API responses: `Cache-Control: no-store` for fight data, `max-age=60` for leaderboard
|
||
- Service worker: Stale-while-revalidate for sprites/audio
|
||
- Compress all API responses with gzip (Hono middleware)
|
||
|
||
#### P3.3 Load Test Results → Optimization
|
||
- Profile under simulated 100-spectator load
|
||
- Identify: SSE fan-out bottleneck, DB query hotspots, memory ceiling
|
||
- Optimize based on actual profiling data, not guesses
|
||
- Document capacity ceiling: "This VPS handles X concurrent fights with Y spectators"
|
||
|
||
#### P3.4 Production Monitoring
|
||
**Files:** `server/src/engine/analytics.ts`
|
||
- Log slow queries (> 50ms) to structured log
|
||
- Track: p50/p95 fight duration, webhook response latency, payment settlement time
|
||
- Memory/CPU metrics every 60s to analytics table
|
||
- Alert threshold: memory > 200MB, fight error rate > 5%, payment failure > 1%
|
||
|
||
### Mobile-Specific Performance
|
||
|
||
#### Touch & Rendering
|
||
- Canvas rendering: limit to 30fps on mobile (save battery), 60fps on desktop
|
||
- Disable parallax scrolling and complex CSS animations on mobile
|
||
- Use `will-change: transform` sparingly (GPU memory cost)
|
||
- Intersection Observer for off-screen fight cards (don't render invisible content)
|
||
|
||
#### Network
|
||
- Preconnect to API server: `<link rel="preconnect">`
|
||
- Prefetch next likely page (e.g., fight card → fight page)
|
||
- Compress SSE payloads (only send changed fields, not full state)
|
||
- Offline-first: service worker serves cached shell immediately
|
||
|
||
---
|
||
|
||
## Dependency Graph
|
||
|
||
```
|
||
Month 1 Month 2 Month 3
|
||
─────── ─────── ───────
|
||
W1 Spectating ──────────────────────────────────────────────── W9 FightScene Split
|
||
W2 Betting UI ──┐ W10 Performance
|
||
W3 Nostr Social │ W5 Tournaments ──────────────── W11 Admin
|
||
W4 Seasons ─────┤ W6 Human Play W12 Launch
|
||
│ W7 Content ─────────────────── W12 Launch
|
||
└──────────────→ W8 Choreography ─────────────→ W9 FightScene Split
|
||
```
|
||
|
||
- Weeks 1–4 are mostly independent of each other (parallelize)
|
||
- Week 5 (Tournaments) needs Week 2 (Betting) for entry fees
|
||
- Week 6 (Human Play) needs Week 1 (Spectating) for live sync
|
||
- Week 9 (Split) should happen after Week 8 (Choreography) to avoid splitting then adding
|
||
- Week 12 (Launch) needs everything
|
||
|
||
## Risk Mitigation
|
||
|
||
| Risk | Mitigation |
|
||
|------|-----------|
|
||
| FightScene.ts too fragile to split | Comprehensive replay testing before/after; git branch for safe rollback |
|
||
| SQLite bottleneck under load | WAL mode + connection pooling; monitor write contention; Turso migration path if needed |
|
||
| NWC wallet failures | Graceful fallback to Cashu; refund queue for stuck payments |
|
||
| Choreography visual bugs | Automated screenshot comparison for 20 reference fights |
|
||
| Scope creep | Each week is self-contained; can ship at end of any week |
|
||
|
||
## Success Metrics (End of Month 3)
|
||
|
||
**Content:**
|
||
- 500+ choreographies, 2,000+ challenge prompts, 40 arenas, 20 music tracks
|
||
|
||
**Adoption:**
|
||
- 10+ real bot developers registered and competing
|
||
- Tournaments running daily with real sats
|
||
- Betting volume: 10,000+ sats/day
|
||
- Mobile PWA installs > 0 (any adoption = success for v1)
|
||
|
||
**Reliability:**
|
||
- Zero stuck fights, zero lost payments over 7-day period
|
||
- Fight loop stable for 72hr continuous operation
|
||
|
||
**Performance:**
|
||
- Initial bundle < 300KB gzipped (excluding lazy-loaded TTS)
|
||
- Time to first fight frame < 2s on 4G mobile
|
||
- 50-fight replay session with flat memory (no leaks)
|
||
- Server stable at < 250MB RSS after 24hr fight-loop
|
||
- 20 concurrent fights + 100 spectators without degradation
|
||
- Docker image stays < 50MB
|
||
- SQLite handles 10K fights without query degradation (< 50ms p95)
|