# BPC_DeathCauseTracker — Death Cause Tracker

## Blueprint Spec — UE 5.5–5.7

---

### Parent Class
`ActorComponent`

### Dependencies
- **Requires:** [`BPC_HealthSystem`](../02-player/08_BPC_HealthSystem.md) — Receives OnDeath dispatcher for recording cause
- **Required By:** [`BPC_DeathHandlingSystem`](../05-saveload/BPC_DeathHandlingSystem.md) — Reads LastDeathCause and DeathHistory
- **Required By:** [`BPC_RunHistoryTracker`](../05-saveload/BPC_RunHistoryTracker.md) — Reads death history for summary
- **Required By:** [`BPC_AdaptiveEnvironmentDirector`](../10-adaptive/BPC_AdaptiveEnvironmentDirector.md) — Reads death patterns for adaptation
- **Engine/Plugin Requirements:** GameplayTags (for ChapterTag in DeathRecord)

### Purpose
Records the cause and context of the player's death for use by the death handling system, adaptive systems, and run summary. Tracks full session death history with cause type, location, instigator, timestamp, and chapter context.

---

## 1. Enums

```text
Enum Name: E_DeathCause
(DisplayName = "Death Cause")

Values:
  Melee          = 0    // Killed by melee attack
  Projectile     = 1    // Killed by projectile/firearm
  Environmental  = 2    // Killed by environment (fall, trap, fire zone)
  Scripted       = 3    // Scripted/cinematic kill
  Psychic        = 4    // Killed by psychic/supernatural force
  InstantKill    = 5    // Instant-kill mechanic
  Unknown        = 6    // Cause cannot be determined
```

---

## 2. Structs

### `S_DeathRecord`
| Field | Type | Description |
|-------|------|-------------|
| `Cause` | E_DeathCause | How the player died |
| `Location` | Vector | World position of death |
| `Instigator` | Actor | What/who killed the player (nullable) |
| `Timestamp` | Float | Game time of death in seconds |
| `ChapterTag` | GameplayTag | Which chapter the death occurred in |

---

## 3. Variables

### Configuration (Instance Editable, Expose On Spawn)

| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `MaxDeathHistorySize` | Integer | 50 | DeathTracking | Maximum number of death records to retain |

### Internal (Private / Protected, No Expose)

| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `LastDeathCause` | E_DeathCause | Unknown | Internal | Cause of the most recent death |
| `LastDeathLocation` | Vector | (0,0,0) | Internal | World position of last death |
| `LastDeathInstigator` | Actor | None | Internal | Actor that caused last death |
| `DeathHistory` | Array of S_DeathRecord | Empty | Internal | Full session death log |

---

## 4. Functions

### Public Functions

#### `RecordDeath` → `void`
- **Description:** Called when player dies. Stores cause, location, instigator, timestamp, and chapter tag into a new S_DeathRecord.
- **Parameters:**
  | Param | Type | Description |
  |-------|------|-------------|
  | `Cause` | E_DeathCause | How the player died |
  | `Location` | Vector | World position of death |
  | `Instigator` | Actor | Killing actor (optional) |
- **Blueprint Authority:** Any
- **Flow:** Create S_DeathRecord → populate fields → add to DeathHistory → update LastDeath* variables → trim history if over MaxDeathHistorySize → broadcast OnDeathRecorded

#### `GetLastDeathCause` → `E_DeathCause`
- **Description:** Returns the cause of the most recent death.
- **Parameters:** None
- **Blueprint Authority:** Any

#### `GetLastDeathLocation` → `Vector`
- **Description:** Returns the world location of the most recent death.
- **Parameters:** None
- **Blueprint Authority:** Any

#### `GetLastDeathInstigator` → `Actor`
- **Description:** Returns the actor that caused the most recent death (may be None).
- **Parameters:** None
- **Blueprint Authority:** Any

#### `GetDeathHistory` → `Array of S_DeathRecord`
- **Description:** Returns the full death history for this session.
- **Parameters:** None
- **Blueprint Authority:** Any

#### `GetDeathCount` → `Integer`
- **Description:** Returns the total number of deaths this session.
- **Parameters:** None
- **Blueprint Authority:** Any

