From 4b46aaf643102229a5a832609c3fb86b7e3ea236 Mon Sep 17 00:00:00 2001 From: Dorian Date: Sat, 7 Mar 2026 19:42:49 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20mobile=20human=20vs=20AI=20=E2=80=94=20?= =?UTF-8?q?multiple=20choice,=20two-row=20VS=20bar,=20responsive=20arena?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Server-side choice generation for all 22 challenge types (factual + creative) - Mobile: 3 multiple-choice buttons replace keyboard input (4s timer) - Two-row VS bar on mobile (names row + HP bars row) in FightPage and FightViewer - Battle log hidden on mobile to maximize canvas visibility - Arena page responsive: stacking header, tighter fight cards, no name overflow - Profile page two-column desktop layout with contained sprite display - Human fighter sprites with baby growth system Co-Authored-By: Claude Opus 4.6 --- frontend/src/components/FightViewer.vue | 92 +++-- frontend/src/game/FightScene.ts | 44 ++- frontend/src/game/sprites/human.ts | 455 ++++++++++++++++++++++++ frontend/src/game/sprites/index.ts | 2 +- frontend/src/pages/ArenaPage.vue | 26 +- frontend/src/pages/BotProfilePage.vue | 249 ++++++------- frontend/src/pages/FightPage.vue | 278 ++++++++++++--- server/src/engine/challenges.ts | 8 + server/src/engine/human-responses.ts | 210 ++++++++++- 9 files changed, 1115 insertions(+), 249 deletions(-) diff --git a/frontend/src/components/FightViewer.vue b/frontend/src/components/FightViewer.vue index be93050..b184f7b 100644 --- a/frontend/src/components/FightViewer.vue +++ b/frontend/src/components/FightViewer.vue @@ -116,8 +116,8 @@ async function initScene() { scene = await createFightScene({ canvas: canvasRef.value, - botA: { name: props.fight.botA.name, seed: props.fight.botA.avatarSeed || props.fight.botA.name, tier: props.fight.botA.tier, archetype: props.fight.botA.archetype, customization: props.fight.botA.customization as any }, - botB: { name: props.fight.botB.name, seed: props.fight.botB.avatarSeed || props.fight.botB.name, tier: props.fight.botB.tier, archetype: props.fight.botB.archetype, customization: props.fight.botB.customization as any }, + botA: { name: props.fight.botA.name, seed: props.fight.botA.avatarSeed || props.fight.botA.name, tier: props.fight.botA.tier, archetype: props.fight.botA.archetype, customization: props.fight.botA.customization as any, wins: props.fight.botA.wins, losses: props.fight.botA.losses }, + botB: { name: props.fight.botB.name, seed: props.fight.botB.avatarSeed || props.fight.botB.name, tier: props.fight.botB.tier, archetype: props.fight.botB.archetype, customization: props.fight.botB.customization as any, wins: props.fight.botB.wins, losses: props.fight.botB.losses }, arena: props.fight.arena, }) } @@ -401,8 +401,8 @@ async function replay() {