# Audio, VFX, Cinematics & UI

V5 is one open-world narrative game that has to _sound_, _spark_, _cut_, and
_read_ like seven at once: the neon pulse of an Urban heist, the AM-radio hiss
of a 1947 Period interrogation, the wide golden-hour swell of a Frontier outlaw
trail, the medieval-Slavic sign-craft of a Hunter contract, the
electronic-orchestral hybrid of a Sci-Fi boarding op, and the white-room hush of
a cross-cell Mind Palace deduction — all emitted by one shared presentation
stack keyed on the same `EV5Cell` enum the gameplay layer routes on. Four Unreal
C++ modules own that job: **`V5Audio`** (MetaSound voice routing, the dialogue
ducking director, dynamic per-cell music, period radio, DualSense haptics,
Dolby/Sony/Steam spatial backends, and the shipping audio content manifest),
**`V5VFX`** (Niagara catalogs for muzzle/blood/debris, the five Witcher signs,
sci-fi biotic/tech powers, weather, vehicle damage, the Mind Palace evidence
orb, and a per-quality-tier particle budget), **`V5Cinematics`** (Sequencer
style catalog, an 8,000-setup per-companion camera library, the pre-rendered
master pipeline, a full Director-Mode NLE, a cross-cell replay editor, and the
Period behind-the-scenes documentary viewer), and **`V5UI`** (the CommonUI
shell, six per-cell HUDs, the dialogue wheel, the volumetric Mind Palace room,
photo mode, the companion-app bridge, and a 16-language menu localization
manifest). Where the netcode and GAS layers must be _provably correct_, this
layer has the inverse remit: it is cosmetic, it may cost whatever the platform
budget allows, and its one hard rule is that it must never write back into state
the simulation hashes. This page is part of the **Platform, Services & Live
Operations** group; the section hub is
[../V5_ARCHITECTURE.md](../V5_ARCHITECTURE.md).

## What ships, honestly

The four modules are **real, deterministic Unreal C++ that builds and is
exercised by automation**, but they are a _decision, data, and validation_
layer, and the honest distance from the engine runtime differs sharply per
module. Six qualifications so the rest of the page reads at face value:

1. **These modules are pure-function builders, not stateful subsystems.** Unlike
   V4's `UGameInstanceSubsystem` dispatchers, every entry point here is a
   `static` `BlueprintPure` method on a `UBlueprintFunctionLibrary`
   (`UV5_Audio_RouterSubsystem`, `UV5_VFX_Budget`, `UV5_Cine_DirectorMode`,
   `UV5_UI_Shell`, …). They take inputs and return manifests, view-models, or
   validation structs with no side effects, so the same call yields the same
   answer on every machine and every rule is unit-testable without a live world.

2. **`V5UI` is the one module with genuine engine-runtime instantiation — and it
   is substantial.** `V5UIWidgets.cpp` ships real `UCommonActivatableWidget` /
   `UUserWidget` subclasses that build their own widget trees at runtime via
   `WidgetTree->ConstructWidget<>()`, plus a real
   `AV5_UI_MindPalaceVolumetricRoom` `AActor` that spawns `USceneComponent`s
   into a `UWorld`. The widget tests `NewObject<>` these widgets and
   `SpawnActor<>` the room into a transient world and assert their built trees.
   This is a larger live-engine surface than V4's single MVVM touch.

3. **The other three modules link their middleware loosely — or not at all.**
   `V5VFX.Build.cs` links the real **`Niagara`** module but never calls
   `UNiagaraFunctionLibrary` — it builds system _definitions_ and budget math.
   `V5Audio.Build.cs` and `V5Cinematics.Build.cs` do **not even link**
   MetasoundEngine, MovieScene, or Sequencer; their MetaSound graph ids and
   level sequence paths are soft `FName` / `FSoftObjectPath` references to
   content that is named but not authored.

4. **There are zero binary `.uasset` presentation assets.** `V5/ue/Content`
   holds **no** `.uasset` at all. The soft paths the C++ builds —
   `/Game/V5VFX/Niagara/…`, `/Game/V5Cinematics/…`, `/Game/V5/UI/…` — name
   content that is specified but pending. Three JSON sidecars
   (`V5/audio/audio-production-manifest.json`,
   `V5/cinematics/cinematic-asset-manifest.json`,
   `cinematic-director-mode-manifest.json`) are schema-versioned design
   contracts, honestly labeled as data.

