--- id: wiki-2026-0508-dda title: Dynamic Difficulty Adjustment (DDA) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [DDA, dynamic difficulty, rubber banding, AI Director, flow state, adaptive difficulty] duplicate_of: none source_trust_level: B confidence_score: 0.85 verification_status: applied tags: [game-design, dda, dynamic-difficulty, flow, ai-director, player-modeling, adaptive] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: game design applicable_to: [Game Design, Adaptive Learning, ML Curriculum] --- # Dynamic Difficulty Adjustment (DDA) ## 매 한 줄 > **"매 player skill 의 real-time 매 difficulty 의 dial"**. Csikszentmihalyi 의 Flow zone 의 maintain. 매 Left 4 Dead 의 AI Director, 매 racing 의 rubber banding. 매 modern: 매 ML-driven player model + 매 ethical detect (gaming the system). 매 LMS adaptive learning 의 same principle. ## 매 핵심 ### 매 mechanism 1. **Player metric**: 매 win rate, HP remaining, time, deaths. 2. **Skill estimate**: 매 sliding window of recent. 3. **Adjustment**: 매 enemy stats / spawn / hint. 4. **Subtle**: 매 obvious 의 player 의 frustrate. ### 매 famous example - **Left 4 Dead AI Director** (Valve): 매 zombie spawn 의 control. - **Resident Evil 4**: 매 difficulty 의 silent. - **Mario Kart**: 매 rubber banding (item, speed). - **Crash Bandicoot**: 매 attempt 후 의 adjust. - **Mario AI** (research): 매 student 의 player. ### 매 method - **Heuristic**: 매 simple rule. - **Bayesian player model**: 매 skill posterior. - **RL-based**: 매 difficulty 의 policy 학습. - **MCTS-based**: 매 lookahead. ### 매 ethical / design constraint - **Subtle**: 매 player 의 perception X. - **Fair feel**: 매 effort-reward. - **Not patronize**: 매 매 player 의 skill ↑ 의 acknowledge. - **No gaming detection**: 매 player 의 intentional poor 의 abuse. ### 매 응용 1. **Action / shooter**: 매 enemy difficulty. 2. **Racing**: 매 rubber banding. 3. **Puzzle**: 매 hint. 4. **MMO raid**: 매 boss adjustment. 5. **Edu game / LMS**: 매 question difficulty. 6. **AI tutor**: 매 explanation depth. 7. **Aim training**: 매 [[Cognitive Training Software (eg Aim Lab_KovaaKs)]] 의 adaptive scenario. ### 매 modern AI 응용 - **Player modeling**: 매 ML 의 skill 의 estimate. - **RL-based DDA**: 매 difficulty controller 의 train. - **Generative content**: 매 procedurally adapted level. ## 💻 패턴 ### Sliding window skill estimator ```ts class SkillEstimator { private history: number[] = []; recordOutcome(win: boolean, time: number, hpLost: number) { const score = (win ? 1 : 0) * (60 / Math.max(time, 1)) * (1 - hpLost / 100); this.history.push(score); if (this.history.length > 20) this.history.shift(); } estimateSkill(): number { if (!this.history.length) return 0.5; return this.history.reduce((a, b) => a + b, 0) / this.history.length; } } ``` ### AI Director-style (probabilistic) ```ts class AIDirector { threatLevel = 0; // 0-1 update(player: Player) { const recentDamage = player.recentDamageTaken(); const ammoLow = player.ammo < 30; const downtime = player.timeWithoutCombat(); // 매 raise threat 의 calm if (downtime > 30) this.threatLevel = Math.min(1, this.threatLevel + 0.05); // 매 ease 의 stress if (recentDamage > 50 || ammoLow) this.threatLevel = Math.max(0, this.threatLevel - 0.1); } shouldSpawnEnemy(): boolean { return Math.random() < this.threatLevel; } enemyComposition() { if (this.threatLevel < 0.3) return 'easy_pack'; if (this.threatLevel < 0.7) return 'mixed'; return 'horde'; } } ``` ### Rubber banding (racing) ```ts function applyRubberBand(car: Car, leader: Car) { const distanceBehind = leader.position - car.position; // 매 subtle catch-up if (distanceBehind > 100) { car.maxSpeed *= 1.05; // 매 5% boost car.itemDropChance *= 1.5; // 매 better items } else if (distanceBehind < -50) { // 매 leader 의 small handicap car.maxSpeed *= 0.98; } } ``` ### Bayesian player model (IRT-inspired) ```python import numpy as np class BayesianPlayer: def __init__(self, prior_mean=0, prior_var=1): self.skill_mean = prior_mean self.skill_var = prior_var def update(self, item_difficulty, success): """매 item response theory.""" # 매 expected probability p_success = 1 / (1 + np.exp(-(self.skill_mean - item_difficulty))) # 매 posterior update (simplified Kalman) info = p_success * (1 - p_success) self.skill_var = 1 / (1 / self.skill_var + info) self.skill_mean += self.skill_var * info * (int(success) - p_success) def select_difficulty(self, items, target_p=0.7): """매 just-beyond comfort.""" return min(items, key=lambda d: abs( 1 / (1 + np.exp(-(self.skill_mean - d))) - target_p )) ``` ### RL-based DDA ```python class DifficultyController: """매 RL 의 매 player 의 engagement 의 maximize.""" def __init__(self): self.policy = QNetwork() def select_difficulty(self, player_state): actions = ['decrease', 'maintain', 'increase'] q_values = self.policy(player_state) return actions[q_values.argmax()] def reward(self, player_state): # 매 engagement = match length + retention + flow indicator return ( player_state.session_length * 0.3 + (1 if player_state.continued_after_match else 0) * 0.5 + player_state.subjective_satisfaction * 0.2 ) ``` ### Detect gaming the system ```python def detect_throw_match(player_history): """매 player 의 intentional poor 의 detect.""" recent = player_history[-10:] # 매 sudden drop in performance historical_avg = np.mean([h.score for h in player_history[:-10]]) recent_avg = np.mean([h.score for h in recent]) if recent_avg < historical_avg * 0.4: return 'WARN: possible throwing for DDA exploit' return None ``` ### Subtle communication (UX) ```ts function hidePlayerSeesAdjustment() { // 매 ❌ 매 obvious if (showText) showMessage('Difficulty decreased due to your performance'); // 매 ✅ 매 silent // 매 just adjust enemy stats internally. // 매 player 의 say "I'm getting better!" 매 actually 의 difficulty 의 ease. } ``` ### A/B test (DDA effectiveness) ```python def ab_test_dda(players_a_no_dda, players_b_with_dda): return { 'session_length_a': mean(p.session_length for p in players_a_no_dda), 'session_length_b': mean(p.session_length for p in players_b_with_dda), 'retention_d7_a': retention(players_a_no_dda, days=7), 'retention_d7_b': retention(players_b_with_dda, days=7), 'satisfaction_a': mean(p.satisfaction for p in players_a_no_dda), 'satisfaction_b': mean(p.satisfaction for p in players_b_with_dda), } ``` ### LMS adaptive (similar pattern) ```python def adaptive_quiz(student, item_pool): skill = student.estimated_skill # 매 zone of proximal development target_difficulty = skill + 0.5 # 매 just-beyond next_item = min(item_pool, key=lambda i: abs(i.difficulty - target_difficulty)) response = present(next_item, student) student.update_skill(next_item.difficulty, response.correct) return next_item ``` ### Procedural difficulty (level generation) ```python def generate_level(player_skill): return { 'enemy_count': int(10 + player_skill * 20), 'enemy_hp': 100 * (1 + player_skill * 0.5), 'puzzle_complexity': int(player_skill * 5), 'time_limit': 300 - int(player_skill * 100), 'powerup_density': max(0.1, 0.5 - player_skill * 0.3), } ``` ## 매 결정 기준 | Genre | DDA approach | |---|---| | Action / Shooter | AI Director (Valve-style) | | Racing | Rubber banding (subtle) | | Puzzle | Hint frequency | | MMO raid | Stat-tier difficulty | | RPG | Side content | | Edu game | Adaptive item (IRT) | | Esports / competitive | NO DDA (fairness) | | Casual mobile | Subtle DDA + retention focus | **기본값**: 매 Bayesian player model + 매 subtle adjust + 매 A/B test + 매 detect gaming. ## 🔗 Graph - 부모: [[Game-Design]] · [[Adaptive-Learning]] - 변형: [[AI-Director]] · [[Rubber-Banding]] · [[Player-Modeling]] - 응용: [[Cognitive Training Software (eg Aim Lab_KovaaKs)]] · [[Corporate-LMS-Training]] (adaptive) · [[Cognitive-Evaluation-Theory]] - Adjacent: [[Default Mode Network (DMN)]] (flow) · [[Deliberate-Practice]] · [[Combined Arms (제병협동) 전술]] ## 🤖 LLM 활용 **언제**: 매 game design. 매 adaptive learning system. 매 personalized challenge. **언제 X**: 매 esports / fairness-critical (no DDA). ## ❌ 안티패턴 - **Obvious DDA**: 매 player 의 perception → 매 motivation lose. - **Patronizing**: 매 매 player 의 skill 의 acknowledge X. - **Punishing skilled play**: 매 better → 매 harder feel of unfair. - **No detection 의 throw**: 매 exploit. - **DDA in competitive**: 매 fairness violation. - **Too aggressive adjust**: 매 whiplash. ## 🧪 검증 / 중복 - Verified (Csikszentmihalyi Flow, Valve AI Director paper, Hunicke MDA). - 신뢰도 B. - Related: [[Cognitive Training Software (eg Aim Lab_KovaaKs)]] · [[Corporate-LMS-Training]] · [[Cognitive-Evaluation-Theory]] · [[Deliberate-Practice]] · [[Combined Arms (제병협동) 전술]]. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — mechanism + 매 AI Director / rubber band / Bayesian / RL / detect-throw code |