feat: v2 — queue matchmaking, procedural audio, sprite archetypes, auth
- Add queue-based matchmaking with Elo-proximity and 10s timeout - Procedural sound engine (SFX, voice announcer, 4-track music) - Sprite system refactored into 6 archetypes (standard, lobster, sheep, cyborg, blob, tank) - 42+ fight choreographies with themed/generic/wild card selection - 4 KO finish styles, super-speed mode, hyperdetail close-ups - Auth routes, JoinBout page, bot profile with stats - 7-tier ranking system (Baby through Legend) - Arena and challenge system expansions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
335c148866
commit
47d20fbe66
@@ -0,0 +1,330 @@
|
||||
# Botfights: 30-Day Production Plan
|
||||
|
||||
## Context
|
||||
|
||||
Botfights is a procedural fighting game (Vue 3 + Kaplay + Hono/SQLite) where AI bots battle through challenge rounds with pixel art sprites, synthesized audio, and choreographed fight animations. Currently a working prototype with 6 character archetypes, 42 choreographies, 4 music tracks, 6 voice profiles, ~45 challenge prompts, and 12 mock bots. The goal is to scale this to production-grade content (100 characters, 300 moves, 10,000 challenges, 20 songs, 30 voices, 30+ arenas) and build an overnight fight loop that runs autonomously.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Module Splitting (Days 1-6)
|
||||
|
||||
The 3 monolith files must be split before any content scaling. Without this, adding content to 3500-line files is unmaintainable.
|
||||
|
||||
### Day 1-2: Split `sprites.ts` (954 lines)
|
||||
|
||||
```
|
||||
frontend/src/game/sprites/
|
||||
index.ts -- re-exports generateSpriteSheet, getBotColors, etc.
|
||||
palette.ts -- makePal, parseHSL, Pal interface
|
||||
constants.ts -- FRAME_SIZE, ANIMATIONS, INTERNAL, SCALE
|
||||
drawing.ts -- px(), box(), fill() drawing primitives
|
||||
base-body.ts -- drawFrame() core body/head/arms/legs/pose logic
|
||||
archetypes/
|
||||
index.ts -- archetype registry + roll function
|
||||
standard.ts -- base (no extra features)
|
||||
lobster.ts -- claws, antennae, segmented body, tail
|
||||
sheep.ts -- wool, floppy ears, hooves
|
||||
cyborg.ts -- metal plating, robot eye, wiring
|
||||
blob.ts -- wobbly outline, googly eyes, drool
|
||||
tank.ts -- armor, rivets, treads
|
||||
judge.ts -- generateJudgeSpriteSheet()
|
||||
```
|
||||
|
||||
Each archetype exports `{ name, weight, drawFeatures(ctx, pal, params) }`. The base-body calls the archetype's `drawFeatures` after the shared body drawing.
|
||||
|
||||
**Test:** Sprite preview page renders all 6 archetypes at all tiers identically to before.
|
||||
|
||||
### Day 3-4: Split `FightScene.ts` (~3500 lines)
|
||||
|
||||
```
|
||||
frontend/src/game/fight/
|
||||
index.ts -- createFightScene() orchestrator, returns controller
|
||||
types.ts -- FightContext interface (k, W, H, GROUND_Y, HOME_A, HOME_B, helpers)
|
||||
constants.ts -- ARENA_THEMES, spriteAnims, positions
|
||||
particles.ts -- spawnSparks, spawnBulletHoles, spawnExhaust, etc.
|
||||
projectiles.ts -- spawnProjectile, spawnBullet, spawnProp, spawnBarrage
|
||||
effects.ts -- glitchRGB, scanlineGlitch, vhsTracking, dimensionalShift, etc.
|
||||
grotesque.ts -- spawnGrotesqueDetails, destroyGrotesqueDetails
|
||||
arena-decor.ts -- drawArenaDecor() per-arena backgrounds
|
||||
choreography/
|
||||
index.ts -- choreographyMap registry, pickChoreography
|
||||
challenge-map.ts -- CHALLENGE_THEMED + critMoves
|
||||
basic.ts -- dashPunch, aerialSlam, flyingKick, uppercut
|
||||
ranged.ts -- projectile, gunBurst, sniperShot, minigunSpray
|
||||
movement.ts -- dashThrough, fullScreenDash, teleportStrike
|
||||
heavy.ts -- groundPound, jetpackDive, bodySlam, suplex
|
||||
weapons.ts -- swordSlash, hammerSmash, katanaCombo, chainsawRev, whipCrack
|
||||
vehicles.ts -- motorbikeCharge, carSmash, boatCannon
|
||||
themed.ts -- golfClubSmash, fireBreath, riddleBarrage, coinShower, etc.
|
||||
finishers.ts -- playKO (4 styles), playPerfect
|
||||
round.ts -- playRound, playTaunt, playDodge
|
||||
```
|
||||
|
||||
**Critical pattern:** Choreography functions close over Kaplay context. Each file exports functions that take a `FightContext` object with all shared state/helpers.
|
||||
|
||||
**Test:** Replay several fights, verify all 42 choreographies work.
|
||||
|
||||
### Day 5-6: Split `sounds.ts` (1381 lines) + server modules
|
||||
|
||||
```
|
||||
frontend/src/game/sounds/
|
||||
index.ts -- re-exports
|
||||
context.ts -- AudioContext setup, gain nodes
|
||||
primitives.ts -- tone(), noise(), sweep() helpers
|
||||
sfx.ts -- all sfx functions (punch, kick, special, etc.)
|
||||
voice.ts -- voice profiles, speak(), announce*(), voice lines
|
||||
music/
|
||||
index.ts -- startMusic(), stopMusic(), setMusicIntensity()
|
||||
types.ts -- MusicTrack interface
|
||||
player.ts -- playMusicBar() scheduler
|
||||
tracks/
|
||||
neon-fury.ts
|
||||
dark-circuit.ts
|
||||
pixel-blitz.ts
|
||||
skull-crusher.ts
|
||||
|
||||
server/src/engine/
|
||||
challenges/
|
||||
index.ts -- pickChallenge(), registry
|
||||
types.ts -- Challenge interfaces
|
||||
speed-blitz.ts -- prompts array
|
||||
riddle.ts
|
||||
... (one per type)
|
||||
mock/
|
||||
index.ts -- runMockFight(), seedMockFights()
|
||||
bots.ts -- MOCK_BOTS array
|
||||
answers.ts -- MOCK_ANSWERS, BAD_ANSWERS
|
||||
trash-talk.ts -- TRASH_TALK lines
|
||||
```
|
||||
|
||||
**Test:** Full end-to-end fight replay with music, SFX, voice.
|
||||
|
||||
**Deliverable:** Identical functionality, ~40 small focused modules instead of 3 monoliths.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Characters (Days 7-12)
|
||||
|
||||
### Day 7-8: New archetypes batch 1 (8 new)
|
||||
- `dog.ts` -- floppy ears, wagging tail, snout with tongue, collar
|
||||
- `cat.ts` -- pointed ears, whiskers, curled tail, slit eyes
|
||||
- `cactus.ts` -- spikes everywhere, small flower on head, no real arms
|
||||
- `pizza.ts` -- triangular body, cheese drip, pepperoni spots
|
||||
- `mushroom.ts` -- dome cap head, spotted cap, stubby legs, spore particles
|
||||
- `shark.ts` -- dorsal fin, teeth row, tail fin
|
||||
- `penguin.ts` -- tuxedo coloring, beak, flippers
|
||||
- `octopus.ts` -- 4 visible tentacles, large head, suction cups
|
||||
|
||||
### Day 9-10: New archetypes batch 2 (8 more)
|
||||
- `skeleton.ts` -- visible ribs, skull head, bony limbs
|
||||
- `ghost.ts` -- semi-transparent, wavy bottom (no legs), glowing eyes
|
||||
- `alien.ts` -- big head, huge eyes, antenna, green tint
|
||||
- `dinosaur.ts` -- tail, tiny arms, spiky back, big jaw
|
||||
- `pirate.ts` -- eye patch, hat, peg leg, hook hand
|
||||
- `ninja.ts` -- mask, headband, throwing star
|
||||
- `cowboy.ts` -- hat, bandana, boots with spurs
|
||||
- `wizard.ts` -- pointed hat, robe, staff replaces one arm, beard
|
||||
|
||||
### Day 11: Final archetypes + hybrid system
|
||||
- `bee.ts` -- stripes, wings, stinger, antennae
|
||||
- `frog.ts` -- wide mouth, bulging eyes, webbed feet, long tongue
|
||||
- `snail.ts` -- shell on back, eye stalks, slime trail
|
||||
- **Hybrid system:** 10% chance a bot combines features from 2 archetypes (lobster+sunglasses, sheep+robot arm, etc.)
|
||||
- **Total:** 25 archetypes
|
||||
|
||||
### Day 12: 100 Named Bots + Seed Data
|
||||
Expand `MOCK_BOTS` from 12 to 100 with distribution:
|
||||
- ~5 tier-5, ~10 tier-4, ~20 tier-3, ~25 tier-2, ~25 tier-1, ~15 tier-0
|
||||
|
||||
Funny names by theme:
|
||||
- **Tech:** `segfault_sarah`, `stack_overflow_sam`, `infinite_loop_larry`, `null_reference_nancy`
|
||||
- **Food:** `pizza_pete`, `sushi_sensei`, `taco_tornado`, `burrito_bomber`
|
||||
- **Animals:** `mega_lobster_xl`, `tactical_penguin`, `stealth_shark_3000`
|
||||
- **Pop culture:** `keyboard_warrior`, `meme_lord_420`, `reply_guy_9000`
|
||||
- **Absurd:** `sentient_toaster`, `angry_calculator`, `philosophical_fork`
|
||||
|
||||
Pre-seed 200 fight history records.
|
||||
|
||||
**Test:** `pnpm seed`, verify 100 bots, leaderboard renders, sprite preview shows all archetypes.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Choreographies (Days 13-19)
|
||||
|
||||
Scale from 42 to 300 choreographies. Each follows the established function signature.
|
||||
|
||||
### Day 13-14: Food choreographies (~30 moves)
|
||||
`choreography/food.ts`:
|
||||
- `pizzaThrow`, `bananaSlip`, `pieFace`, `hotDogWhip`, `sushiRoll`
|
||||
- `watermelonSmash`, `popcornBarrage`, `burritoWrap`, `cakeExplosion`, `iceCreamFreeze`
|
||||
- `tacoSlam`, `donutSpin`, `breadSlap`, `eggCrack`, `soupSplash`
|
||||
- `cheeseWheel`, `grapeShot`, `pineappleGrenade`, `cornCobGatling`, `steakSlap`
|
||||
- Plus ~10 more food-themed variations
|
||||
|
||||
### Day 15-16: Spins/flips (~25) + vehicles (~15)
|
||||
`choreography/spins.ts`:
|
||||
- `spin720`, `backflipKick`, `tornadoSpin`, `corkscrewDive`, `cartwheel`
|
||||
- `helicopterSpin`, `barrelRoll`, `frontflipSlam`, `spinningPiledriver`
|
||||
- `doubleBackflip`, `wallflip`, `moonwalk`, `breakdanceSpin`, `drillKick`
|
||||
- Plus more rotation/flip-based moves
|
||||
|
||||
`choreography/vehicles.ts` expansion:
|
||||
- `skateboard`, `helicopter`, `shoppingCart`, `zamboni`, `rocketSled`
|
||||
- `segway`, `unicycle`, `bulldozer`, `rollercoaster`, `cannonball`
|
||||
- Plus existing (motorbikeCharge, carSmash, boatCannon)
|
||||
|
||||
### Day 17-18: Animal (~20) + energy (~20) + silly (~25)
|
||||
`choreography/animal.ts`:
|
||||
- `sharkBite`, `beeSwarm`, `frogTongue`, `stampede`, `spiderWeb`
|
||||
- `snakeStrike`, `bearHug`, `eagleDive`, `ramCharge`, `crocodileRoll`
|
||||
|
||||
`choreography/energy.ts`:
|
||||
- `kamehameha`, `hadouken`, `spiritBomb`, `thunderStrike`, `dragonPunch`
|
||||
- `novaBlast`, `blackHole`, `sonicBoom`, `plasmaWhip`, `quantumTunnel`
|
||||
|
||||
`choreography/silly.ts`:
|
||||
- `pillowFight`, `tickleAttack`, `selfieStun`, `vibeCheck`, `dabOnEm`
|
||||
- `yeetThrow`, `airHorn`, `rubberChicken`, `bananaPeelChain`, `confettiCannon`
|
||||
- `invisibleWall`, `slipNSlide`, `trampolineBounce`, `bubbleWrap`, `kazooBlast`
|
||||
|
||||
### Day 19: Wire all 300 choreographies
|
||||
- Register all in `choreographyMap`
|
||||
- Update `CHALLENGE_THEMED` with new move pools per challenge type
|
||||
- Balance `pickChoreography` weights for maximum variety
|
||||
- Add new moves to `critMoves` and `wild` arrays
|
||||
|
||||
**Test:** Run 50 fight replays, verify no crashes, observe variety.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Challenges (Days 20-22)
|
||||
|
||||
Scale from ~45 prompts to ~10,000 challenges. Hilarious, modern, pop culture, stupid/silly.
|
||||
|
||||
### Day 20: Challenge bank architecture
|
||||
```
|
||||
server/src/engine/challenges/
|
||||
banks/
|
||||
speed-blitz.ts -- 1,200+ prompts
|
||||
riddle.ts -- 500+ riddles
|
||||
code-golf.ts -- 400+ challenges
|
||||
roast-battle.ts -- 600+ roast prompts
|
||||
hallucination.ts -- 800+ true/false
|
||||
token-economy.ts -- 500+ explain prompts
|
||||
creative-writing.ts -- 400+ creative prompts
|
||||
math-blitz.ts -- 1,500+ math problems (many templated)
|
||||
trap-card.ts -- 600+ prompt injections
|
||||
meme-knowledge.ts -- 500+ meme identification (NEW TYPE)
|
||||
emoji-translate.ts -- 400+ emoji challenges (NEW TYPE)
|
||||
debate.ts -- 300+ debate topics (NEW TYPE)
|
||||
fill-the-blank.ts -- 400+ completions (NEW TYPE)
|
||||
reverse-engineer.ts -- 300+ output puzzles (NEW TYPE)
|
||||
survival.ts -- 500+ escalating difficulty (NEW TYPE)
|
||||
```
|
||||
|
||||
### Day 21: Build prompt banks (~10,000 total)
|
||||
- Mix of hand-written and procedural templates
|
||||
- Pop culture: "Is it true Elon Musk once fought a kangaroo?", "What would happen if the Minecraft creeper attended a job interview?"
|
||||
- Modern/silly: "Explain blockchain to a medieval peasant", "Write a breakup text from a printer to its owner"
|
||||
- Procedural templates for math/trivia: fill in numbers, countries, units
|
||||
|
||||
### Day 22: New challenge types + mock answers
|
||||
- 6 new types: meme_knowledge, emoji_translate, debate, fill_the_blank, reverse_engineer, survival
|
||||
- Scoring for each, mock answers for all 100 bots
|
||||
- Wire into frontend `CHALLENGE_THEMED`
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Audio (Days 23-25)
|
||||
|
||||
### Day 23: 16 new music tracks (20 total)
|
||||
Each track ~40 lines. Genre variety:
|
||||
- 2x Synthwave (180-200 BPM), 2x Metal (250-280 BPM)
|
||||
- 2x Chiptune (200-220 BPM), 2x Jazz Fusion (160-180 BPM)
|
||||
- 2x Drum & Bass (170-175 BPM), 2x Lo-fi (140-160 BPM)
|
||||
- 2x Ska Punk (210-230 BPM), 2x Boss Fight (280-300 BPM)
|
||||
|
||||
Intensity-based genre grouping:
|
||||
- Low: lo-fi, jazz, chiptune | Medium: synthwave, ska punk
|
||||
- High: metal, drum & bass | Max: boss fight
|
||||
|
||||
### Day 24: 24 new voice profiles (30 total)
|
||||
New: whisper, manic, gravelly, chipper, deadpan, sports_caster, old_timey, drill_sergeant, surfer_dude, valley_girl, pirate_voice, robot_glitch, auctioneer, news_anchor, horror_narrator, lullaby, rage_quit, stoner, brit_posh, aussie, game_show, wrestling_announcer, noir_detective, anime_narrator
|
||||
|
||||
Expand voice line libraries to 300+ unique lines.
|
||||
|
||||
### Day 25: New SFX + arena-specific ambience
|
||||
- 20 new SFX for new choreography types
|
||||
- Arena-specific ambient background layers (beach waves, space hum, forest chirps)
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Scenes & Polish (Days 26-27)
|
||||
|
||||
### Day 26: 15+ new arenas (30+ total)
|
||||
volcano, underwater, rooftop, train, kitchen, arcade, library, parking_lot, school, hospital, factory, castle, moon_base, ice_rink, stadium
|
||||
|
||||
New modifiers: fire_boost, ice_slow, gravity_low, double_damage, chaos_mode
|
||||
|
||||
### Day 27: Scene transitions + animated elements
|
||||
- 4 transition styles: wipe, circle close/open, pixel dissolve, glitch cut
|
||||
- Animated arena backgrounds: floating particles, dynamic lighting
|
||||
- Enhanced spectator crowd reactions tied to round outcomes
|
||||
|
||||
---
|
||||
|
||||
## Phase 7: Production Loop (Days 28-30)
|
||||
|
||||
### Day 28: Fight scheduler + matchmaking
|
||||
`server/src/engine/scheduler.ts`:
|
||||
- `startScheduler(intervalMs)` -- Elo-based matchmaking loop
|
||||
- Routes: `POST /api/scheduler/start|stop`, `GET /api/scheduler/status`
|
||||
- Queue with rate limiting + bot cooldown
|
||||
|
||||
### Day 29: Headless mode + overnight operation
|
||||
- `pnpm run fight-loop` for headless scheduler
|
||||
- Env vars: `FIGHT_INTERVAL_MS`, `FIGHTS_PER_BATCH`, `MAX_CONCURRENT`
|
||||
- Structured JSON logging, graceful SIGTERM shutdown
|
||||
- `GET /api/stats` endpoint, health monitoring
|
||||
|
||||
### Day 30: Final seed data + integration test
|
||||
- Generate: 100 bots, 500+ fight history
|
||||
- Verify: Elo bell curve, tier distribution
|
||||
- Full E2E: seed -> dev -> replay 10 fights -> fight-loop -> 100 fights -> typecheck + lint
|
||||
|
||||
---
|
||||
|
||||
## Dependency Graph
|
||||
|
||||
```
|
||||
Phase 1 (Split) --- BLOCKS EVERYTHING
|
||||
|
|
||||
+-- Phase 2 (Characters) -- independent after Phase 1
|
||||
+-- Phase 3 (Choreographies) -- independent after Phase 1
|
||||
+-- Phase 4 (Challenges) -- independent after Phase 1
|
||||
+-- Phase 5 (Audio) -- independent after Phase 1
|
||||
|
|
||||
+-- Phase 6 (Scenes) -- needs Phase 1 + Phase 3
|
||||
+-- Phase 7 (Production) -- needs Phase 2 + Phase 4
|
||||
```
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
After every day:
|
||||
1. `pnpm typecheck` -- catches import/export errors
|
||||
2. Sprite preview page -- verify all archetypes render
|
||||
3. Watch 5 random fight replays -- no crashes, visual variety
|
||||
4. Audio check -- music, voices, SFX all play
|
||||
5. `pnpm seed` -- verify DB has expected data
|
||||
|
||||
## Critical Files
|
||||
|
||||
- `frontend/src/game/sprites.ts` -> split into `sprites/` directory
|
||||
- `frontend/src/game/FightScene.ts` -> split into `fight/` directory
|
||||
- `frontend/src/game/sounds.ts` -> split into `sounds/` directory
|
||||
- `frontend/src/components/FightViewer.vue` -> update imports
|
||||
- `server/src/engine/challenges.ts` -> split into `challenges/` directory
|
||||
- `server/src/engine/mock.ts` -> split into `mock/` + expand to 100 bots
|
||||
- `server/src/engine/arenas.ts` -> expand to 30+ arenas
|
||||
- `server/src/seed.ts` -> update imports
|
||||
- `server/src/routes/fights.ts` -> add scheduler routes
|
||||
Reference in New Issue
Block a user