5. **The decision math is genuine and value-pinned.** Distance attenuation in
   decibels, the dB→amplitude loudness sum, dialogue ducking, the per-quality
   Niagara budget, the Fibonacci-sphere orb layout, and the radial
   dialogue-wheel geometry are real algorithms asserted against specific
   computed numbers across **22 automation specs** (4 audio + 3 VFX + 7
   cinematics + 8 UI). They would fail against a hardcoded return.

6. **The validators fail loud.** `ValidateCameraBudget`,
   `ValidateDirectorModeTool`, `ValidateCrossCellReplayEditor`,
   `ValidateDocumentary`, and `ValidateTier2State` accumulate a
   `TArray<FString>`/`Issues` list and only set `bValid` when it is empty — they
   reject drift (wrong counts, missing approval, overlapping clips) rather than
   rubber-stamping.

Everything below is real where it cites a function and a line; where it names an
authored asset or an un-called plugin, that is the specified-but-pending part.

## The shared shape: builders, validators, one real widget runtime

```mermaid
flowchart TD
    subgraph BFL["V5 presentation — pure-function C++ (this page)"]
        AUD["V5Audio<br/>Router · DuckingDirector · DynamicMusic · PeriodRadio · Haptics · ContentManifest"]
        VFX["V5VFX<br/>Niagara catalogs + per-tier particle budget"]
        CIN["V5Cinematics<br/>Styles · 8k camera lib · DirectorMode NLE · ReplayEditor · Documentary"]
        UI["V5UI<br/>Build*State view-models + validators"]
    end
    GAS["GAS verbs / combat / dialogue / heist"] --> AUD & VFX & CIN
    UI -->|reads, never writes| GAS
    UI ==>|"NewObject / SpawnActor (real)"| RT["Live UWorld: CommonUI widgets + MindPalace AActor"]
    VFX -. "links but never calls" .-> NIA["Niagara module"]
    AUD -. soft FName .-> MS["MetaSound graphs — not authored, not linked"]
    CIN -. soft path .-> LS["LevelSequence .uasset — not authored, Sequencer not linked"]
    UI -. soft class .-> WBP["WBP_* designer assets — not authored"]
```

The thick edge is the boundary that is genuinely crossed: `V5UI` instantiates
and runs engine objects. The dashed edges are soft references awaiting authored
content (and, for audio/cinematics, a plugin link as well).

## Audio — `V5Audio`

### Voice routing and the spatial mix

`UV5_Audio_RouterSubsystem::BuildVoiceRoute` (`V5AudioSystems.cpp:147`) stamps a
voice source onto the dialogue bus with a cell-tuned attenuation radius (Sci-Fi
40 m, others 28 m), a Mind-Palace priority bump (90 vs 75), occlusion enabled
for every non-stereo backend, and a per-cell/per-backend MetaSound graph id. The
real math is `EvaluateSpatialMix` (`:205`): for each route on the requested
backend within radius it computes a distance attenuation
`clamp(distMeters × −0.8, −36, 0)` dB, accumulates loudness as
`Σ pow(10, (VolumeDb + AttenDb) / 20)`, converts back with `20 × log₁₀(Σ)`,
tracks the highest-priority audible source, and flags `bWithinBackendBudget`
against the backend's `MaxSpatialSources`. The `V5.Audio.SpatialMixing` spec
feeds four routes — one in range, one priority-120 in range, one 1 km away, one
on a different backend — and asserts exactly two audible Dolby sources,
`voice.priority` selected, and loudness above −30 dB: a hardcoded return could
not satisfy all four.

### Dialogue ducking and dynamic music