#### `ClearDeathHistory` → `void`
- **Description:** Empties the death history and resets last death variables. Called on new game.
- **Parameters:** None
- **Blueprint Authority:** Server only (if multiplayer)

---

## 5. Event Dispatchers

| Dispatcher | Parameters | Bind Access | Description |
|------------|-----------|-------------|-------------|
| `OnDeathRecorded` | DeathRecord: S_DeathRecord | Public | New death entry added to history |
| `OnFirstDeath` | Cause: E_DeathCause | Public | First death of the session (for tutorials/achievements) |
| `OnDeathCountThreshold` | Count: Integer | Public | Death count reaches a configured threshold (e.g., 10, 25, 50) |

---

## 6. Overridden Events / Custom Events

### Event: `OnHealthSystemDeath`
- **Description:** Subscribes to [`BPC_HealthSystem`](../02-player/08_BPC_HealthSystem.md)`OnDeath` dispatcher on BeginPlay. Routes damage event data to `RecordDeath`.
- **Flow:**
  1. Extract DeathCause from S_DamageEvent
  2. Map DamageType to E_DeathCause (Physical→Melee or Projectile, Fire→Environmental, etc.)
  3. Get player world location
  4. Call RecordDeath(Cause, Location, Instigator)

---

## 7. Blueprint Graph Logic Flow

```mermaid
flowchart TD
    A[BeginPlay] --> B[Subscribe to BPC_HealthSystem.OnDeath]
    B --> C[Idle — waiting for death]
    C --> D{OnDeath dispatcher fires}
    D --> E[Map DamageType → E_DeathCause]
    E --> F[Get player world location]
    F --> G[Get GS_CoreGameState.ActiveChapterTag]
    G --> H[Create S_DeathRecord]
    H --> I[Add to DeathHistory array]
    I --> J[Update LastDeathCause / Location / Instigator]
    J --> K{DeathHistory count == 1?}
    K -->|Yes| L[Broadcast OnFirstDeath]
    K -->|No| M[Check threshold milestones]
    L --> N[Broadcast OnDeathRecorded]
    M --> N
```

---

## 8. Communication Matrix

| Who Talks | How | What Is Sent |
|-----------|-----|-------------|
| [`BPC_HealthSystem`](../02-player/08_BPC_HealthSystem.md) | Dispatcher (`OnDeath`) | `S_DamageEvent` (read Type, Instigator, HitLocation) |
| [`BPC_DeathHandlingSystem`](../05-saveload/BPC_DeathHandlingSystem.md) | Direct read | `LastDeathCause`, `LastDeathLocation`, `LastDeathInstigator` |
| [`BPC_RunHistoryTracker`](../05-saveload/BPC_RunHistoryTracker.md) | Direct read | `DeathHistory` array |
| [`BPC_AdaptiveEnvironmentDirector`](../10-adaptive/BPC_AdaptiveEnvironmentDirector.md) | Direct read | `DeathHistory` for death pattern analysis |
| [`SS_AchievementSystem`](../11-meta/SS_AchievementSystem.md) | Dispatcher (`OnDeathRecorded`) | Death count and cause for achievement checks |
| [`GS_CoreGameState`](../01-core/06_GS_CoreGameState.md) | Direct read | `ActiveChapterTag` for death record context |

---

## 9. Validation / Testing Checklist

- [ ] E_DeathCause enum has all 7 values defined
- [ ] S_DeathRecord struct contains all 5 fields
- [ ] RecordDeath correctly appends to DeathHistory and updates LastDeath* variables
- [ ] DeathHistory trimmed when exceeding MaxDeathHistorySize
- [ ] OnFirstDeath fires only on the first death of the session
- [ ] ClearDeathHistory resets all state for new game
- [ ] Edge case: Instigator can be None (environmental/fall deaths)
- [ ] Edge case: rapid successive deaths all recorded independently
- [ ] Edge case: death during cutscene with no damage event maps to Scripted or Unknown

---

## 10. Reuse Notes

- E_DeathCause can be extended per project (add new enum values)
- S_DeathRecord fields are generic enough for any genre
- MaxDeathHistorySize prevents unbounded memory growth in long sessions
- Death history is not persisted to save file by default — wire to I_Persistable if cross-session tracking needed
- ChapterTag in death record enables chapter-based analytics and adaptive tuning

---

*Specification based on Master Section 5.8, line 1836.*