# 133 — Room Audio Zone (`BP_RoomAudioZone`)

## Purpose
A trigger volume placed in the world that automatically switches the audio reverb/occlusion profile when the player enters. When the player exits, it restores the previous room preset via a push/pop stack in `SS_AudioManager`. Supports nested room zones (room within building within cave) with priority-based override.

## Dependencies
- **Requires:** `SS_AudioManager` (132 — calls `SetRoomPreset` / `PopRoomPreset` on overlap), `DA_RoomAcousticPreset` (135 — assigned acoustic profile)
- **Required By:** Level Designers (placed in world)
- **Engine/Plugin Requirements:** MetaSounds plugin (for room reverb pipeline)

## Class Info
| Property | Value |
|----------|-------|
| **Parent Class** | `TriggerVolume` (or `Actor` with `BoxComponent`) |
| **Class Type** | Blueprint Actor |
| **Asset Path** | `Content/Framework/Audio/BP_RoomAudioZone.uasset` |
| **Implements Interfaces** | *(none)* |

---

## 1. Enums

*Uses enums defined elsewhere:*
- `E_AudioBusCategory` — from `SS_AudioManager` (132)

---

## 2. Structs

*Uses struct defined in `SS_AudioManager` (132):*
- `S_RoomAcousticProfile` — acoustic profile fields (reverb density, decay time, wet level, etc.)

---

## 3. Variables

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

| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `RoomPreset` | `DA_RoomAcousticPreset` | `None` | `Room Config` | Acoustic profile for this room |
| `TransitionTime` | `Float` | `1.5` | `Room Config` | Crossfade duration on enter (seconds) |
| `ExitTransitionTime` | `Float` | `1.0` | `Room Config` | Crossfade duration on exit (seconds) |
| `bOverrideOcclusion` | `Boolean` | `false` | `Room Config` | Override occlusion settings in this zone |
| `OcclusionTraceChannel` | `ETraceTypeQuery` | `Camera` | `Room Config` | Trace channel for per-source occlusion |
| `Priority` | `Integer` | `0` | `Room Config` | Higher priority zones override lower (for nested rooms) |
| `bIsActive` | `Boolean` | `true` | `State` | Whether this room zone is actively processing |
| `ZoneDebugColor` | `LinearColor` | `Cyan` | `Debug` | Color of the trigger volume in editor for visual identification |
| `bShowDebugInfo` | `Boolean` | `false` | `Debug` | Print room zone enter/exit to log |

### Internal (Private)

| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `bPlayerInside` | `Boolean` | `false` | `State` | Whether the player is currently inside this zone |

---

## 4. Functions

### Public Functions

#### `SetRoomAudioEnabled` → `void`
- **Description:** Toggle room audio processing. Used for narrative lock, void space override.
- **Parameters:**
  | Param | Type | Description |
  |-------|------|-------------|
  | `bEnabled` | `Boolean` | True to enable, false to disable zone processing |
- **Blueprint Authority:** Any
- **Flow:**
  1. Set `bIsActive = bEnabled`
  2. If `bEnabled == false` and `bPlayerInside`: force `PopRoomPreset` on `SS_AudioManager`
  3. If `bEnabled == true` and `bPlayerInside`: re-apply `SetRoomPreset`

#### `GetPriority` → `Integer`
- **Description:** Returns the zone priority. Used by `SS_AudioManager` for nested zone resolution.
- **Parameters:** *(none)*
- **Blueprint Authority:** Any (Pure)

#### `GetAcousticProfile` → `DA_RoomAcousticPreset`
- **Description:** Returns the assigned room acoustic preset.
- **Parameters:** *(none)*
- **Blueprint Authority:** Any (Pure)

---

## 5. Event Dispatchers

| Dispatcher | Parameters | Bind Access | Description |
|------------|-----------|-------------|-------------|
| `OnPlayerEnteredZone` | `ZoneName: FName` | `Public` | Fired when player enters (for gameplay logic) |
| `OnPlayerExitedZone` | `ZoneName: FName` | `Public` | Fired when player exits |
| `OnZoneEnabledChanged` | `bEnabled: Boolean` | `Public` | Fired when `SetRoomAudioEnabled` is called |

---

## 6. Overridden Events / Custom Events

### Event: `OnActorBeginOverlap`
- **Description:** Detects player character entering the trigger volume → calls `SS_AudioManager.SetRoomPreset()`.
- **Flow:**
  1. Validate `OtherActor` — is it the player character? (check tag `Player` or cast to `BP_PlayerCharacter`)
  2. If not player: return
  3. If `!bIsActive`: return
  4. Set `bPlayerInside = true`
  5. Get `SS_AudioManager` from Game Instance
  6. Call `SS_AudioManager.SetRoomPreset(RoomPreset)` with `TransitionTime`
  7. Fire `OnPlayerEnteredZone`
  8. If `bShowDebugInfo`: log zone name to console

### Event: `OnActorEndOverlap`
- **Description:** Player exits → restore previous room preset via `SS_AudioManager.PopRoomPreset()`.
- **Flow:**
  1. Validate `OtherActor` — is it the player?
  2. If not player: return
  3. If `!bIsActive`: return
  4. Set `bPlayerInside = false`
  5. Get `SS_AudioManager` from Game Instance
  6. Call `SS_AudioManager.PopRoomPreset()` (restores previous room from stack)
  7. Fire `OnPlayerExitedZone`
  8. If `bShowDebugInfo`: log to console