`UV5_Audio_DialogueDirector::ApplyDialogueDucking` (`:265`) subtracts a real dB
offset from the mix — music **−9 dB** and radio **−14 dB** under full dialogue,
a lighter **−3 / −5 dB** in bark-only mode — and the spec asserts the bark duck
leaves music _louder_ than the dialogue duck, a relation only correct arithmetic
produces. `BuildMixSnapshot` (`:165`) sets per-state bus levels (Combat music −1
dB, Cinematic −2/−5, Dialogue −6/−5, Mind Palace −4/−8) and auto-applies ducking
when dialogue is active. `UV5_Audio_DynamicMusic::SelectMusicState` (`:310`)
resolves the priority order Mind Palace → Cinematic → Combat → Exploration (the
spec proves Mind Palace wins even with combat+cinematic also true), and
`BuildDynamicMusicGraph` emits a per-cell layered-stem graph with a faster
Sci-Fi transition (1.25 s vs 2.0 s).

### Period radio, haptics, and the content manifest

`UV5_Audio_PeriodRadio::BuildPeriodRadioMetaSound` (`:291`) gates the band on
the era: AM-only at `EraYear ≤ 1947` (`period_am` bank), FM at `≥ 1968` or in
the Urban cell (`period_fm`) — asserted at 1947 and 1968. `BuildHapticCue`
(`:342`) returns DualSense profiles with distinct low/high motor frequencies and
an intensity clamp: Weapon (120/220 Hz, adaptive-trigger, 0.08 s, transient),
HorseTrot (55/92 Hz, looping, 0.32 s), GravityTransition (35/180 Hz, sustained
1.2 s). `BuildShippingContentManifest` (`:391`) assembles the launch audio
budget and computes — not asserts — its own pass flags: three composer clusters
covering all five primary cells, five score budgets totalling **40
original-score hours**, nine SFX categories summing to **4,730 unique cues**
(floor 4,500), twelve VO languages × 10,000 = **120,000 recorded lines**, **18
period radio stations + 140 TV channels**, and three binaural backends (Dolby
128 / Sony 360 96 / Steam 128 sources). `V5.Audio.BackendsHapticsAndContent`
pins every one of those numbers.

## VFX — `V5VFX`

`V5VFX` is a Niagara _catalog and budget_ module: it builds typed system
definitions with soft `/Game/V5VFX/Niagara/…` paths, GPU-sim flags, and
per-platform particle caps, then proves a quality-tier budget over them — it
never spawns a particle. The catalog families (`V5VFXSystems.cpp`) are the three
shared impacts (muzzle/blood/debris), the **five Witcher signs** each with a
base and a charged variant (10 variants, charged spawn rate 48 vs base 24), five
sci-fi biotic/tech powers, five weather systems (rain/snow/dust/fog/solar-flare,
each carrying a visibility multiplier), three Chaos-gated vehicle-damage
systems, the Mind Palace evidence orb (with a high-contrast MPC swap), and seven
per-cell emission curves. `BuildAllNiagaraSystems` (`:220`) composes them into a
**22-system** catalog (asserted exactly).

`EvaluateNiagaraBudget` (`:244`) is the real gate. Each quality tier carries a
particle cap, a visible-system cap, and a `BudgetScale`: Switch 2 Performance
9,000 / 32 / 0.6×, Switch 2 Quality 14,000 / 36 / 1.0×, Console 32,000 / 72 /
1.5×, PC Ultra 64,000 / 128 / 2.0×. Estimated particles are
`Σ round(MaxParticlesSwitch2 × BudgetScale)` across the catalog, and
`bWithinBudget` requires both the particle and the system count under cap. The
`V5.VFX.Switch2Budget` spec asserts the 22-system catalog fits the two Switch 2
tiers and that the Quality cap is stricter than Console.
`BuildPerCellEmissionCurves` (`:207`) emits a real three-key attack-peak-release
envelope (start 0/0, peak at t = 0.35, release at t = 1.0) with a per-cell peak
scale (Hunter 1.15, Sci-Fi 1.25, Mind Palace 0.75), verified for shape and
ordering. The pending inch is uniform: turn a definition into a
`UNiagaraFunctionLibrary::SpawnSystem*` call against an authored system.

## Cinematics — `V5Cinematics`

This is the richest of the four modules and models cinematics as typed contracts
plus fail-loud validators rather than a live `ULevelSequencePlayer`.

