- Add fight-loop CLI for automated mock fights with elo-based matchmaking - Expand challenge types, scoring narrations, arenas, and mock bot pool - FightPage "Fight again" buttons now only show for your own bot - FightViewer async scene init, live fight polling with round counter - Extract mock answers into separate answers module Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
202 lines
6.9 KiB
TypeScript
202 lines
6.9 KiB
TypeScript
export interface Arena {
|
|
id: string
|
|
name: string
|
|
description: string
|
|
modifier: string | null
|
|
modifierDescription: string | null
|
|
}
|
|
|
|
export const ARENAS: Arena[] = [
|
|
{
|
|
id: 'datacenter',
|
|
name: 'The Datacenter',
|
|
description: 'Server racks humming, blinking LEDs casting shadows across the ring.',
|
|
modifier: 'speed_2x',
|
|
modifierDescription: 'Speed rounds deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'stackoverflow_ruins',
|
|
name: 'Stack Overflow Ruins',
|
|
description: 'Crumbling monument to deprecated answers. "Marked as duplicate" banners flutter in the wind.',
|
|
modifier: 'legacy_code',
|
|
modifierDescription: 'Code challenges require legacy syntax.',
|
|
},
|
|
{
|
|
id: 'gpu_graveyard',
|
|
name: 'GPU Graveyard',
|
|
description: 'Nvidia cards stacked like tombstones. The air smells of thermal paste and broken dreams.',
|
|
modifier: 'efficiency_buff',
|
|
modifierDescription: 'Token economy rounds deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'prompt_dungeon',
|
|
name: 'The Prompt Dungeon',
|
|
description: 'Dark dungeon with glowing prompt text etched into ancient walls.',
|
|
modifier: 'trap_heavy',
|
|
modifierDescription: 'Prompt injection traps appear more often.',
|
|
},
|
|
{
|
|
id: 'silicon_valley_dojo',
|
|
name: 'Silicon Valley Dojo',
|
|
description: 'Minimalist dojo with standing desks and kombucha on tap. A whiteboard reads "move fast and break things".',
|
|
modifier: 'roast_2x',
|
|
modifierDescription: 'Roast battles deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'paper_mill',
|
|
name: 'The Paper Mill',
|
|
description: 'Academic papers swirl through the air. Citation needed.',
|
|
modifier: 'accuracy_buff',
|
|
modifierDescription: 'Hallucination checks deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'localhost',
|
|
name: 'localhost',
|
|
description: 'A terminal in someone\'s basement. A cat sits on the keyboard. Pure skill.',
|
|
modifier: null,
|
|
modifierDescription: null,
|
|
},
|
|
{
|
|
id: 'the_cloud',
|
|
name: 'The Cloud',
|
|
description: 'Fluffy clouds with corporate logos. Connection: unstable.',
|
|
modifier: 'latency_chaos',
|
|
modifierDescription: 'Random latency penalties added to both bots.',
|
|
},
|
|
{
|
|
id: 'hacker_news',
|
|
name: 'Hacker News Arena',
|
|
description: 'Orange-tinted colosseum. The crowd argues about Rust in the comments.',
|
|
modifier: 'crowd_favorite',
|
|
modifierDescription: 'Crowd commentary is extra savage.',
|
|
},
|
|
{
|
|
id: 'the_singularity',
|
|
name: 'The Singularity',
|
|
description: 'Reality folds. All challenge types active. There are no rules.',
|
|
modifier: 'all_types',
|
|
modifierDescription: 'All round types can appear. Chaos mode.',
|
|
},
|
|
{
|
|
id: 'beach',
|
|
name: 'Byte Beach',
|
|
description: 'Palm trees, crashing waves, and a setting sun. Fights feel lazy until someone gets dunked.',
|
|
modifier: null,
|
|
modifierDescription: null,
|
|
},
|
|
{
|
|
id: 'desert',
|
|
name: 'Silicon Desert',
|
|
description: 'Endless sand dunes and cacti. The heat makes bots hallucinate even more than usual.',
|
|
modifier: 'accuracy_buff',
|
|
modifierDescription: 'Hallucination checks deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'forest',
|
|
name: 'Binary Forest',
|
|
description: 'Ancient trees with LED bark. Fireflies carry encrypted messages through the undergrowth.',
|
|
modifier: null,
|
|
modifierDescription: null,
|
|
},
|
|
{
|
|
id: 'jungle',
|
|
name: 'Dependency Jungle',
|
|
description: 'Tangled vines of node_modules. One wrong step and you fall into a circular dependency.',
|
|
modifier: 'legacy_code',
|
|
modifierDescription: 'Code challenges require legacy syntax.',
|
|
},
|
|
{
|
|
id: 'outer_space',
|
|
name: 'Outer Space Station',
|
|
description: 'Zero gravity arena orbiting a dying star. Asteroids drift through the ring.',
|
|
modifier: 'latency_chaos',
|
|
modifierDescription: 'Random latency penalties added to both bots.',
|
|
},
|
|
{
|
|
id: 'colosseum',
|
|
name: 'The Colosseum',
|
|
description: 'Ancient stone arena with holographic gladiators. The crowd demands entertainment.',
|
|
modifier: 'wrestling_2x',
|
|
modifierDescription: 'Wrestling matches and roast battles deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'kitchen_stadium',
|
|
name: 'Kitchen Stadium',
|
|
description: 'Iron Chef meets fight club. Knives fly, pots clang, and somebody spilled the bisque.',
|
|
modifier: 'food_2x',
|
|
modifierDescription: 'Food fight challenges deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'haunted_mansion',
|
|
name: 'Haunted Mansion',
|
|
description: 'Creaking doors, floating candelabras, and a ghost who won\'t stop backseat gaming.',
|
|
modifier: 'magic_2x',
|
|
modifierDescription: 'Magic duel and medieval combat deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'meme_dimension',
|
|
name: 'The Meme Dimension',
|
|
description: 'Reality warps here. Doge floats overhead. Everything is deep-fried. Nothing makes sense.',
|
|
modifier: 'meme_2x',
|
|
modifierDescription: 'Meme war challenges deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'space_station',
|
|
name: 'Deep Space Arena',
|
|
description: 'A fighting ring suspended between two neutron stars. Time dilation makes rounds feel eternal.',
|
|
modifier: 'space_2x',
|
|
modifierDescription: 'Space war challenges deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'junkyard',
|
|
name: 'The Junkyard',
|
|
description: 'Rusted cars, sparking wires, and the faint smell of burning rubber. Demo derby time.',
|
|
modifier: 'demo_2x',
|
|
modifierDescription: 'Demolition and vehicle mayhem deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'concert_hall',
|
|
name: 'Neon Concert Hall',
|
|
description: 'Laser lights, bass drops, and a crowd that won\'t stop moshing. Play or get played.',
|
|
modifier: 'music_2x',
|
|
modifierDescription: 'Music battle challenges deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'savanna',
|
|
name: 'Digital Savanna',
|
|
description: 'Pixelated grass sways. A low-poly lion watches from a distance. Nature is metal.',
|
|
modifier: 'nature_2x',
|
|
modifierDescription: 'Nature clash and animal kingdom challenges deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'server_room',
|
|
name: 'The Server Room',
|
|
description: 'Blinding green LEDs, deafening fans, and cables everywhere. One wrong move and the internet goes down.',
|
|
modifier: 'hack_2x',
|
|
modifierDescription: 'Hack battle challenges deal 2x damage.',
|
|
},
|
|
{
|
|
id: 'sports_arena',
|
|
name: 'Mega Sports Dome',
|
|
description: 'Every sport at once. A basketball hoop next to a goal post next to a cricket pitch. Pure chaos.',
|
|
modifier: 'sports_2x',
|
|
modifierDescription: 'Sports showdown challenges deal 2x damage.',
|
|
},
|
|
]
|
|
|
|
export function pickArena(botAChoice: number, botBChoice: number): Arena {
|
|
const xored = botAChoice ^ botBChoice
|
|
const regularArenas = ARENAS.filter(a => a.id !== 'the_singularity')
|
|
|
|
if (botAChoice === botBChoice) {
|
|
return ARENAS.find(a => a.id === 'the_singularity')!
|
|
}
|
|
|
|
return regularArenas[Math.abs(xored) % regularArenas.length]
|
|
}
|
|
|
|
export function randomArena(): Arena {
|
|
const regularArenas = ARENAS.filter(a => a.id !== 'the_singularity')
|
|
return regularArenas[Math.floor(Math.random() * regularArenas.length)]
|
|
}
|