# 62 — BPC_DifficultyManager

## Blueprint Spec — UE 5.5–5.7

---

### Parent Class
`ActorComponent`

### Dependencies
- [`GI_GameFramework`](../01-core/04_GI_GameFramework.md) — Central game instance access
- [`BPC_PlayerMetricsTracker`](../02-player/15_BPC_PlayerMetricsTracker.md) — Input for difficulty tuning
- [`BPC_AtmosphereController`](64_BPC_AtmosphereController.md) — Output to atmosphere/scare systems
- [`BPC_HealthSystem`](../02-player/08_BPC_HealthSystem.md) — Health/revive tuning
- [`BPC_InventoryComponent`](../04-inventory/22_BPC_InventoryComponent.md) — Resource scarcity input

### Purpose
Central difficulty orchestrator. Dynamically adjusts game challenge based on player performance metrics and explicit difficulty profile settings. Operates as a non-intrusive governor that tunes encounter intensity, resource availability, AI aggression, puzzle complexity, and survival pressure without direct player awareness (unless overridden by explicit difficulty mode selection).

### Variables

| Name | Type | Description |
|------|------|-------------|
| `CurrentDifficulty` | EGameDifficulty | Active difficulty preset |
| `bIsAdaptive` | Bool | Auto-adjust based on performance |
| `AdaptiveBias` | Float (0.0–1.0) | Current adaptive tuning bias |
| `PlayerEfficiencyScore` | Float (0.0–1.0) | Rolling efficiency metric |
| `PlayerSurvivalScore` | Float (0.0–1.0) | Rolling survival metric |
| `ExplorationThoroughness` | Float (0.0–1.0) | How much player explores |
| `ResourceConsumptionRate` | Float | Scarcity/frequency of resources |
| `bIsPaused` | Bool | Pause all difficulty adjustments |
| `AdjustmentCooldown` | Float | Seconds between recalibrations |
| `LastAdjustmentTime` | Float | Timestamp of last adjustment |
| `PerformanceWindow` | TArray\<Float\> | Sliding window of recent metric samples |
| `MaxWindowSize` | Int | Max samples before averaging |

### Enums

| Enum | Values | Description |
|------|--------|-------------|
| `EGameDifficulty` | Story, Easy, Normal, Hard, Survival, Adaptive | Difficulty presets |

### Structs

| Struct | Fields | Description |
|--------|--------|-------------|
| `FDifficultyParams` | HealthMultiplier, DamageMultiplier, AmmoScarcity, EnemyAggression, PuzzleComplexity, FearIntensity, ReviveCount, CheckpointFrequency, TimedPressure | Tuning package |

### Functions

| Name | Inputs | Outputs | Description |
|------|--------|---------|-------------|
| `Initialize` | Difficulty: EGameDifficulty | — | Set initial difficulty state |
| `SetDifficulty` | Difficulty: EGameDifficulty | — | Apply explicit difficulty preset |
| `SetAdaptiveMode` | bEnabled: Bool | — | Toggle adaptive adjustment |
| `RecalculateDifficulty` | — | — | Analyze metrics and adjust |
| `GetCurrentParams` | — | FDifficultyParams | Return current tuning |
| `ApplyHealthMultiplier` | BaseValue: Float | Float | Scaled health |
| `ApplyDamageMultiplier` | BaseValue: Float | Float | Scaled damage |
| `GetAmmoScarcity` | — | Float | 0.0 = abundant, 1.0 = scarce |
| `GetEnemyAggressionModifier` | — | Float | Multiplier for AI aggression |
| `GetFearIntensityModifier` | — | Float | Scare system intensity |
| `GetReviveLimit` | — | Int | Max revives allowed |
| `GetCheckpointFrequency` | — | Float | Time between auto-saves |
| `IsTimedPressureActive` | — | Bool | Survival timer enabled |
| `PauseAdjustments` | bPaused: Bool | — | Freeze recalibration |

### Event Dispatchers

| Name | Parameters | Fired When |
|------|-----------|-----------|
| `OnDifficultyChanged` | NewDifficulty: EGameDifficulty | Difficulty preset changes |
| `OnAdaptiveShift` | ShiftAmount: Float | Adaptive tuning adjusts |
| `OnPerformanceWarning` | Metric: EPerformanceMetric, Value: Float | Player struggling/excelling |

### Blueprint Flow

```
[Initialize]
  └─► Set default difficulty based on game mode / save data
  └─► SetDifficulty(DefaultDifficulty)
  └─► If bIsAdaptive:
         Start recalibration timer (AdjustmentCooldown)
         Bind to BPC_PlayerMetricsTracker dispatchers

[RecalculateDifficulty — called by timer or metric threshold]
  └─► Gather metrics from BPC_PlayerMetricsTracker:
         DeathCount, HealingUsed, AmmoUsed, EnemiesKilled,
         TimeInCombat, TimeHidden, PuzzlesSolved
  └─► Compute PlayerEfficiencyScore =
         (EnemiesKilled / TimeInCombat) * ExplorationThoroughness
  └─► Compute PlayerSurvivalScore =
         1.0 - (DeathCount / MaxDeathsBeforeAdjust)
  └─► If PlayerSurvivalScore < LowThreshold:
         Reduce enemy aggression by 0.1
         Increase ammo drops by 15%
         Extend checkpoint frequency
         Fire OnPerformanceWarning(Struggling)
  └─► If PlayerEfficiencyScore > HighThreshold AND DeathCount == 0:
         Increase enemy aggression by 0.1
         Reduce ammo drops by 10%
         Shorten checkpoint frequency
         Fire OnPerformanceWarning(Excelling)
  └─► If bIsAdaptive:
         Lerp AdaptiveBias toward target
         BPC_AtmosphereController.SetTuningBias(AdaptiveBias)
  └─► Update LastAdjustmentTime
  └─► Broadcast OnAdaptiveShift

[SetDifficulty — explicit override]
  └─► Set CurrentDifficulty = input
  └─► bIsAdaptive = false if explicit non-Adaptive difficulty
  └─► Broadcast OnDifficultyChanged
  └─► Apply to dependent systems:
         BPC_HealthSystem.MaxRevives = GetReviveLimit()
         SS_SaveManager.AutoSaveInterval = GetCheckpointFrequency()
         BPC_AtmosphereController.FearIntensityBias = GetFearIntensityModifier()
```

### Communications With

| Target | Method | Why |
|--------|--------|-----|
| [`BPC_PlayerMetricsTracker`](../02-player/15_BPC_PlayerMetricsTracker.md) | Get Owner Component | Feed performance data |
| [`BPC_AtmosphereController`](65_BPC_AtmosphereController.md) | Direct call | Apply fear/intensity tuning |
| [`BPC_HealthSystem`](../02-player/08_BPC_HealthSystem.md) | Get Owner Component | Revive limits |
| [`SS_SaveManager`](../05-saveload/28_SS_SaveManager.md) | Game Instance | Checkpoint frequency |
| [`BPC_InventoryComponent`](../04-inventory/22_BPC_InventoryComponent.md) | Get Owner Component | Resource scarcity input |
| [`BPC_FearSystem`](90_BPC_FearSystem.md) | Direct call | Fear intensity modifier |
| [`BPC_AlertSystem`](../09-ai/60_BPC_AlertSystem.md) | Get on AI Controller | Enemy aggression modifier |

### Reuse Notes
- Single instance per game (attach to GameMode or persistent GameState)
- Designed to be optional; game works without it using static defaults
- Adaptive mode is additive; explicit difficulty modes override everything
- Performance window smooths out spikes before adjustment triggers
- All tuning values are configurable at runtime via console or debug menu