fix: fight restart bug, mobile TTS, character sizing, bitcoin symbols
- Fix fight replay showing empty scene: validate rounds before playing, retry loading fight data up to 5 times when rounds are missing - Add COOP/COEP headers to production server for SharedArrayBuffer (required by Kokoro TTS WASM threading on mobile) - Add blob: to scriptSrc/workerSrc CSP for Web Worker support - Fix mobile character cutoff: raise ground line to 0.82, add MOBILE_SCALE_CAP (0.55) so fighters never shrink too small - Add ₿ bitcoin chest badge to all fighter sprites (scales with tier) - Add sats coin stack on bot profile page proportional to satsWon - Seed dev tournament with 8 mock bots on startup (dev mode only) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
a10c1c9cb6
commit
5ee6b6c88c
@@ -9,7 +9,7 @@ import { pickChoreography } from './fight/choreography/picker'
|
||||
export { pickChoreography }
|
||||
import {
|
||||
isPerfMode, perfParticles, isReducedMotion, haptic,
|
||||
GROUND_Y_RATIO, HOME_A_RATIO, HOME_B_RATIO, REFERENCE_HEIGHT, SPRITE_LOAD_TIMEOUT_MS,
|
||||
GROUND_Y_RATIO, HOME_A_RATIO, HOME_B_RATIO, REFERENCE_HEIGHT, MOBILE_SCALE_CAP, SPRITE_LOAD_TIMEOUT_MS,
|
||||
FIGHTER_BASE_SCALE, FIGHTER_TIER_SCALE, JUDGE_SCALE, HUMAN_COACH_SCALE, HUMAN_RUN_SCALE,
|
||||
AMBIENT_PARTICLE_COUNT, SKY_GRADIENT_BANDS, GROUND_DEPTH_LINES, PERSPECTIVE_GRID_LINES, PILLAR_WIDTH,
|
||||
SPEECH_BUBBLE_MAX_CHARS, SPEECH_BUBBLE_WRAP, SPEECH_BUBBLE_MAX_LINES, SPEECH_BUBBLE_FONT_SIZE, SPEECH_BUBBLE_DEFAULT_DURATION,
|
||||
@@ -193,7 +193,7 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
const vhsTracking = (duration: number = 0.4) => _vhsTracking(fightCtx, duration)
|
||||
const dimensionalShift = (duration: number = 0.6) => _dimensionalShift(fightCtx, duration)
|
||||
|
||||
const SF = Math.min(1, H / REFERENCE_HEIGHT)
|
||||
const SF = Math.max(MOBILE_SCALE_CAP, Math.min(1, H / REFERENCE_HEIGHT))
|
||||
const GROUND_Y = H * GROUND_Y_RATIO
|
||||
const HOME_A = W * HOME_A_RATIO
|
||||
const HOME_B = W * HOME_B_RATIO
|
||||
|
||||
@@ -87,10 +87,11 @@ export const HYPERDETAIL_BASE_CHANCE = 0.05 // Base hyperdetail chance
|
||||
export const HYPERDETAIL_INTENSITY_SCALE = 0.45 // Scales with intensity
|
||||
|
||||
// --- Scene layout ---
|
||||
export const GROUND_Y_RATIO = 0.78 // Ground line as fraction of canvas height
|
||||
export const GROUND_Y_RATIO = 0.82 // Ground line as fraction of canvas height
|
||||
export const HOME_A_RATIO = 0.28 // Fighter A home X position ratio
|
||||
export const HOME_B_RATIO = 0.72 // Fighter B home X position ratio
|
||||
export const REFERENCE_HEIGHT = 500 // Reference canvas height for scale factor
|
||||
export const MOBILE_SCALE_CAP = 0.55 // Cap SF on small screens so fighters aren't too tiny
|
||||
export const SPRITE_LOAD_TIMEOUT_MS = 5_000 // Max wait for sprite loading (mobile hang prevention)
|
||||
|
||||
// --- Fighter scaling ---
|
||||
|
||||
@@ -201,14 +201,35 @@ export function generateSpriteSheet(
|
||||
if (tier >= 3) { px(cx + hOff, beltY, '#ffd700', ox, oy); px(cx + hOff + 1, beltY, '#ffd700', ox, oy) }
|
||||
}
|
||||
|
||||
// Chest emblem (tier 4+)
|
||||
if (tier >= 4) {
|
||||
// ₿ Bitcoin chest badge — every fighter carries the symbol
|
||||
{
|
||||
const ey = by + Math.round(bh * 0.3)
|
||||
px(cx + hOff - 1, ey, pal.acc, ox, oy)
|
||||
px(cx + hOff, ey, pal.accLight, ox, oy)
|
||||
px(cx + hOff + 1, ey, pal.acc, ox, oy)
|
||||
px(cx + hOff, ey - 1, pal.acc, ox, oy)
|
||||
px(cx + hOff, ey + 1, pal.acc, ox, oy)
|
||||
const ec = cx + hOff
|
||||
// Tier 0-1: simple orange ₿ dot
|
||||
// Tier 2-3: small ₿ shape (vertical bar + bumps)
|
||||
// Tier 4+: full golden ₿ with glow
|
||||
if (tier >= 4) {
|
||||
// Golden glow behind
|
||||
px(ec - 2, ey, '#ffd70066', ox, oy)
|
||||
px(ec + 2, ey, '#ffd70066', ox, oy)
|
||||
px(ec, ey - 2, '#ffd70066', ox, oy)
|
||||
px(ec, ey + 2, '#ffd70066', ox, oy)
|
||||
}
|
||||
const bc = tier >= 4 ? '#ffd700' : tier >= 2 ? '#ff8c00' : '#ff6600'
|
||||
// Vertical stroke
|
||||
px(ec, ey - 1, bc, ox, oy)
|
||||
px(ec, ey, bc, ox, oy)
|
||||
px(ec, ey + 1, bc, ox, oy)
|
||||
// Right bumps (₿ shape)
|
||||
if (bw >= 6) {
|
||||
px(ec + 1, ey - 1, bc, ox, oy)
|
||||
px(ec + 1, ey + 1, bc, ox, oy)
|
||||
}
|
||||
// Top/bottom serifs
|
||||
if (tier >= 2) {
|
||||
px(ec, ey - 2, tier >= 4 ? '#ffd700' : '#cc7000', ox, oy)
|
||||
px(ec, ey + 2, tier >= 4 ? '#ffd700' : '#cc7000', ox, oy)
|
||||
}
|
||||
}
|
||||
|
||||
// Shoulder pads (tier 3+)
|
||||
|
||||
Reference in New Issue
Block a user