### Event: `BeginPlay`
- **Description:** Register this zone with a global zone manager if one exists. Configure trigger volume collision settings.
- **Flow:**
  1. Configure trigger volume: `SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap)`
  2. Set `Generate Overlap Events = true`
  3. Optionally set trigger volume color from `ZoneDebugColor`
  4. If `RoomPreset` is null: log warning, set `bIsActive = false`

### Event: `EndPlay`
- **Description:** Cleanup — if player is inside zone on destruction, force pop the room preset.
- **Flow:**
  1. If `bPlayerInside`: call `SS_AudioManager.PopRoomPreset()`
  2. Set `bPlayerInside = false`

---

## 7. Blueprint Graph Logic Flow

### Nested Room Zone Stack

```mermaid
flowchart TD
    A[Enter Room A - SmallRoom] --> B[SS_AudioManager.SetRoomPreset: SmallRoom]
    B --> C[Enter Room B - Bathroom, Priority > A]
    C --> D[SS_AudioManager.SetRoomPreset: Bathroom]
    D --> E[Exit Room B]
    E --> F[SS_AudioManager.PopRoomPreset → Restore SmallRoom]
    F --> G[Exit Room A]
    G --> H[SS_AudioManager.PopRoomPreset → Restore Default/Outdoor]
```

---

## 8. Room Preset Reference

### Included Room Presets (in `Content/Framework/Audio/RoomPresets/`)

| Preset Asset | Description | Typical Use |
|-------------|-------------|-------------|
| `DA_RoomAcousticPreset` | Base class | Parent for all presets |
| `DA_RP_SmallRoom` | Small room reverb | Offices, bedrooms, closets |
| `DA_RP_LargeHall` | Large hall reverb | Auditoriums, churches, lobbies |
| `DA_RP_Outdoor` | Outdoor (minimal reverb) | Default fallback, streets, forests |
| `DA_RP_Cave` | Cave/underground reverb | Caves, tunnels, basements |
| `DA_RP_VoidSpace` | Void/alt death space reverb | Alt death space, dream sequences |
| `DA_RP_Industrial` | Industrial/factory reverb | Factories, warehouses, hangars |
| `DA_RP_Bathroom` | Small tile reverb | Bathrooms, tiled corridors |

---

## 9. Communication Matrix

| Who Talks | How | What Is Sent |
|-----------|-----|-------------|
| `BP_RoomAudioZone` | `SS_AudioManager.SetRoomPreset()` | `DA_RoomAcousticPreset`, crossfade time |
| `BP_RoomAudioZone` | `SS_AudioManager.PopRoomPreset()` | *(none — restores previous from stack)* |
| `BP_RoomAudioZone` | `Dispatcher: OnPlayerEnteredZone` | `FName ZoneName` (for gameplay scripting) |
| `BP_RoomAudioZone` | `Dispatcher: OnPlayerExitedZone` | `FName ZoneName` |
| Level Designer | Direct placement in world | Adjusts `RoomPreset`, `Priority`, `TransitionTime` in Details Panel |
| Narrative System | `SetRoomAudioEnabled(false)` | Disables zone during cutscenes/void space |

---

## 10. Validation / Testing Checklist

- [ ] Player entering zone triggers `SetRoomPreset` with correct preset
- [ ] Reverb parameters smoothly crossfade over `TransitionTime`
- [ ] Player exiting zone triggers `PopRoomPreset` restoring previous room
- [ ] Nested zones: entering inner room, exiting restores outer room
- [ ] Priority: higher priority zone overrides lower priority when overlapping
- [ ] `SetRoomAudioEnabled(false)` during overlap — zone is disabled
- [ ] `SetRoomAudioEnabled(true)` after disable — zone reapplies
- [ ] Non-player actors do NOT trigger zone overlap
- [ ] Zone with null `RoomPreset` logs warning and remains inactive
- [ ] `bShowDebugInfo` logs enter/exit to console
- [ ] Zone destroyed while player inside — `PopRoomPreset` still called
- [ ] Edge case: Rapid enter/exit (player on boundary) — no audio glitching
- [ ] Edge case: `SS_AudioManager` not found — zone gracefully handles missing subsystem
- [ ] Edge case: Multiple zones with same `Priority` — last-entered wins

---

## 11. Reuse Notes

- Place multiple `BP_RoomAudioZone` actors throughout a level to create realistic acoustic transitions.
- Use `Priority` to handle overlapping zones — higher values override. Example: a bathroom (Priority=5) inside a house (Priority=0).
- `bOverrideOcclusion` enables per-source occlusion line traces in this zone — useful for walls, doors.
- The `OnPlayerEnteredZone` / `OnPlayerExitedZone` dispatchers allow gameplay logic to react to room changes (e.g., "You've entered the forbidden wing" audio sting).
- Zone scaling: Box components can be scaled to any size. Use multiple zones for irregularly shaped rooms.
- Debug mode (`bShowDebugInfo` + `ZoneDebugColor`) helps level designers visualize acoustic boundaries.

---

*Blueprint Spec: BP_RoomAudioZone — Trigger volume for automatic room acoustic switching. Architecture document: [`metasounds-audio-system.md`](../../architecture/metasounds-audio-system.md) Section 6.*
