Files
botfights/frontend/src/game/fight/config.ts
T
DorianandClaude Opus 4.6 3a5f473d25 fix: show full text in battle log and speech bubbles
Remove .slice(0, 120) truncation from battle log entries and
.slice(0, 60) from speech bubble calls. Increase bubble limits
to 200 chars, 24 chars/line, 8 lines so responses display fully.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 14:11:02 +00:00

124 lines
6.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ═══════════════════════════════════════════════════════════════
// Gameplay constants — all tunable magic numbers in one place
// ═══════════════════════════════════════════════════════════════
// --- Performance mode ---
const PERF_KEY = 'bf_perf_mode'
function detectLowEnd(): boolean {
if (typeof navigator === 'undefined') return false
const cores = navigator.hardwareConcurrency || 4
const mobile = navigator.maxTouchPoints > 0
return cores < 4 || mobile
}
function loadPerfPref(): boolean | null {
try {
const v = localStorage.getItem(PERF_KEY)
if (v === '1') return true
if (v === '0') return false
} catch {}
return null
}
let _perfMode = loadPerfPref() ?? detectLowEnd()
export function isPerfMode(): boolean { return _perfMode }
export function setPerfMode(on: boolean): void {
_perfMode = on
try { localStorage.setItem(PERF_KEY, on ? '1' : '0') } catch {}
}
/** Scale a particle count down in performance mode (40%) or reduced motion (20%) */
export function perfParticles(count: number): number {
if (_reducedMotion) return Math.max(1, Math.round(count * 0.2))
return _perfMode ? Math.max(1, Math.round(count * 0.4)) : count
}
// --- Reduced motion ---
const _reducedMotion = typeof window !== 'undefined'
? window.matchMedia('(prefers-reduced-motion: reduce)').matches
: false
export function isReducedMotion(): boolean { return _reducedMotion }
// --- Haptic feedback ---
export function haptic(ms: number = 50): void {
try { navigator?.vibrate?.(ms) } catch { /* no vibration support */ }
}
// --- Choreography selection probabilities ---
export const CREATOR_ULTIMATE_CHANCE = 0.5 // Creator ultimate chance (non-crit); 1.0 on crits
export const CREATOR_THEMED_MOVE_RATIO = 0.6 // Creator uses creator-themed moves 60% of the time
export const CRIT_THEMED_RATIO = 0.5 // On crits: 50% themed, 50% epic generic
export const CHOREOGRAPHY_THEMED_RATIO = 0.6 // Normal: 60% themed
export const CHOREOGRAPHY_GENERIC_CUTOFF = 0.85 // Normal: 25% generic (0.600.85), 15% wild (0.851.0)
// --- Tier-gated ultimate chances ---
export const TIER_ULTIMATE_CHANCES: Record<number, number> = {
2: 0.15,
3: 0.20,
4: 0.30,
5: 0.40,
}
// --- Morph system ---
export const CREATOR_MORPH_CRIT_CHANCE = 0.7 // Creator morphs on devastating crits 70%
export const CREATOR_MORPH_INTENSITY_THRESHOLD = 0.6 // Creator morphs when intensity > 0.6
export const BOT_MORPH_CRIT_CHANCE = 0.4 // Regular bots morph on devastating crits 40%
export const BOT_MORPH_INTENSITY_THRESHOLD = 0.7 // Regular bots morph when intensity > 0.7
// --- Creator cameo ---
export const CREATOR_CAMEO_CHANCE = 0.06 // 6% per round in non-creator fights
// --- Round exchange probabilities ---
export const DODGE_CHANCE = 0.12 // Defender dodges instead of being hit
export const COUNTER_ATTACK_CHANCE = 0.25 // Defender counters after getting hit
export const SCANLINE_GLITCH_CHANCE = 0.25 // Random scanline glitch during exchanges
export const COMEDY_SFX_CHANCE = 0.15 // Comedy sound on non-decisive hits
export const PHYSICAL_CONTACT_BASE = 0.35 // Base chance for brawl/clinch
export const PHYSICAL_CONTACT_INTENSITY_SCALE = 0.2 // Added per unit of intensity
export const PHYSICAL_CONTACT_EXCHANGE_BONUS = 0.15 // Added after first exchange
export const CROWD_REACTION_CHANCE = 0.4 // Crowd reacts to round results
export const CREATOR_VOICE_LINE_CHANCE = 0.6 // Creator gets a voice line
// --- Hyperdetail (grotesque close-up) ---
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.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 ---
export const FIGHTER_BASE_SCALE = 1.8 // Base fighter sprite scale
export const FIGHTER_TIER_SCALE = 0.4 // Additional scale per tier level
export const JUDGE_SCALE = 1.3 // Judge sprite scale
export const HUMAN_COACH_SCALE = 1.2 // Human coach sprite scale
export const HUMAN_RUN_SCALE = 1.3 // Human run-across sprite scale
// --- Scene visual constants ---
export const AMBIENT_PARTICLE_COUNT = 18 // Floating dust/embers in air
export const SKY_GRADIENT_BANDS = 6 // Number of sky gradient bands
export const GROUND_DEPTH_LINES = 12 // Ground gradient fade lines
export const PERSPECTIVE_GRID_LINES = 24 // Floor grid convergence lines
export const PILLAR_WIDTH = 8 // Side pillar frame width
export const SPEECH_BUBBLE_MAX_CHARS = 200 // Max chars in speech bubble
export const SPEECH_BUBBLE_WRAP = 24 // Chars per line in speech bubble
export const SPEECH_BUBBLE_MAX_LINES = 8 // Max lines in speech bubble
export const SPEECH_BUBBLE_FONT_SIZE = 12 // Speech bubble font size
export const SPEECH_BUBBLE_DEFAULT_DURATION = 3 // Default speech bubble duration (seconds)
// --- Human appearance ---
export const HUMAN_SHOW_CHANCE = 0.15 // Chance per round for human appearance
export const HUMAN_COACH_CHANCE = 0.4 // Of appearances: coach (most common)
export const HUMAN_RUN_CHANCE = 0.7 // Of appearances: run across (cumulative cutoff)
// --- Haptic scaling ---
export const HAPTIC_MIN_SHAKE = 3 // Min shake intensity to trigger haptic
export const HAPTIC_SCALE = 8 // Haptic ms = intensity * scale (capped 100)