--- id: wiki-2026-0508-게임-밸런싱 title: 게임 밸런싱 category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Game Balancing, 밸런스 디자인] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [game-design, balancing, simulation] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: Python/TypeScript framework: Unity/Unreal/web --- # 게임 밸런싱 ## 매 한 줄 > **"매 fairness × engagement × progression의 quantitative tuning loop"**. 게임 밸런싱은 단순 number tweak이 아닌, player skill curve와 reward schedule을 데이터 기반으로 calibrate하는 systems engineering이다. 2026 현업은 telemetry-driven A/B + LLM-assisted simulation으로 cycle을 일/주 단위로 단축한다. ## 매 핵심 ### 매 밸런싱 차원 - **Power balance**: weapon/character/spell 의 win-rate convergence to ~50%. - **Resource economy**: gold/XP/material 의 inflation/sink ratio. - **Difficulty curve**: time-to-mastery 의 monotonic with checkpoints. - **Matchmaking**: MMR/Elo/Glicko-2 — skill variance bounded. ### 매 측정 지표 - Win rate, pick rate, ban rate (MOBA/FGC). - Time-to-kill (TTK), DPS, EHP (effective HP). - Retention D1/D7/D30, session length, churn at level X. - Gini coefficient of resource distribution. ### 매 응용 1. League of Legends 의 patch cycle (2-week) — champion winrate band [47%, 53%]. 2. Hearthstone 의 nerf/buff 의 telemetry-driven (Vicious Syndicate stats). 3. Slay the Spire 의 Monte Carlo simulation 의 deck balance. 4. Destiny 2 의 sandbox team 의 sandbox tuning (Bungie quarterly). ## 💻 패턴 ### 1. Win-rate convergence target ```python # Bayesian winrate estimate with prior import numpy as np from scipy.stats import beta def champion_winrate(wins, losses, prior_a=50, prior_b=50): a = prior_a + wins b = prior_b + losses mean = a / (a + b) ci_low, ci_high = beta.ppf([0.025, 0.975], a, b) return mean, (ci_low, ci_high) # Patch decision: nerf if CI bound > 0.53 mean, (lo, hi) = champion_winrate(wins=12500, losses=10800) needs_nerf = lo > 0.53 ``` ### 2. DPS / TTK calculation ```python def time_to_kill(damage_per_shot, fire_rate_hz, target_hp, armor=0): effective_dps = damage_per_shot * fire_rate_hz * (1 - armor) return target_hp / effective_dps # Weapon balance check: TTK in [0.4s, 1.2s] band for w in weapons: ttk = time_to_kill(w.dmg, w.rpm/60, target_hp=200, armor=0.1) assert 0.4 <= ttk <= 1.2, f"{w.name} TTK={ttk:.2f}s out of band" ``` ### 3. Resource economy faucet/sink ```typescript type Economy = { faucets: number; sinks: number; supply: number }; function inflationRate(econ: Economy, dt: number): number { const net = econ.faucets - econ.sinks; return net / econ.supply / dt; // per-day inflation } // Target: |inflation| < 0.02 per week (2%) ``` ### 4. Monte Carlo deck simulation ```python def simulate_deck(deck, opponents, n_runs=10000): wins = 0 for _ in range(n_runs): opp = random.choice(opponents) result = play_match(deck, opp) wins += result == "win" return wins / n_runs # Auto-balance: card value = marginal winrate Δ when included ``` ### 5. Elo / Glicko-2 matchmaking ```python def glicko2_update(rating, rd, opponents): # rd = rating deviation; volatility tracked separately g = lambda phi: 1 / math.sqrt(1 + 3 * phi**2 / math.pi**2) # ... (full Glicko-2 spec) return new_rating, new_rd ``` ### 6. Difficulty curve fitting ```python import numpy as np # Player completion rate per level levels = np.arange(1, 51) completion = np.array([...]) # telemetry # Target: monotonic decrease, no cliff > 15% drop diff = np.diff(completion) cliffs = np.where(diff < -0.15)[0] # cliffs → level redesign candidates ``` ### 7. A/B test with CUPED variance reduction ```python def cuped_estimate(treatment_y, control_y, treatment_x, control_x): # x = pre-experiment covariate (e.g., D7 retention) theta = np.cov(np.concatenate([treatment_y, control_y]), np.concatenate([treatment_x, control_x]))[0,1] / \ np.var(np.concatenate([treatment_x, control_x])) adj_t = treatment_y - theta * treatment_x adj_c = control_y - theta * control_x return adj_t.mean() - adj_c.mean() ``` ### 8. LLM-assisted balance review (2026) ```python # Claude Opus 4.7 의 patch note review prompt = f""" Patch diff: {diff} Telemetry (last 7d): {telemetry_json} Identify: 1. Champions exceeding [47%, 53%] winrate band. 2. Hidden interactions (item × champion synergy outliers). 3. Risk score (1-10) per change. """ review = claude.messages.create(model="claude-opus-4-7", ...) ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Competitive PvP | Winrate convergence + telemetry-driven nerf cycle | | Single-player | Difficulty curve + retention cliff analysis | | Gacha/F2P | Whale vs F2P parity + pity timer math | | Esports patch | 2-week cycle + pro-play meta watch | | New release | Closed beta MC sim + open beta A/B | **기본값**: telemetry → Bayesian winrate → 2-week patch cycle 의 [47%, 53%] band. ## 🔗 Graph - 부모: [[Game_Design]] ## 🤖 LLM 활용 **언제**: patch note generation, telemetry anomaly detection, balance hypothesis brainstorming, sim scenario writing. **언제 X**: 최종 numerical tuning (designer judgment + playtesting 의 X-able), competitive integrity decision. ## ❌ 안티패턴 - **Whale-only balancing**: F2P player 의 churn 의 무시. - **Knee-jerk nerf**: 1-day data 의 over-react — sample size 의 부족. - **Symmetric balance obsession**: asymmetric design 의 intentional 의 flatten의 X. - **Nerf-only meta**: power creep 의 reverse — fun 의 erosion. - **Ignoring rank-stratified data**: bronze 와 challenger 의 winrate 의 different — aggregate 의 misleading. ## 🧪 검증 / 중복 - Verified (Riot Games engineering blog, GDC talks 2023-2025, Vicious Syndicate). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — game balancing full content with patterns |