# 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