refactor: extract magic numbers to named constants

Frontend: choreography selection ratios, morph trigger chances,
creator cameo/ultimate chances, dodge/counter probabilities.
Server: HP, K-factors, Elo divisor, tier thresholds, fight loop interval.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-08 23:34:05 +00:00
co-authored by Claude Opus 4.6
parent 1731a64ae8
commit 7c8e404cf1
8 changed files with 129 additions and 45 deletions
+12 -11
View File
@@ -5,6 +5,11 @@ import { generateSpriteSheet, generateJudgeSpriteSheet, generateHumanSpriteSheet
import type { Fighter, FightSceneConfig, RoundEvent, FightContext, ChoreoContext } from './fight/types'
export type { FightSceneConfig, RoundEvent } from './fight/types'
import { ARENA_THEMES, spriteAnims, CHALLENGE_THEMED, TIER_ULTIMATES, CREATOR_MOVES, CREATOR_ULTIMATES } from './fight/constants'
import {
CREATOR_ULTIMATE_CHANCE, CREATOR_THEMED_MOVE_RATIO,
CRIT_THEMED_RATIO, CHOREOGRAPHY_THEMED_RATIO, CHOREOGRAPHY_GENERIC_CUTOFF,
TIER_ULTIMATE_CHANCES,
} from './fight/config'
import { spawnSparks as _spawnSparks, spawnBulletHoles as _spawnBulletHoles, spawnExhaust as _spawnExhaust } from './fight/particles'
import { glitchRGB as _glitchRGB, scanlineGlitch as _scanlineGlitch, vhsTracking as _vhsTracking, dimensionalShift as _dimensionalShift } from './fight/effects'
import { spawnProjectile as _spawnProjectile } from './fight/projectiles'
@@ -46,9 +51,9 @@ import {
export function pickChoreography(challengeType: string, isCritical: boolean, _round: number, attackerTier: number = 0, attackerArchetype?: string): string {
// THE CREATOR: special move selection — 50% ultimate, 60% creator moves, rest normal
// THE CREATOR: special move selection
if (attackerArchetype === 'the_creator') {
const ultimateChance = isCritical ? 1.0 : 0.5
const ultimateChance = isCritical ? 1.0 : CREATOR_ULTIMATE_CHANCE
if (Math.random() < ultimateChance) {
// Creator gets ALL ultimates + their 4 exclusive ones
const all: string[] = [...CREATOR_ULTIMATES]
@@ -57,17 +62,15 @@ export function pickChoreography(challengeType: string, isCritical: boolean, _ro
}
return all[Math.floor(Math.random() * all.length)]
}
// 60% creator-themed, 40% normal selection
if (Math.random() < 0.6) {
if (Math.random() < CREATOR_THEMED_MOVE_RATIO) {
return CREATOR_MOVES[Math.floor(Math.random() * CREATOR_MOVES.length)]
}
// Fall through to normal selection
}
// Tier-gated ultimates: higher tier = higher chance of spectacular ultimate moves
// Tier 2: 15% chance, Tier 3: 20%, Tier 4: 30%, Tier 5: 40%
if (attackerTier >= 2) {
const ultimateChance = attackerTier === 2 ? 0.15 : attackerTier === 3 ? 0.20 : attackerTier === 4 ? 0.30 : 0.40
const ultimateChance = TIER_ULTIMATE_CHANCES[attackerTier] ?? TIER_ULTIMATE_CHANCES[5]
// On crits, double the chance
const roll = isCritical ? ultimateChance * 2 : ultimateChance
if (Math.random() < roll) {
@@ -85,8 +88,7 @@ export function pickChoreography(challengeType: string, isCritical: boolean, _ro
// Critical hits always get BIG moves (but can still be themed)
if (isCritical) {
const entry = CHALLENGE_THEMED[challengeType]
// 50% themed, 50% epic generic for crits
if (entry && Math.random() < 0.5) {
if (entry && Math.random() < CRIT_THEMED_RATIO) {
return entry.themed[Math.floor(Math.random() * entry.themed.length)]
}
const critMoves = [
@@ -111,11 +113,10 @@ export function pickChoreography(challengeType: string, isCritical: boolean, _ro
return fallback[Math.floor(Math.random() * fallback.length)]
}
// 60% themed, 25% generic fallback, 15% wild card
const roll = Math.random()
if (roll < 0.6) {
if (roll < CHOREOGRAPHY_THEMED_RATIO) {
return entry.themed[Math.floor(Math.random() * entry.themed.length)]
} else if (roll < 0.85) {
} else if (roll < CHOREOGRAPHY_GENERIC_CUTOFF) {
return entry.generic[Math.floor(Math.random() * entry.generic.length)]
} else {
const wild = [