**Style catalog and sequencer beats.** `BuildStyleCatalog` (`:410`) encodes the
four documented cinematography languages with real lens data: Noir (50 mm, 42°
FOV, 16:9, high-contrast, Dutch angles — Urban/Period/Steampunk), Epic Vista (24
mm, 70°, 2.39:1 — Frontier/Hunter), Handheld Doc-Cine (35 mm, 58° — Sci-Fi), and
Cinematic Widescreen (40 mm, 2.39:1 — Sci-Fi/Mind Palace).
`BuildSequencerCinematic` (`:390`) lays a four-shot
Establishing→Closeup→OverShoulder→ActionBeat spine over a clamped duration, and
`BuildCampaignBeatManifest` (`:579`) emits 256 in-engine beats that
`ValidateSequencerBudget` (`:1338`) checks for in-engine count, a duration cap,
and present sequence paths.

**The per-companion camera library.** `BuildPerCompanionCameraLibrary` (`:463`)
generates **8 companions × 5 cells × 200 setups = 8,000 camera setups**, each
with a cell-derived rig, focal length, boom length, and projected shot coverage
summing to 30,000 — every number asserted in
`V5.Cinematics.CameraLibraryBudget`. `ValidateCameraBudget` (`:489`) rejects any
drift in the counts and any setup that is not director-approved.

**Pipeline, Director Mode, replay editor, documentary.** `BuildPipeline`
(`:540`) fixes the 4K master pipeline (DPX + OpenEXR masters, AV1 + H.265
delivery, ACEScg HDR) with twelve key story moments. `BuildDirectorModeTool`
(`:612`) and its validator (`:699`) are a genuine non-linear editor contract:
five timeline tracks (Video/Camera/Audio/Subtitle/Marker), twelve clips, eleven
cuts (hard / dissolve / match / J / L, with J/L/dissolve cuts requesting audio
pre-roll), and three Movie Render Queue export presets — the validator enforces
unique ids, in-bounds track references, continuity-checked cuts, and
non-destructive editing. `BuildCrossCellReplayEditor` (`:853`) and
`ValidateCrossCellReplayEditor` (`:918`) extend that to a privacy-aware splice
tool: two source clips per cell, N−1 splices, and validation that every clip is
rights-cleared, privacy-scrubbed, replay-hash-verified, non-overlapping, and
that every splice crosses a cell boundary with audio normalization.
`BuildPeriodBehindTheScenesDocumentary` (`:1061`) builds a 42-minute, 8-chapter,
24-still viewer with theater / chapter-select / still-gallery modes, and
`ValidateDocumentary` (`:1218`) checks chapter start-time continuity and
Period/Noir scoping.

## UI / HUD — `V5UI`

### The real widget runtime

`V5UI` is the module that touches the engine for real. The data layer is a
family of `Build*State` pure functions — shell, main menu, cell select,
settings, the six per-cell HUD models, the dialogue wheel, the volumetric Mind
Palace, photo mode, the companion-app bridge, and localization. The _runtime_
layer (`V5UIWidgets.cpp`) wraps each of these in an actual CommonUI/UMG widget
that constructs its tree procedurally — no designer `.uasset` required.
`UV5_UI_ShellWidget` (a `UCommonActivatableWidget`) builds one button per
registered screen and one per navigation action, maintains an activatable screen
stack with `PushScreen` / `PopScreen`, and overrides
`NativeGetDesiredFocusTarget` for gamepad focus; the spec proves it registers
**ten screens**, grows and shrinks the stack, and restores the prior active
screen on pop.

### Shell, menu, settings

`UV5_UI_MainMenu::BuildMainMenuState` (`V5UISystems.cpp:415`) emits nine entries
with online-gated `Continue`/`Bureau HQ`/`Companion App`, a **six-slide curated
Workshop showcase carousel** with a wrapping `AdvanceCuratedShowcase`, and a
**twelve-month community spotlight calendar**; the widget test confirms the
carousel advances to index 1 and wraps backward to 5.
`UV5_UI_Settings::BuildSettingsForCategory` (`:533`) is not a toggle list — it
defines real entries across six categories (Display/Audio/Input/Network/
Accessibility/Privacy) with control types, min/max/step ranges, per-cell flags
on the eight aim/difficulty accessibility settings, and `bPrivacyCritical` flags
on do-not-sell, DSAR export, and under-13 controls. The settings widget renders
one tab per category and the matching control widget per declared control type.

