- 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>
14 KiB
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, collarcat.ts-- pointed ears, whiskers, curled tail, slit eyescactus.ts-- spikes everywhere, small flower on head, no real armspizza.ts-- triangular body, cheese drip, pepperoni spotsmushroom.ts-- dome cap head, spotted cap, stubby legs, spore particlesshark.ts-- dorsal fin, teeth row, tail finpenguin.ts-- tuxedo coloring, beak, flippersoctopus.ts-- 4 visible tentacles, large head, suction cups
Day 9-10: New archetypes batch 2 (8 more)
skeleton.ts-- visible ribs, skull head, bony limbsghost.ts-- semi-transparent, wavy bottom (no legs), glowing eyesalien.ts-- big head, huge eyes, antenna, green tintdinosaur.ts-- tail, tiny arms, spiky back, big jawpirate.ts-- eye patch, hat, peg leg, hook handninja.ts-- mask, headband, throwing starcowboy.ts-- hat, bandana, boots with spurswizard.ts-- pointed hat, robe, staff replaces one arm, beard
Day 11: Final archetypes + hybrid system
bee.ts-- stripes, wings, stinger, antennaefrog.ts-- wide mouth, bulging eyes, webbed feet, long tonguesnail.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,sushiRollwatermelonSmash,popcornBarrage,burritoWrap,cakeExplosion,iceCreamFreezetacoSlam,donutSpin,breadSlap,eggCrack,soupSplashcheeseWheel,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,cartwheelhelicopterSpin,barrelRoll,frontflipSlam,spinningPiledriverdoubleBackflip,wallflip,moonwalk,breakdanceSpin,drillKick- Plus more rotation/flip-based moves
choreography/vehicles.ts expansion:
skateboard,helicopter,shoppingCart,zamboni,rocketSledsegway,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,spiderWebsnakeStrike,bearHug,eagleDive,ramCharge,crocodileRoll
choreography/energy.ts:
kamehameha,hadouken,spiritBomb,thunderStrike,dragonPunchnovaBlast,blackHole,sonicBoom,plasmaWhip,quantumTunnel
choreography/silly.ts:
pillowFight,tickleAttack,selfieStun,vibeCheck,dabOnEmyeetThrow,airHorn,rubberChicken,bananaPeelChain,confettiCannoninvisibleWall,slipNSlide,trampolineBounce,bubbleWrap,kazooBlast
Day 19: Wire all 300 choreographies
- Register all in
choreographyMap - Update
CHALLENGE_THEMEDwith new move pools per challenge type - Balance
pickChoreographyweights for maximum variety - Add new moves to
critMovesandwildarrays
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-loopfor headless scheduler- Env vars:
FIGHT_INTERVAL_MS,FIGHTS_PER_BATCH,MAX_CONCURRENT - Structured JSON logging, graceful SIGTERM shutdown
GET /api/statsendpoint, 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:
pnpm typecheck-- catches import/export errors- Sprite preview page -- verify all archetypes render
- Watch 5 random fight replays -- no crashes, visual variety
- Audio check -- music, voices, SFX all play
pnpm seed-- verify DB has expected data
Critical Files
frontend/src/game/sprites.ts-> split intosprites/directoryfrontend/src/game/FightScene.ts-> split intofight/directoryfrontend/src/game/sounds.ts-> split intosounds/directoryfrontend/src/components/FightViewer.vue-> update importsserver/src/engine/challenges.ts-> split intochallenges/directoryserver/src/engine/mock.ts-> split intomock/+ expand to 100 botsserver/src/engine/arenas.ts-> expand to 30+ arenasserver/src/seed.ts-> update importsserver/src/routes/fights.ts-> add scheduler routes