### HUDs, dialogue wheel, Mind Palace, photo mode

`UV5_UI_HUDWidgetBase` resolves a per-cell route through the mode router, asks
the shell for a HUD model, and mounts a meter strip, a quick-action bar, and
conditional sub-panels; the seven launch HUD subclasses supply only their route.
The `V5.UI.Widgets.HUDs` spec asserts the Frontier HUD mounts a mount-status
panel and tracks horse stamina, the Vice-Squad HUD mounts the investigation
notebook, and the Sci-Fi ship HUD mounts the dialogue wheel — the documented
per-cell vocabularies, realized as built widget trees.
`UV5_UI_DialogueWheelWidget` lays spokes radially on a canvas at `360 × i / n`
degrees offset −90° so spoke 0 sits at the top; the spec proves a four-spoke
Hunter wheel places spoke 0 at 0° and spoke 1 at 90° with the Hunter flavor
token. `AV5_UI_MindPalaceVolumetricRoom` distributes one evidence orb per clue
on a **Fibonacci sphere** (golden angle `π × (3 − √5)`, `ComputeOrbLayout` at
`:569`); the test spawns the actor into a transient `UWorld`, builds three orbs,
and asserts each sits on the room shell at distinct positions.
`UV5_UI_PhotoMode` exposes eleven tools, two video export profiles (5 s silent +
15 s AAC-audio MP4), and twelve shooting locations, with `ValidateTier2State`
(`:829`) enforcing 48 kHz stereo audio, privacy-scrubbed metadata, all-cell
location coverage, and a 12-location floor. The companion-app bridge gates
web-view / AR / VTuber surfaces on sign-in and under-13 status and asserts
no-raw-camera and no-raw-voice upload, and the localization manifest covers
**sixteen culture codes**.

## How it connects (and where it does not yet)

Presentation sits **downstream of gameplay and reads, never writes**. The reload
montages, hit-react variants, dialogue-wheel cursor, and cinematic-finisher root
motion selected by the GAS, combat, and animation layer
([./gas-animation-input.md](./gas-animation-input.md)) are what _should_ trigger
a dialogue route, a ducking snapshot, a Niagara cue, a Sequencer beat, or a HUD
re-route; the HUD view-models read state and push nothing back. The
interrogation pressure meters, heist phase banners, and Mind Palace deduction
threads these surfaces present originate in
[./interrogation-dialogue-and-heist.md](./interrogation-dialogue-and-heist.md),
and the consent flags, privacy-scrubbed replay metadata, and telemetry toggles
the settings, replay editor, and companion bridge expose are governed by the
data and live-ops contracts in
[./telemetry-build-and-data.md](./telemetry-build-and-data.md).

The honest remaining work is uniform and identical in shape to the animation
layer's: the math, manifests, and validators are real and tested, and `V5UI`
already instantiates live engine widgets — but the authored `.uasset` content
(MetaSound graphs, Niagara systems, level sequences, designer WBP skins), the
plugin links for audio and cinematics, and the final emission calls (Niagara
spawn, LevelSequence play, MetaSound playback) are the pending integration.
These are **shippable units awaiting a call site, a plugin link, and authored
content**, not stubs — every decision they make is computed, deterministic, and
pinned to a known-correct value.

## Related

- [GAS, Animation & Input](./gas-animation-input.md) — the verbs, montages, and
  finisher root motion this layer dresses with audio, VFX, and cinematics
- [Interrogation, Dialogue & Heist](./interrogation-dialogue-and-heist.md) — the
  pressure meters, dialogue choices, and heist phases these surfaces present
- [Telemetry, Build & Data](./telemetry-build-and-data.md) — the consent flags,
  cook path, and `.uasset` content pipeline the authored presentation assets
  flow through
- The section hub: [../V5_ARCHITECTURE.md](../V5_ARCHITECTURE.md)
