unreal-memory-streaming

Unreal 5.8 Memory and Streaming

Control Unreal residency, streaming, and hitches

---
name: unreal-memory-streaming
description: Budget, load, retain, stream, evict, precache, and diagnose runtime content in Unreal Engine 5.8. Use for unexpected asset residency, hard and soft reference chains, Asset Manager load lifetimes, async loading, Memory Insights, LLM, texture streaming pools and mip quality, Streaming Virtual Texturing, Nanite streaming, World Partition readiness, load-time hitches, shader or PSO compilation hitches, PSO precaching, bundled PSO caches, or memory/load regression testing.
---

# Unreal 5.8 Memory and Streaming

## Classify the failure before changing policy

Read [`references/system-selector.md`](references/system-selector.md) and
[`references/budgets-and-evidence.md`](references/budgets-and-evidence.md).

1. Define target device, memory pools, storage, build, scenario, cold/warm state, and readiness budget.
2. Classify the problem: dependency residency, retained allocation, streaming budget, IO/load latency,
   render-resource readiness, or shader/PSO compilation.
3. Capture the appropriate evidence: Reference Viewer/Size Map, Memory Insights/LLM, Asset Loading
   Insights, texture/VT/Nanite stats, Render Resource Viewer, or PSO validation.
4. Name the owner, load trigger, residency boundary, unload condition, and failure behavior.
5. Change one dependency edge, budget, lead time, representation, or precache policy.
6. Repeat the identical cold or warm traversal on target hardware and verify memory, quality, and hitch.

Use neighboring skills for their owned decisions:

- Asset schemas, Primary Asset rules, bundles, cook inclusion ->
  [`../unreal-data-assets-tables/SKILL.md`](../unreal-data-assets-tables/SKILL.md)
- World Partition cells, sources, loading range, teleports ->
  [`../unreal-world-partition/SKILL.md`](../unreal-world-partition/SKILL.md)
- Trace capture and Memory/Asset Loading Insights ->
  [`../unreal-insights-profiling/SKILL.md`](../unreal-insights-profiling/SKILL.md)
- GPU resource/pass budgets ->
  [`../unreal-rendering-performance/SKILL.md`](../unreal-rendering-performance/SKILL.md)

Load only what applies:

- [`references/reference-graphs-and-residency.md`](references/reference-graphs-and-residency.md)
- [`references/async-loading-and-lifetime.md`](references/async-loading-and-lifetime.md)
- [`references/texture-streaming.md`](references/texture-streaming.md)
- [`references/virtual-texturing.md`](references/virtual-texturing.md)
- [`references/geometry-and-world-readiness.md`](references/geometry-and-world-readiness.md)
- [`references/pso-and-shader-hitches.md`](references/pso-and-shader-hitches.md)
- [`references/memory-profiling.md`](references/memory-profiling.md)
- [`references/load-hitch-diagnosis.md`](references/load-hitch-diagnosis.md)
- [`references/regression-and-recipes.md`](references/regression-and-recipes.md)

## Required answer format

Return:

1. **Target budget and workload**, including cold/warm state.
2. **Failure class and evidence source**.
3. **Owner and dependency/residency graph**.
4. **Load, readiness, use, retention, and unload sequence**.
5. **Exact setting/API/policy change** and predicted memory/latency/quality effect.
6. **Cooked-build A/B proof** and failure-path test.
7. **Uncertainty**, profiler overhead, and adjacent skill routing.

## Hard rules

- Do not equate soft references with unloaded content; loaded assets require explicit lifetime ownership.
- Do not replace every hard edge with a soft edge; use hard references inside one intentional residency unit.
- Never synchronously load in latency-sensitive gameplay unless a measured, bounded exception is accepted.
- Separate CPU memory, GPU allocations, texture pools, VT pools, Nanite pools, and package size.
- Do not set `r.Streaming.PoolSize=0` or disable streaming as a shipping fix.
- Do not raise a pool before proving the target budget has headroom and the content demand is valid.
- Treat low mips, fallback meshes, collision, shaders/PSOs, registration, and gameplay initialization as
  part of readiness—not only UObject load completion.
- Memory allocation tracing must start with the process; a late trace cannot reconstruct old allocations.
- Validate PSO precache misses and wait for required startup compiles; a warm driver cache can hide failure.
- Prove behavior in a cooked target build. PIE, loose editor content, and a warm dev PC are insufficient.

See [`references/sources.md`](references/sources.md) for the UE 5.8 primary-source trail.

## Classify the failure before changing policy

Read [`references/system-selector.md`](/unreal/unreal-memory-streaming/system-selector/) and
[`references/budgets-and-evidence.md`](/unreal/unreal-memory-streaming/budgets-and-evidence/).

1. Define target device, memory pools, storage, build, scenario, cold/warm state, and readiness budget.
2. Classify the problem: dependency residency, retained allocation, streaming budget, IO/load latency,
   render-resource readiness, or shader/PSO compilation.
3. Capture the appropriate evidence: Reference Viewer/Size Map, Memory Insights/LLM, Asset Loading
   Insights, texture/VT/Nanite stats, Render Resource Viewer, or PSO validation.
4. Name the owner, load trigger, residency boundary, unload condition, and failure behavior.
5. Change one dependency edge, budget, lead time, representation, or precache policy.
6. Repeat the identical cold or warm traversal on target hardware and verify memory, quality, and hitch.

Use neighboring skills for their owned decisions:

- Asset schemas, Primary Asset rules, bundles, cook inclusion ->
  [`../unreal-data-assets-tables/SKILL.md`](/unreal/unreal-data-assets-tables/)
- World Partition cells, sources, loading range, teleports ->
  [`../unreal-world-partition/SKILL.md`](/unreal/unreal-world-partition/)
- Trace capture and Memory/Asset Loading Insights ->
  [`../unreal-insights-profiling/SKILL.md`](/unreal/unreal-insights-profiling/)
- GPU resource/pass budgets ->
  [`../unreal-rendering-performance/SKILL.md`](/unreal/unreal-rendering-performance/)

Load only what applies:

- [`references/reference-graphs-and-residency.md`](/unreal/unreal-memory-streaming/reference-graphs-and-residency/)
- [`references/async-loading-and-lifetime.md`](/unreal/unreal-memory-streaming/async-loading-and-lifetime/)
- [`references/texture-streaming.md`](/unreal/unreal-memory-streaming/texture-streaming/)
- [`references/virtual-texturing.md`](/unreal/unreal-memory-streaming/virtual-texturing/)
- [`references/geometry-and-world-readiness.md`](/unreal/unreal-memory-streaming/geometry-and-world-readiness/)
- [`references/pso-and-shader-hitches.md`](/unreal/unreal-memory-streaming/pso-and-shader-hitches/)
- [`references/memory-profiling.md`](/unreal/unreal-memory-streaming/memory-profiling/)
- [`references/load-hitch-diagnosis.md`](/unreal/unreal-memory-streaming/load-hitch-diagnosis/)
- [`references/regression-and-recipes.md`](/unreal/unreal-memory-streaming/regression-and-recipes/)

## Required answer format

Return:

1. **Target budget and workload**, including cold/warm state.
2. **Failure class and evidence source**.
3. **Owner and dependency/residency graph**.
4. **Load, readiness, use, retention, and unload sequence**.
5. **Exact setting/API/policy change** and predicted memory/latency/quality effect.
6. **Cooked-build A/B proof** and failure-path test.
7. **Uncertainty**, profiler overhead, and adjacent skill routing.

## Hard rules

- Do not equate soft references with unloaded content; loaded assets require explicit lifetime ownership.
- Do not replace every hard edge with a soft edge; use hard references inside one intentional residency unit.
- Never synchronously load in latency-sensitive gameplay unless a measured, bounded exception is accepted.
- Separate CPU memory, GPU allocations, texture pools, VT pools, Nanite pools, and package size.
- Do not set `r.Streaming.PoolSize=0` or disable streaming as a shipping fix.
- Do not raise a pool before proving the target budget has headroom and the content demand is valid.
- Treat low mips, fallback meshes, collision, shaders/PSOs, registration, and gameplay initialization as
  part of readiness—not only UObject load completion.
- Memory allocation tracing must start with the process; a late trace cannot reconstruct old allocations.
- Validate PSO precache misses and wait for required startup compiles; a warm driver cache can hide failure.
- Prove behavior in a cooked target build. PIE, loose editor content, and a warm dev PC are insufficient.

See [`references/sources.md`](/unreal/unreal-memory-streaming/sources/) for the UE 5.8 primary-source trail.

unreal 5.8 memory and streaming budget, load, retain, stream, evict, precache, and diagnose runtime content in unreal engine 5.8. use for unexpected asset residency, hard and soft reference chains, asset manager load lifetimes, async loading, memory insights, llm, texture streaming pools and mip quality, streaming virtual texturing, nanite streaming, world partition readiness, load-time hitches, shader or pso compilation hitches, pso precaching, bundled pso caches, or memory/load regression testing. async loading and lifetime async loading and lifetime owned load sequence 1. gather soft paths or primary asset ids before the transition. 2. request through asset manager or fstreamablemanager::requestasyncload. 3. retain the fstreamablehandle when cancellation, progress, combined requests, or residency ownership matters. 4. on completion, verify request state and every required asset; callbacks may arrive after the caller's original state changed. 5. create/register render, physics, audio, and gameplay resources in a bounded readiness phase. 6. transfer assets into a hard owner for the exact use lifetime or keep the governing handle alive. 7. on cancellation/transition, stop dependent work, release owners/handles, and verify collection/eviction. fstreamablemanager keeps requested assets referenced through the completion delegate; afterward the caller must retain them if needed. a soft pointer path does not itself own residency. race and failure checks - owner destroyed before completion; - two requests for the same asset with different consumers; - cancel after io began but before callback; - partial bundle failure or missing cooked dependency; - async completion followed by synchronous resource creation hitch; - unload while a component/task/delegate still uses the asset; - stale callback applies content to a new state/level/character. use a request generation/token and weak owner where appropriate. completion means “asset available,” not automatically “gameplay-ready.” budgets and evidence budgets and evidence record before analysis: | dimension | required context | |---|---| | hardware | platform, ram/vram/unified memory, storage, driver/os | | build | commit, configuration, cooked/pie, device profile | | workload | map, path, speed, camera, content counts, duration | | cache state | cold process/os/driver/ddc versus warmed state | | budgets | peak/resident memory by pool, ready latency, hitch threshold, quality floor | | capture | trace channels/stats, markers, start/end, sampling overhead | measure separately: - process/platform committed and resident memory; - engine/llm allocation categories; - uobject/assets and retained ownership; - gpu resource allocations; - conventional texture streaming pool; - each virtual-texture physical pool and page-table memory; - nanite streaming pool; - transient load/decompression/pso compile peaks; - package/install size. do not sum overlapping counters. define whether each value is reserved, allocated, resident, wanted, budgeted, or transient. compare cold and warm runs when the player can experience both. geometry and world readiness geometry and world readiness nanite nanite streams fine-grained geometry pages. r.nanite.streaming.streamingpoolsize trades memory for fewer io/decompression requests; too small a pool can thrash even in a static view. use nanite streaming geometry visualization and nanitestats before changing it. validate package/storage cost separately. conventional meshes and skeletal content per-platform lods reduce render cost and may reduce memory when higher lods are stripped or excluded by platform policy. confirm which lod/render resources are resident in render resource viewer. do not assume an unseen mesh releases while a component, asset, or streaming handle still owns it. world partition readiness world partition cell loading is only one layer. ready-to-enter must include: - required cell activated/loaded state; - collision and navigation ready; - required assets and bundles loaded; - texture/nanite/vt quality above the declared floor; - render/physics components registered; - psos required for first visible use compiled; - gameplay initialization complete. derive preload lead distance from maximum approach speed × worst measured readiness latency plus look- ahead and safety margin. for teleports, use a temporary destination streaming source and wait on the world partition subsystem, then apply the broader readiness gate. avoid globally inflating loading range to solve one path; it raises residency and concurrent io everywhere. load and streaming hitch diagnosis load and streaming hitch diagnosis 1. mark the player action/region entry and capture timing plus loadtime/file channels as needed. 2. inspect asset loading insights package order, async priorities, serialization, and game-thread waits. 3. correlate file io, decompression, uobject creation, postload, component registration, render/physics resource creation, pso compile, and gc. 4. determine whether work is synchronous, async but completed too late, or async followed by a blocking readiness phase. 5. move/preload only the causal work, increase lead time, or amortize creation across frames. | symptom | first evidence | |---|---| | first pickup/effect hitches | package load, component registration, pso/decode readiness | | entering region hitches | world partition/cell activation, file io, texture/nanite demand | | memory spike then gc hitch | transient allocations, object churn, retained load handles | | asset says loaded but appears late | render/physics resource or pso readiness | | cold run hitches, warm run does not | os/driver/cache-sensitive io or compilation | | async request still stalls | late request, completion on critical path, sync dependency inside postload | never “fix” by hiding the trace interval behind a shorter loading screen. if blocking is required, own it with a real loading transition and an explicit complete/timeout/failure contract. memory profiling memory profiling memory insights start allocation tracing with the process: text mygame.exe -trace=default,memory mygame.exe -trace=default,memory,metadata,assetmetadata use marked a/b timestamps to query allocations live at a point, retained across an action, freed during an interval, or monotonically growing across repetitions. metadata improves asset/class attribution but increases trace volume. late connect cannot reconstruct allocations made before tracing began. low-level memory tracker launch with -llm for tagged totals or -llmcsv for periodic csv under saved/profiling/llm. inspect stat llm, stat llmfull, stat llmplatform, and stat llmoverhead where available. default tracker allocations are a subset of platform tracker totals; do not add them together. asset/assetclass tag sets are experimental and add memory/runtime overhead. use them only for targeted diagnosis and record that overhead. interpretation - growth that stabilizes may be an intentional cache; prove its cap and eviction; - repeated retained growth after teardown suggests surviving ownership; - high alloc/free rate with stable total is churn, not a leak; - llm category attribution and detailed allocation callstacks answer different questions; - gpu resources, driver memory, mapped files, and platform allocations may not equal uobject estimates. pso and shader compilation hitches pso and shader compilation hitches ue 5.8 enables pso precaching where the rhi supports it. component precaching gathers material, vertex- factory, render-state, and mesh-pass psos after load and compiles asynchronously. validate 1. test a cooked development build with an empty/cold driver cache on representative consumer cpu cores. 2. enable r.psoprecache.validation 1 for lightweight numbers or 2 for detailed miss logging. 3. inspect stat psoprecache and shader pipeline cache runtime hitch statistics. 4. correlate first-visible hitch with pso compilation rather than asset io/registration. 5. wait during a loading screen until required outstanding compiles reach zero; use fshaderpipelinecache::numprecompilesremaining() for the governing check. if a component's pso is not ready, the proxy delay strategy can skip the draw or show default material; allowing the draw to block risks a hitch. pick the visual/readiness policy explicitly. bundled cache boundary runtime precaching should cover most cases. add a manually recorded bundled graphics pso cache when validation proves misses or unsupported collection paths remain. record representative content on each platform/rhi, merge/stabilize through the documented cook pipeline, ship the cache, and repeat cold-cache validation. ray-tracing psos are not supported by the bundled-cache workflow documented for ue 5.8. do not judge from a warm developer driver cache. new materials, vertex factories, passes, quality tiers, rhi changes, and content patches require renewed coverage. reference graphs and residency reference graphs and residency audit an unexpected load 1. select the suspect asset and open reference viewer. 2. inspect referencers, dependencies, hard/soft edges, management references, and reference tree depth. 3. open size map for the asset and its dependencies; use asset audit for class/type/cooked-size detail. 4. confirm the runtime owner with memory insights/llm; editor graph size is not runtime residency proof. 5. identify the earliest hard edge that crosses the intended residency boundary. 6. convert only that boundary to a soft/primary asset load contract, then prove cook and lifetime. use a hard reference when owner and target must always be resident together. use tsoftobjectptr, tsoftclassptr, or fsoftobjectpath when the dependency must load on demand. use primary asset ids and bundles when many callers need governed discovery and phase-specific residency. common accidental roots: - gameinstance/subsystem/default object references; - always-loaded maps, huds, gamemodes, singletons, or data assets; - blueprint class defaults that reference presentation-heavy classes; - arrays/catalogs holding hard class or asset pointers; - an async-loaded object copied into a long-lived hard owner; - delegates/tasks/components retaining the owner after expected teardown. report the root and complete chain. removing the leaf from memory without changing its surviving owner does not fix retention. regression and recipes regression and recipes regression record | metric | baseline | candidate | budget/result | |---|---:|---:|---| | peak process/platform memory | | | | | steady memory after traversal | | | | | texture/vt/nanite pool pressure | | | | | ready latency / worst hitch ms | | | | | pso misses/runtime compile hitches | | | | | visual quality/fallback result | | | | run repeated cold and warm samples. preserve device profile, build, route, speed, camera, content, and cache preparation. reject wins that shift work past the capture, lower required quality, or break cook. symptom recipes | symptom | bounded experiment | |---|---| | opening one menu loads a level's content | reference viewer from widget/class default; soften first boundary | | textures stay blurry | build/inspect streaming data, then compare wanted versus budgeted mips | | texture pool over budget | identify valid demand/forced/non-streaming owners before pool or mip change | | vt tiles flicker | identify saturated format pool; a/b fixed pool size within vram budget | | static nanite view keeps streaming | inspect pool thrash; a/b pool or resident demand | | repeated spawn/despawn grows ram | marked memory insights retained-allocation query | | first material use hitches | cold pso validation; wait/precache or cover documented misses | | teleport arrives into missing world | destination source plus complete readiness gate and timeout | ue 5.8 primary sources ue 5.8 primary sources - memory insights - low-level memory tracker - reference viewer - asset management - asynchronous asset loading - texture streaming overview - building texture streaming data - texture streaming configuration - texture streaming metrics - streaming virtual texturing - virtual texture memory pools - runtime virtual texturing - pso precaching - creating a bundled pso cache - nanite technical details pages were checked against ue 5.8 documentation on 2026-07-19. reconfirm trace channels, pool semantics, platform/rhi support, pso workflow, defaults, and feature maturity after an engine upgrade. system selector system selector | question | primary evidence/system | |---|---| | why is this asset loaded? | reference viewer/reference tree, asset manager audit | | what owns retained cpu memory? | memory insights + llm tags/callstacks | | what owns gpu memory? | render resource viewer + platform/rhi metrics | | why are textures blurry or thrashing? | stat streaming, texture accuracy/resolution views | | why do virtual textures show low-res tiles? | vt pool stats/visualization and feedback/upload demand | | why does entering a region hitch? | asset loading insights, file/loadtime trace, world partition evidence | | why does first rendering hitch? | pso precache validation and shader pipeline cache hitch stats | | why does geometry pop or stream forever? | nanite stats/pool or world partition readiness | | why did memory grow after repeated action? | marked memory insights allocation query | do not combine all streaming systems into one “pool.” each has separate ownership, telemetry, eviction, and quality behavior. texture streaming texture streaming diagnose before changing the pool 1. build texture streaming data: build dropdown -> build texture streaming. 2. use primitive distance, mesh uv density, material texture scales, and required texture resolution accuracy/view modes to find bad bounds, uv density, scale analysis, or insufficient residency. 3. run stat streaming and record texture, streaming, wanted, budget, over-budget, and update time. 4. reproduce the target camera path and distinguish temporary cached mips from sustained demand. controls | cvar | effect/tradeoff | |---|---| | r.streaming.poolsize | texture-pool mb; larger reduces pressure but consumes target memory | | r.streaming.framesforfullupdate | larger lowers streamer cpu work but reacts more slowly | | r.streaming.maxtempmemoryallowed | more staging may improve throughput but raises transient memory | | r.streaming.mipbias | larger bias reduces wanted resolution and quality | | r.streaming.usepertexturebias | applies bias selectively to fit the pool rather than degrading every wanted mip | | r.streaming.limitpoolsizetovram | caps pool against available gpu memory where supported | r.texturestreaming 0, r.streaming.poolsize 0, r.streaming.useallmips, and r.streaming.fullyloadusedtextures are diagnostic/showcase controls, not default shipping fixes. for a controlled wanted-resolution test, r.streaming.dropmips 2 removes cached/hidden mips so the required texture resolution view reflects visible demand; restore it before final measurement. fix stale material-instance streaming data, wrong mesh uv density, oversized bounds, forced residency, incorrect texture groups, and excessive source resolution before buying a larger pool. streaming and runtime virtual texturing streaming and runtime virtual texturing use streaming virtual texturing (svt) for large cooked textures/udims when tile-level residency beats whole-mip streaming. use runtime virtual texturing (rvt) for gpu-generated/cacheable surface data such as landscape blending. do not convert content solely because conventional texture streaming is poorly configured. physical pools - page-table memory grows on demand and generally remains until all related content is released. - each vt physical pool is a fixed-size lru cache matched by format/tile configuration. - configure serialized pools under project settings -> engine -> virtual texture pool. - transient auto-grown pools exist only for the editor session; copy validated estimates into fixed pools for cooked builds. - if visible tiles exceed a matching pool, continual eviction produces low-resolution/flickering tiles. use stat virtualtexturing for update/upload cost and page-table counters; use stat virtualtexturememory for pool memory. inspect each format/layer pool independently. larger pools reduce eviction but permanently reserve more gpu memory. increasing upload limits/feedback resolution can reduce latency while increasing cpu/gpu/upload work. tune a repeatable traversal and test camera cuts, fast motion, multiple views, and every device profile. rvt low mips for large worlds may require far-away actors to remain resident. bake/stream low mips when that trades runtime generation and residency for acceptable disk/streaming cost.

Async loading and lifetime

# Async loading and lifetime

## Owned load sequence

1. Gather soft paths or Primary Asset IDs before the transition.
2. Request through Asset Manager or `FStreamableManager::RequestAsyncLoad`.
3. Retain the `FStreamableHandle` when cancellation, progress, combined requests, or residency ownership
   matters.
4. On completion, verify request state and every required asset; callbacks may arrive after the caller's
   original state changed.
5. Create/register render, physics, audio, and gameplay resources in a bounded readiness phase.
6. Transfer assets into a hard owner for the exact use lifetime or keep the governing handle alive.
7. On cancellation/transition, stop dependent work, release owners/handles, and verify collection/eviction.

`FStreamableManager` keeps requested assets referenced through the completion delegate; afterward the
caller must retain them if needed. A soft pointer path does not itself own residency.

## Race and failure checks

- owner destroyed before completion;
- two requests for the same asset with different consumers;
- cancel after IO began but before callback;
- partial bundle failure or missing cooked dependency;
- async completion followed by synchronous resource creation hitch;
- unload while a component/task/delegate still uses the asset;
- stale callback applies content to a new state/level/character.

Use a request generation/token and weak owner where appropriate. Completion means “asset available,”
not automatically “gameplay-ready.”

Budgets and evidence

# Budgets and evidence

Record before analysis:

| Dimension | Required context |
|---|---|
| Hardware | platform, RAM/VRAM/unified memory, storage, driver/OS |
| Build | commit, configuration, cooked/PIE, device profile |
| Workload | map, path, speed, camera, content counts, duration |
| Cache state | cold process/OS/driver/DDC versus warmed state |
| Budgets | peak/resident memory by pool, ready latency, hitch threshold, quality floor |
| Capture | trace channels/stats, markers, start/end, sampling overhead |

Measure separately:

- process/platform committed and resident memory;
- engine/LLM allocation categories;
- UObject/assets and retained ownership;
- GPU resource allocations;
- conventional texture streaming pool;
- each virtual-texture physical pool and page-table memory;
- Nanite streaming pool;
- transient load/decompression/PSO compile peaks;
- package/install size.

Do not sum overlapping counters. Define whether each value is reserved, allocated, resident, wanted,
budgeted, or transient. Compare cold and warm runs when the player can experience both.

Geometry and world readiness

# Geometry and world readiness

## Nanite

Nanite streams fine-grained geometry pages. `r.Nanite.Streaming.StreamingPoolSize` trades memory for
fewer IO/decompression requests; too small a pool can thrash even in a static view. Use Nanite Streaming
Geometry visualization and `NaniteStats` before changing it. Validate package/storage cost separately.

## Conventional meshes and skeletal content

Per-platform LODs reduce render cost and may reduce memory when higher LODs are stripped or excluded by
platform policy. Confirm which LOD/render resources are resident in Render Resource Viewer. Do not assume
an unseen mesh releases while a component, asset, or streaming handle still owns it.

## World Partition readiness

World Partition cell loading is only one layer. Ready-to-enter must include:

- required cell activated/loaded state;
- collision and navigation ready;
- required assets and bundles loaded;
- texture/Nanite/VT quality above the declared floor;
- render/physics components registered;
- PSOs required for first visible use compiled;
- gameplay initialization complete.

Derive preload lead distance from maximum approach speed × worst measured readiness latency plus look-
ahead and safety margin. For teleports, use a temporary destination streaming source and wait on the
World Partition subsystem, then apply the broader readiness gate. Avoid globally inflating loading range
to solve one path; it raises residency and concurrent IO everywhere.

Load and streaming hitch diagnosis

# Load and streaming hitch diagnosis

1. Mark the player action/region entry and capture Timing plus `loadtime`/`file` channels as needed.
2. Inspect Asset Loading Insights package order, async priorities, serialization, and Game-thread waits.
3. Correlate file IO, decompression, UObject creation, PostLoad, component registration, render/physics
   resource creation, PSO compile, and GC.
4. Determine whether work is synchronous, async but completed too late, or async followed by a blocking
   readiness phase.
5. Move/preload only the causal work, increase lead time, or amortize creation across frames.

| Symptom | First evidence |
|---|---|
| first pickup/effect hitches | package load, component registration, PSO/decode readiness |
| entering region hitches | World Partition/cell activation, file IO, texture/Nanite demand |
| memory spike then GC hitch | transient allocations, object churn, retained load handles |
| asset says loaded but appears late | render/physics resource or PSO readiness |
| cold run hitches, warm run does not | OS/driver/cache-sensitive IO or compilation |
| async request still stalls | late request, completion on critical path, sync dependency inside PostLoad |

Never “fix” by hiding the trace interval behind a shorter loading screen. If blocking is required, own it
with a real loading transition and an explicit complete/timeout/failure contract.

Memory profiling

# Memory profiling

## Memory Insights

Start allocation tracing with the process:

```text
MyGame.exe -trace=default,memory
MyGame.exe -trace=default,memory,metadata,assetmetadata
```

Use marked A/B timestamps to query allocations live at a point, retained across an action, freed during
an interval, or monotonically growing across repetitions. Metadata improves asset/class attribution but
increases trace volume. Late connect cannot reconstruct allocations made before tracing began.

## Low-Level Memory Tracker

Launch with `-LLM` for tagged totals or `-LLMCSV` for periodic CSV under `Saved/Profiling/LLM`.
Inspect `stat LLM`, `stat LLMFULL`, `stat LLMPlatform`, and `stat LLMOverhead` where available. Default
tracker allocations are a subset of platform tracker totals; do not add them together.

Asset/AssetClass tag sets are Experimental and add memory/runtime overhead. Use them only for targeted
diagnosis and record that overhead.

## Interpretation

- growth that stabilizes may be an intentional cache; prove its cap and eviction;
- repeated retained growth after teardown suggests surviving ownership;
- high alloc/free rate with stable total is churn, not a leak;
- LLM category attribution and detailed allocation callstacks answer different questions;
- GPU resources, driver memory, mapped files, and platform allocations may not equal UObject estimates.

PSO and shader compilation hitches

# PSO and shader compilation hitches

UE 5.8 enables PSO precaching where the RHI supports it. Component precaching gathers material, vertex-
factory, render-state, and mesh-pass PSOs after load and compiles asynchronously.

## Validate

1. Test a cooked Development build with an empty/cold driver cache on representative consumer CPU cores.
2. Enable `r.PSOPrecache.Validation 1` for lightweight numbers or `2` for detailed miss logging.
3. Inspect `stat PSOPrecache` and Shader Pipeline Cache runtime hitch statistics.
4. Correlate first-visible hitch with PSO compilation rather than asset IO/registration.
5. Wait during a loading screen until required outstanding compiles reach zero; use
   `FShaderPipelineCache::NumPrecompilesRemaining()` for the governing check.

If a component's PSO is not ready, the proxy delay strategy can skip the draw or show default material;
allowing the draw to block risks a hitch. Pick the visual/readiness policy explicitly.

## Bundled cache boundary

Runtime precaching should cover most cases. Add a manually recorded bundled graphics PSO cache when
validation proves misses or unsupported collection paths remain. Record representative content on each
platform/RHI, merge/stabilize through the documented cook pipeline, ship the cache, and repeat cold-cache
validation. Ray-tracing PSOs are not supported by the bundled-cache workflow documented for UE 5.8.

Do not judge from a warm developer driver cache. New materials, vertex factories, passes, quality tiers,
RHI changes, and content patches require renewed coverage.

Reference graphs and residency

# Reference graphs and residency

## Audit an unexpected load

1. Select the suspect asset and open Reference Viewer.
2. Inspect referencers, dependencies, hard/soft edges, management references, and Reference Tree depth.
3. Open Size Map for the asset and its dependencies; use Asset Audit for class/type/cooked-size detail.
4. Confirm the runtime owner with Memory Insights/LLM; editor graph size is not runtime residency proof.
5. Identify the earliest hard edge that crosses the intended residency boundary.
6. Convert only that boundary to a soft/Primary Asset load contract, then prove cook and lifetime.

Use a hard reference when owner and target must always be resident together. Use `TSoftObjectPtr`,
`TSoftClassPtr`, or `FSoftObjectPath` when the dependency must load on demand. Use Primary Asset IDs and
bundles when many callers need governed discovery and phase-specific residency.

Common accidental roots:

- GameInstance/subsystem/default object references;
- always-loaded maps, HUDs, GameModes, singletons, or Data Assets;
- Blueprint class defaults that reference presentation-heavy classes;
- arrays/catalogs holding hard class or asset pointers;
- an async-loaded object copied into a long-lived hard owner;
- delegates/tasks/components retaining the owner after expected teardown.

Report the root and complete chain. Removing the leaf from memory without changing its surviving owner
does not fix retention.

Regression and recipes

# Regression and recipes

## Regression record

| Metric | Baseline | Candidate | Budget/result |
|---|---:|---:|---|
| peak process/platform memory | | | |
| steady memory after traversal | | | |
| texture/VT/Nanite pool pressure | | | |
| ready latency / worst hitch ms | | | |
| PSO misses/runtime compile hitches | | | |
| visual quality/fallback result | | | |

Run repeated cold and warm samples. Preserve device profile, build, route, speed, camera, content, and
cache preparation. Reject wins that shift work past the capture, lower required quality, or break cook.

## Symptom recipes

| Symptom | Bounded experiment |
|---|---|
| opening one menu loads a level's content | Reference Viewer from widget/class default; soften first boundary |
| textures stay blurry | build/inspect streaming data, then compare wanted versus budgeted mips |
| texture pool over budget | identify valid demand/forced/non-streaming owners before pool or mip change |
| VT tiles flicker | identify saturated format pool; A/B fixed pool size within VRAM budget |
| static Nanite view keeps streaming | inspect pool thrash; A/B pool or resident demand |
| repeated spawn/despawn grows RAM | marked Memory Insights retained-allocation query |
| first material use hitches | cold PSO validation; wait/precache or cover documented misses |
| teleport arrives into missing world | destination source plus complete readiness gate and timeout |

UE 5.8 primary sources

# UE 5.8 primary sources

- [Memory Insights](https://dev.epicgames.com/documentation/en-us/unreal-engine/memory-insights-in-unreal-engine)
- [Low-Level Memory Tracker](https://dev.epicgames.com/documentation/en-us/unreal-engine/using-the-low-level-memory-tracker-in-unreal-engine)
- [Reference Viewer](https://dev.epicgames.com/documentation/en-us/unreal-engine/reference-viewer-in-unreal-engine)
- [Asset Management](https://dev.epicgames.com/documentation/en-us/unreal-engine/asset-management-in-unreal-engine)
- [Asynchronous Asset Loading](https://dev.epicgames.com/documentation/en-us/unreal-engine/asynchronous-asset-loading-in-unreal-engine)
- [Texture Streaming Overview](https://dev.epicgames.com/documentation/en-us/unreal-engine/texture-streaming-overview-for-unreal-engine)
- [Building Texture Streaming Data](https://dev.epicgames.com/documentation/en-us/unreal-engine/building-texture-streaming-data-in-unreal-engine)
- [Texture Streaming Configuration](https://dev.epicgames.com/documentation/en-us/unreal-engine/texture-streaming-configuration-in-unreal-engine)
- [Texture Streaming Metrics](https://dev.epicgames.com/documentation/en-us/unreal-engine/texture-streaming-metrics-in-unreal-engine)
- [Streaming Virtual Texturing](https://dev.epicgames.com/documentation/en-us/unreal-engine/streaming-virtual-texturing-in-unreal-engine)
- [Virtual Texture Memory Pools](https://dev.epicgames.com/documentation/en-us/unreal-engine/virtual-texture-memory-pools-in-unreal-engine)
- [Runtime Virtual Texturing](https://dev.epicgames.com/documentation/en-us/unreal-engine/runtime-virtual-texturing-in-unreal-engine)
- [PSO Precaching](https://dev.epicgames.com/documentation/en-us/unreal-engine/pso-precaching-for-unreal-engine)
- [Creating a Bundled PSO Cache](https://dev.epicgames.com/documentation/en-us/unreal-engine/manually-creating-bundled-pso-caches-in-unreal-engine)
- [Nanite Technical Details](https://dev.epicgames.com/documentation/en-us/unreal-engine/nanite-technical-details)

Pages were checked against UE 5.8 documentation on 2026-07-19. Reconfirm trace channels, pool semantics,
platform/RHI support, PSO workflow, defaults, and feature maturity after an engine upgrade.

System selector

# System selector

| Question | Primary evidence/system |
|---|---|
| Why is this asset loaded? | Reference Viewer/Reference Tree, Asset Manager audit |
| What owns retained CPU memory? | Memory Insights + LLM tags/callstacks |
| What owns GPU memory? | Render Resource Viewer + platform/RHI metrics |
| Why are textures blurry or thrashing? | `stat streaming`, texture accuracy/resolution views |
| Why do virtual textures show low-res tiles? | VT pool stats/visualization and feedback/upload demand |
| Why does entering a region hitch? | Asset Loading Insights, file/loadtime trace, World Partition evidence |
| Why does first rendering hitch? | PSO precache validation and Shader Pipeline Cache hitch stats |
| Why does geometry pop or stream forever? | Nanite stats/pool or World Partition readiness |
| Why did memory grow after repeated action? | marked Memory Insights allocation query |

Do not combine all streaming systems into one “pool.” Each has separate ownership, telemetry, eviction,
and quality behavior.

Texture streaming

# Texture streaming

## Diagnose before changing the pool

1. Build texture streaming data: Build dropdown -> Build Texture Streaming.
2. Use Primitive Distance, Mesh UV Density, Material Texture Scales, and Required Texture Resolution
   accuracy/view modes to find bad bounds, UV density, scale analysis, or insufficient residency.
3. Run `stat streaming` and record Texture, Streaming, Wanted, budget, over-budget, and update time.
4. Reproduce the target camera path and distinguish temporary cached mips from sustained demand.

## Controls

| CVar | Effect/tradeoff |
|---|---|
| `r.Streaming.PoolSize` | texture-pool MB; larger reduces pressure but consumes target memory |
| `r.Streaming.FramesForFullUpdate` | larger lowers streamer CPU work but reacts more slowly |
| `r.Streaming.MaxTempMemoryAllowed` | more staging may improve throughput but raises transient memory |
| `r.Streaming.MipBias` | larger bias reduces wanted resolution and quality |
| `r.Streaming.UsePerTextureBias` | applies bias selectively to fit the pool rather than degrading every wanted mip |
| `r.Streaming.LimitPoolSizeToVRAM` | caps pool against available GPU memory where supported |

`r.TextureStreaming 0`, `r.Streaming.PoolSize 0`, `r.Streaming.UseAllMips`, and
`r.Streaming.FullyLoadUsedTextures` are diagnostic/showcase controls, not default shipping fixes.

For a controlled wanted-resolution test, `r.Streaming.DropMips 2` removes cached/hidden mips so the
Required Texture Resolution view reflects visible demand; restore it before final measurement.

Fix stale material-instance streaming data, wrong mesh UV density, oversized bounds, forced residency,
incorrect texture groups, and excessive source resolution before buying a larger pool.

Streaming and runtime virtual texturing

# Streaming and runtime virtual texturing

Use Streaming Virtual Texturing (SVT) for large cooked textures/UDIMs when tile-level residency beats
whole-mip streaming. Use Runtime Virtual Texturing (RVT) for GPU-generated/cacheable surface data such
as landscape blending. Do not convert content solely because conventional texture streaming is poorly
configured.

## Physical pools

- Page-table memory grows on demand and generally remains until all related content is released.
- Each VT physical pool is a fixed-size LRU cache matched by format/tile configuration.
- Configure serialized pools under Project Settings -> Engine -> Virtual Texture Pool.
- Transient auto-grown pools exist only for the editor session; copy validated estimates into Fixed
  Pools for cooked builds.
- If visible tiles exceed a matching pool, continual eviction produces low-resolution/flickering tiles.

Use `stat virtualtexturing` for update/upload cost and page-table counters; use
`stat virtualtexturememory` for pool memory. Inspect each format/layer pool independently.

Larger pools reduce eviction but permanently reserve more GPU memory. Increasing upload limits/feedback
resolution can reduce latency while increasing CPU/GPU/upload work. Tune a repeatable traversal and test
camera cuts, fast motion, multiple views, and every device profile.

RVT low mips for large worlds may require far-away actors to remain resident. Bake/stream low mips when
that trades runtime generation and residency for acceptable disk/streaming cost.


unreal-metasounds

Unreal 5.8 MetaSounds

---
name: unreal-metasounds
description: Design, parameterize, vary, mix, optimize, and debug procedural audio in Unreal Engine 5.8. Use for MetaSound Sources, Patches, Presets, graph Inputs and Triggers, runtime Audio Component parameters, random variation, sample playback, procedural synthesis, music timing, Quartz, Audio Modulation, Control Buses, attenuation and spatialization, interfaces, concurrency, looping sounds, output watching, Builder API, or silent/clicking/expensive audio.
---

# Unreal 5.8 MetaSounds

## Select the audio layer first

Read [`references/system-selector.md`](references/system-selector.md).

- One playable procedural/parameterized sound -> MetaSound Source.
- Reusable graph behavior inside other MetaSounds -> Patch.
- Same graph with different default inputs -> Preset.
- Cross-category volume/filter/pitch control -> Audio Modulation/Control Buses.
- Sample-accurate musical scheduling -> Quartz plus MetaSound where needed.
- Fixed simple one-shot -> Sound Wave or simple source may be enough.

Keep gameplay authority outside the audio graph. MetaSound consumes events and parameters to render
feedback; it does not decide whether a hit, purchase, cooldown, or state transition is valid.

## Execute

1. Define the sound's informational job, duration, spatial context, variation, and mix priority.
2. Choose Source, Patch, Preset, or a simpler asset and define the public input/output interface.
3. Build a minimum audible signal path and correct one-shot or indefinite lifetime.
4. Add deterministic/random variation, envelopes, filters, synthesis, or layering in bounded stages.
5. Drive runtime changes through MetaSound Inputs/Triggers on the playing Audio Component.
6. Configure attenuation, spatialization, concurrency, sound class/submix, and modulation routing.
7. Test repeated triggering, virtualization/lifecycle, listener distance, and worst-case voice counts.
8. Profile audio/render-thread cost and the complete mix during representative gameplay.

Load only what applies:

- [`references/assets-and-graph-contract.md`](references/assets-and-graph-contract.md)
- [`references/runtime-parameters-and-events.md`](references/runtime-parameters-and-events.md)
- [`references/variation-and-recipes.md`](references/variation-and-recipes.md)
- [`references/spatialization-lifetime-and-concurrency.md`](references/spatialization-lifetime-and-concurrency.md)
- [`references/modulation-mixing-and-quartz.md`](references/modulation-mixing-and-quartz.md)
- [`references/presets-patches-and-interfaces.md`](references/presets-patches-and-interfaces.md)
- [`references/builder-api-and-output-watch.md`](references/builder-api-and-output-watch.md)
- [`references/debugging-and-performance.md`](references/debugging-and-performance.md)

## Required answer format

Return:

1. **Sound's gameplay/readability job** and chosen asset architecture.
2. **Input/output/trigger interface**, units, defaults, and ownership.
3. **Graph signal/control flow in evaluation order**.
4. **Variation rules and deterministic requirements**.
5. **Lifetime, concurrency, attenuation, spatialization, class/submix, and modulation settings**.
6. **Network/cosmetic, accessibility, and performance consequences**.
7. **Audition, debug, and mix acceptance checks**.

## Hard rules

- Only a MetaSound Source is directly playable; Patches encapsulate reusable graph behavior.
- Use Presets for inherited graphs with overridden default Inputs; do not duplicate the graph.
- Use Inputs for values that change during playback. MetaSound Variables are graph-internal, cannot
  be accessed from Blueprint, and do not register external playback-time changes.
- Set runtime parameters on the Audio Component before Play when the first audio block depends on them.
- Keep `UE.Source.OneShot` and its `On Finished` contract for finite sounds; remove it from indefinite sounds.
- Remove DC, avoid discontinuous waveform jumps, and bound gain before output.
- Define concurrency and cleanup for every repeatedly triggered or looping source.
- Use Audio Modulation for shared mix state; do not update every MetaSound instance each frame.
- Critical gameplay information must have a non-audio equivalent and survive mix/accessibility settings.
- Profile at realistic simultaneous voice counts; graph complexity alone is not the final cost.

See [`references/sources.md`](references/sources.md) for the UE 5.8 source trail.

## Select the audio layer first

Read [`references/system-selector.md`](/unreal/unreal-metasounds/system-selector/).

- One playable procedural/parameterized sound -> MetaSound Source.
- Reusable graph behavior inside other MetaSounds -> Patch.
- Same graph with different default inputs -> Preset.
- Cross-category volume/filter/pitch control -> Audio Modulation/Control Buses.
- Sample-accurate musical scheduling -> Quartz plus MetaSound where needed.
- Fixed simple one-shot -> Sound Wave or simple source may be enough.

Keep gameplay authority outside the audio graph. MetaSound consumes events and parameters to render
feedback; it does not decide whether a hit, purchase, cooldown, or state transition is valid.

## Execute

1. Define the sound's informational job, duration, spatial context, variation, and mix priority.
2. Choose Source, Patch, Preset, or a simpler asset and define the public input/output interface.
3. Build a minimum audible signal path and correct one-shot or indefinite lifetime.
4. Add deterministic/random variation, envelopes, filters, synthesis, or layering in bounded stages.
5. Drive runtime changes through MetaSound Inputs/Triggers on the playing Audio Component.
6. Configure attenuation, spatialization, concurrency, sound class/submix, and modulation routing.
7. Test repeated triggering, virtualization/lifecycle, listener distance, and worst-case voice counts.
8. Profile audio/render-thread cost and the complete mix during representative gameplay.

Load only what applies:

- [`references/assets-and-graph-contract.md`](/unreal/unreal-metasounds/assets-and-graph-contract/)
- [`references/runtime-parameters-and-events.md`](/unreal/unreal-metasounds/runtime-parameters-and-events/)
- [`references/variation-and-recipes.md`](/unreal/unreal-metasounds/variation-and-recipes/)
- [`references/spatialization-lifetime-and-concurrency.md`](/unreal/unreal-metasounds/spatialization-lifetime-and-concurrency/)
- [`references/modulation-mixing-and-quartz.md`](/unreal/unreal-metasounds/modulation-mixing-and-quartz/)
- [`references/presets-patches-and-interfaces.md`](/unreal/unreal-metasounds/presets-patches-and-interfaces/)
- [`references/builder-api-and-output-watch.md`](/unreal/unreal-metasounds/builder-api-and-output-watch/)
- [`references/debugging-and-performance.md`](/unreal/unreal-metasounds/debugging-and-performance/)

## Required answer format

Return:

1. **Sound's gameplay/readability job** and chosen asset architecture.
2. **Input/output/trigger interface**, units, defaults, and ownership.
3. **Graph signal/control flow in evaluation order**.
4. **Variation rules and deterministic requirements**.
5. **Lifetime, concurrency, attenuation, spatialization, class/submix, and modulation settings**.
6. **Network/cosmetic, accessibility, and performance consequences**.
7. **Audition, debug, and mix acceptance checks**.

## Hard rules

- Only a MetaSound Source is directly playable; Patches encapsulate reusable graph behavior.
- Use Presets for inherited graphs with overridden default Inputs; do not duplicate the graph.
- Use Inputs for values that change during playback. MetaSound Variables are graph-internal, cannot
  be accessed from Blueprint, and do not register external playback-time changes.
- Set runtime parameters on the Audio Component before Play when the first audio block depends on them.
- Keep `UE.Source.OneShot` and its `On Finished` contract for finite sounds; remove it from indefinite sounds.
- Remove DC, avoid discontinuous waveform jumps, and bound gain before output.
- Define concurrency and cleanup for every repeatedly triggered or looping source.
- Use Audio Modulation for shared mix state; do not update every MetaSound instance each frame.
- Critical gameplay information must have a non-audio equivalent and survive mix/accessibility settings.
- Profile at realistic simultaneous voice counts; graph complexity alone is not the final cost.

See [`references/sources.md`](/unreal/unreal-metasounds/sources/) for the UE 5.8 source trail.

unreal 5.8 metasounds design, parameterize, vary, mix, optimize, and debug procedural audio in unreal engine 5.8. use for metasound sources, patches, presets, graph inputs and triggers, runtime audio component parameters, random variation, sample playback, procedural synthesis, music timing, quartz, audio modulation, control buses, attenuation and spatialization, interfaces, concurrency, looping sounds, output watching, builder api, or silent/clicking/expensive audio. assets and graph contract assets and graph contract create a source via content browser -> add -> audio -> metasound source and a patch via audio -> metasounds -> metasound patch. a source produces playable audio; a patch must be embedded in a source or another metasound. minimum source 1. choose mono/stereo/output format deliberately. 2. route wave player or synthesis output through gain/envelope/filter stages to audio output. 3. expose semantic inputs and triggers in the members panel. 4. for a finite sound, keep ue.source.oneshot and connect the terminal trigger to on finished. 5. for an indefinite loop/sustain, remove the one-shot interface and define external stop/fade cleanup. 6. audition with extreme public-input values before composing into gameplay. metasound is a flow graph, not a blueprint execution graph. audio-rate signals, block/control-rate values, and triggers have different timing semantics. keep pin types/units explicit. public contract name inputs by meaning and unit: impactstrength01, speedcmpersec, surfacetype, release, pitchsemitones. clamp/map raw gameplay values once at the boundary. provide defaults that render a safe, audible result if the caller omits an optional input. do not expose implementation knobs merely because nodes have pins. public inputs should represent stable design controls; internal constants and variables remain graph details. builder api and output watching builder api and output watching builder api use the metasound builder subsystem for runtime/editor creation and mutation of transient sources or patches. use the metasound editor subsystem for editor-only asset creation/serialization workflows. prefer authored assets unless dynamic graph topology is a real requirement. builder handles identify graph nodes/pins but may change when documents rebuild/version. never serialize them as durable identity. define ownership of transient builders, audition/live-update state, dependency loading, and teardown. validate generated graphs before playback/export. output watching watch output can observe supported source outputs—float, int32, bool, time, string, and trigger—while the source is playing. patch outputs cannot be watched directly. the delegate can fire for every output update, including multiple updates within a frame. use watched outputs for presentation/analysis callbacks, not audio-thread authority over gameplay. throttle or aggregate high-rate outputs before expensive game-thread work. for envelope data, watch the audio output with epic's envelope follower analyzer identifiers. failure gates: - no callback -> source not playing, wrong exact output/analyzer name, unsupported type, or patch; - excessive callbacks -> output updates multiple times per frame; - stale builder handle -> graph rebuilt/versioned; - live changes absent -> not auditioning with supported live updates or wrong builder instance. debugging and performance debugging and performance symptom matrix | symptom | inspect first | |---|---| | silent | source playing, audio output route, gain/envelope, one-shot finish timing | | stops immediately | on finished triggered early or one-shot interface on indefinite graph | | never stops | missing finish/release or owner cleanup | | runtime value ignored | using variable instead of input, wrong name/type/component, constructor pin | | click/pop | waveform/gain discontinuity, no release, abrupt stop, dc | | repeats audibly | random pool/history/seed and concurrency stealing | | wrong distance/direction | attenuation/spatialization asset/interface and listener | | mix parameter ignored | modulation routing/activation/proxy update | | hitches on first play | asset/stream/decode/graph readiness and packaged behavior | | audio overload | voice count, per-source graph/dsp, sample rate, effects/submix cost | isolation ladder 1. audition one source with constant values and a minimal signal path. 2. watch meters/output and verify envelope/lifetime. 3. add graph stages one at a time. 4. test through the exact gameplay audio component and parameter order. 5. add attenuation, concurrency, modulation, class, and submix routing individually. 6. reproduce maximum simultaneous voices and full mix on target hardware. 7. use audio diagnostics/insights and mix matrix debugger where applicable. measure audio-render thread, source/voice count, underruns, streaming/decode, effects/submixes, and game-thread parameter traffic. reduce voice count and redundant graph work before degrading the cue that carries critical information. audio modulation, mixing, and quartz audio modulation, mixing, and quartz audio modulation enable the audio modulation plugin when shared dynamic mix control is needed. build: 1. modulation parameters with defined unit/normalized mapping. 2. control buses for categories such as master, music, sfx, dialogue, ambience, or accessibility. 3. control bus mixes for gameplay/menu/state profiles. 4. modulation destinations on metasound sources, sound classes, components, submixes, or effects. 5. blueprint/c++ activation/update/clear ownership and debugging. routing can disable, inherit, override, or union at supported destinations. sound class hierarchy is not automatically equivalent to modulation routing; assign required buses deliberately. when an api edits only the uobject representation, use the appropriate update call to push it to the audio-thread proxy. use metasound get modulator value/mix modulators when the graph must react to a bus. modulation is block-rate, not sample-rate. use graph/audio-rate signals for true audio-rate modulation. mix hierarchy protect critical cues through class/submix routing, concurrency priority, headroom, ducking, and state mixes. test the whole combat/ambience/music/dialogue mix, not soloed assets. provide category volume controls and non-audio equivalents for critical signals. quartz use quartz clocks for beat/bar/subdivision-aligned scheduling. keep transport/clock ownership stable, schedule sufficiently ahead for the audio renderer, and define pause, tempo change, world transition, and late-event behavior. metasound produces/varies sound; quartz owns musical-time scheduling. presets, patches, and interfaces presets, patches, and interfaces patch extract a patch when the same bounded dsp/control behavior is reused: randomized wave choice, envelope mapping, surface selection, filter chain, or musical utility. document every pin, unit, default, and timing assumption. changes propagate to containing graphs; test representative callers. preset right-click a source/patch -> create metasound preset. a preset inherits a read-only graph and overrides selected default inputs. parent changes propagate. use presets for variants sharing the same behavior contract; convert from preset only when the graph must diverge. constructor-pin status cannot be overridden on presets. interfaces interfaces supply standardized inputs/outputs connecting metasounds to audio-engine systems: - ue.source.oneshot: on finished for finite source lifetime. - ue.attenuation: listener distance input. - ue.spatialization: azimuth/elevation inputs. add/remove interfaces in the metasound interfaces panel. do not retain oneshot on indefinite sources. treat interface changes like an api migration because dependent graphs/callers may rely on members. use templates only when repeated asset construction and curated designer controls justify the extra framework. for a small graph, a normal source/patch/preset is clearer. runtime parameters and events runtime parameters and events spawned/owned audio component 1. create or spawn an audio component with the metasound source assigned. 2. set all first-block-critical parameters before calling play. 3. send later values through matching audio component parameter setters. 4. send trigger inputs for discrete audio events such as release, reroll, or next layer. 5. retain component ownership when later updates/stops are required. 6. stop/fade and release the component on owner destruction, state exit, or cancellation. parameter names and types must exactly match graph inputs. if a value appears ignored, confirm the component is the playing instance, the input is not a constructor-only pin, and a later graph node is not overwriting/masking it. variables are not runtime api metasound variables support internal get/set flow. they cannot be accessed by blueprint, and changing them externally while a sound plays is not the live-control path. use inputs for caller-driven state. use get delayed variable only when a one-block delay is intentional, commonly to break a graph cycle. network boundary replicate the compact gameplay event/state when other machines need to hear it, then create/update local audio components. do not replicate dsp samples or every modulation value. define whether a one-shot may be dropped, whether a loop must reconstruct for late relevance, and whether predicted audio must be cancelled or deduplicated after server response. ue 5.8 primary sources ue 5.8 primary sources - metasounds overview - metasounds reference guide - metasound plugin api - metasound builder api - metasound pages - metasound templates quick start - audio modulation overview - audio modulation quick start - audio modulation reference - quartz overview - quartz quick start pages were checked against the ue 5.8 documentation on 2026-07-19. reconfirm interfaces, builder api, template behavior, parameter timing, and modulation routing after an engine upgrade. spatialization, lifetime, and concurrency spatialization, lifetime, and concurrency metasound generates a source; standard unreal audio systems still own attenuation, spatialization, occlusion, classes, submixes, concurrency, priority, and virtualization. spatial contract - use attenuation assets/settings for distance curves, shape, spatialization, air absorption, occlusion, and focus according to the game. - add ue.attenuation when graph behavior needs listener distance. - add ue.spatialization when graph behavior needs azimuth/elevation. - test listener motion, split screen if supported, occlusion transitions, and teleport/discontinuity. do not synthesize manual left/right panning as a substitute for the engine spatializer when true 3d audio is required. lifetime - finite source: terminal trigger -> on finished; component auto-destroy/pool policy verified. - indefinite source: no one-shot interface; external owner controls release/stop. - looping wave player: graph/source must still define when the overall sound ends. - virtualized source: define whether time advances silently or restarts when audible. concurrency group semantically interchangeable voices and choose maximum count/resolution rule by information priority. test bursts, nearby identical sources, quiet-loop accumulation, and modulation interaction. concurrency voice stealing is a mix/design decision: never allow a low-value decorative sound to steal a critical warning merely because it started later. system selector system selector | need | prefer | verify | |---|---|---| | playable generated/processed source | metasound source | output format, lifetime, concurrency | | reused dsp/control subgraph | metasound patch | documented pins and propagation risk | | variants of one graph | metasound preset | inherited defaults, constructor pins | | simple fixed sample | sound wave/simple playback | no procedural complexity required | | category/world mix state | audio modulation + control buses | routing, activation, unit conversion | | beat/bar scheduling | quartz | clock ownership, latency, quantization | | dynamic graph construction | builder api | lifecycle, handles, asset/runtime boundary | decision questions: 1. does the sound need runtime variation or parameter response? 2. is change per play, during playback, per category, or global? 3. must events be sample-accurate or merely frame-aligned? 4. is the source finite, looping, sustained, or procedurally terminated? 5. how many voices can coexist and which may be stolen/virtualized? use the simplest layer that owns the requirement. metasound handles per-source generation; audio modulation handles shared mix control; gameplay provides semantic events/state. variation and recipes variation and recipes impact/weapon one-shot input surface/material category, normalized magnitude, and optional seed. select from a curated wave array, avoid immediate repetition, map magnitude to bounded gain/pitch/filter/transient layers, apply a short envelope, then finish explicitly. keep hit validation in gameplay. footsteps select material-aware sample sets, randomize within narrow authored bounds, and optionally scale by speed/weight. concurrency should prevent impossible stacking. treat footsteps as feedback: preserve distinguishability from ambience and pair critical enemy cues with visual/accessibility alternatives. engine/machine loop maintain an owned indefinite source. map normalized rpm/load to crossfade, pitch, filtering, and layers; smooth control changes. separate start, sustain, and stop/release behavior. stop/fade on owner shutdown and test virtualization/re-entry. adaptive ambience use independent bounded layers with randomized intervals and controlled density. drive broad state via modulation or infrequent parameters rather than per-frame updates to every voice. preserve silence and headroom; random does not mean unbounded simultaneous playback. procedural tone/ui oscillator -> envelope -> filter/gain -> output. start/end at zero amplitude and avoid instantaneous frequency/gain jumps to prevent clicks. limit spectrum and loudness across headphones/speakers. for deterministic replays or synchronized musical structure, own and pass a seed/clock deliberately. for ordinary cosmetic variation, exact cross-client random identity is usually unnecessary.

Assets and graph contract

# Assets and graph contract

Create a Source via Content Browser -> Add -> Audio -> MetaSound Source and a Patch via Audio ->
MetaSounds -> MetaSound Patch. A Source produces playable audio; a Patch must be embedded in a Source
or another MetaSound.

## Minimum Source

1. Choose mono/stereo/output format deliberately.
2. Route Wave Player or synthesis output through gain/envelope/filter stages to Audio Output.
3. Expose semantic Inputs and Triggers in the Members panel.
4. For a finite sound, keep `UE.Source.OneShot` and connect the terminal trigger to `On Finished`.
5. For an indefinite loop/sustain, remove the one-shot interface and define external stop/fade cleanup.
6. Audition with extreme public-input values before composing into gameplay.

MetaSound is a flow graph, not a Blueprint execution graph. Audio-rate signals, block/control-rate
values, and Triggers have different timing semantics. Keep pin types/units explicit.

## Public contract

Name Inputs by meaning and unit: `ImpactStrength01`, `SpeedCmPerSec`, `SurfaceType`, `Release`,
`PitchSemitones`. Clamp/map raw gameplay values once at the boundary. Provide defaults that render a
safe, audible result if the caller omits an optional input.

Do not expose implementation knobs merely because nodes have pins. Public inputs should represent
stable design controls; internal constants and Variables remain graph details.

Builder API and output watching

# Builder API and output watching

## Builder API

Use the MetaSound Builder Subsystem for runtime/editor creation and mutation of transient Sources or
Patches. Use the MetaSound Editor Subsystem for editor-only asset creation/serialization workflows.
Prefer authored assets unless dynamic graph topology is a real requirement.

Builder handles identify graph nodes/pins but may change when documents rebuild/version. Never
serialize them as durable identity. Define ownership of transient builders, audition/live-update
state, dependency loading, and teardown. Validate generated graphs before playback/export.

## Output watching

`Watch Output` can observe supported Source Outputs—Float, Int32, Bool, Time, String, and Trigger—while
the Source is playing. Patch Outputs cannot be watched directly. The delegate can fire for every
output update, including multiple updates within a frame.

Use watched outputs for presentation/analysis callbacks, not audio-thread authority over gameplay.
Throttle or aggregate high-rate outputs before expensive game-thread work. For envelope data, watch
the Audio Output with Epic's Envelope Follower analyzer identifiers.

Failure gates:

- no callback -> Source not playing, wrong exact output/analyzer name, unsupported type, or Patch;
- excessive callbacks -> output updates multiple times per frame;
- stale builder handle -> graph rebuilt/versioned;
- live changes absent -> not auditioning with supported Live Updates or wrong builder instance.

Debugging and performance

# Debugging and performance

## Symptom matrix

| Symptom | Inspect first |
|---|---|
| Silent | source playing, audio output route, gain/envelope, one-shot finish timing |
| Stops immediately | `On Finished` triggered early or one-shot interface on indefinite graph |
| Never stops | missing finish/release or owner cleanup |
| Runtime value ignored | using Variable instead of Input, wrong name/type/component, constructor pin |
| Click/pop | waveform/gain discontinuity, no release, abrupt stop, DC |
| Repeats audibly | random pool/history/seed and concurrency stealing |
| Wrong distance/direction | attenuation/spatialization asset/interface and listener |
| Mix parameter ignored | modulation routing/activation/proxy update |
| Hitches on first play | asset/stream/decode/graph readiness and packaged behavior |
| Audio overload | voice count, per-source graph/DSP, sample rate, effects/submix cost |

## Isolation ladder

1. Audition one Source with constant values and a minimal signal path.
2. Watch meters/output and verify envelope/lifetime.
3. Add graph stages one at a time.
4. Test through the exact gameplay Audio Component and parameter order.
5. Add attenuation, concurrency, modulation, class, and submix routing individually.
6. Reproduce maximum simultaneous voices and full mix on target hardware.
7. Use audio diagnostics/Insights and Mix Matrix Debugger where applicable.

Measure audio-render thread, source/voice count, underruns, streaming/decode, effects/submixes, and
game-thread parameter traffic. Reduce voice count and redundant graph work before degrading the cue
that carries critical information.

Audio Modulation, mixing, and Quartz

# Audio Modulation, mixing, and Quartz

## Audio Modulation

Enable the Audio Modulation plugin when shared dynamic mix control is needed. Build:

1. Modulation Parameters with defined unit/normalized mapping.
2. Control Buses for categories such as master, music, SFX, dialogue, ambience, or accessibility.
3. Control Bus Mixes for gameplay/menu/state profiles.
4. Modulation Destinations on MetaSound Sources, Sound Classes, Components, Submixes, or effects.
5. Blueprint/C++ activation/update/clear ownership and debugging.

Routing can Disable, Inherit, Override, or Union at supported destinations. Sound Class hierarchy is
not automatically equivalent to modulation routing; assign required buses deliberately. When an API
edits only the UObject representation, use the appropriate Update call to push it to the audio-thread
proxy.

Use MetaSound `Get Modulator Value`/`Mix Modulators` when the graph must react to a bus. Modulation is
block-rate, not sample-rate. Use graph/audio-rate signals for true audio-rate modulation.

## Mix hierarchy

Protect critical cues through class/submix routing, concurrency priority, headroom, ducking, and
state mixes. Test the whole combat/ambience/music/dialogue mix, not soloed assets. Provide category
volume controls and non-audio equivalents for critical signals.

## Quartz

Use Quartz clocks for beat/bar/subdivision-aligned scheduling. Keep transport/clock ownership stable,
schedule sufficiently ahead for the audio renderer, and define pause, tempo change, world transition,
and late-event behavior. MetaSound produces/varies sound; Quartz owns musical-time scheduling.

Presets, Patches, and interfaces

# Presets, Patches, and interfaces

## Patch

Extract a Patch when the same bounded DSP/control behavior is reused: randomized wave choice,
envelope mapping, surface selection, filter chain, or musical utility. Document every pin, unit,
default, and timing assumption. Changes propagate to containing graphs; test representative callers.

## Preset

Right-click a Source/Patch -> Create MetaSound Preset. A Preset inherits a read-only graph and
overrides selected default Inputs. Parent changes propagate. Use Presets for variants sharing the
same behavior contract; convert from Preset only when the graph must diverge. Constructor-pin status
cannot be overridden on Presets.

## Interfaces

Interfaces supply standardized Inputs/Outputs connecting MetaSounds to audio-engine systems:

- `UE.Source.OneShot`: `On Finished` for finite source lifetime.
- `UE.Attenuation`: listener distance input.
- `UE.Spatialization`: azimuth/elevation inputs.

Add/remove interfaces in the MetaSound Interfaces panel. Do not retain OneShot on indefinite sources.
Treat interface changes like an API migration because dependent graphs/callers may rely on members.

Use templates only when repeated asset construction and curated designer controls justify the extra
framework. For a small graph, a normal Source/Patch/Preset is clearer.

Runtime parameters and events

# Runtime parameters and events

## Spawned/owned Audio Component

1. Create or spawn an Audio Component with the MetaSound Source assigned.
2. Set all first-block-critical parameters before calling Play.
3. Send later values through matching Audio Component parameter setters.
4. Send Trigger inputs for discrete audio events such as release, reroll, or next layer.
5. Retain component ownership when later updates/stops are required.
6. Stop/fade and release the component on owner destruction, state exit, or cancellation.

Parameter names and types must exactly match graph Inputs. If a value appears ignored, confirm the
component is the playing instance, the input is not a constructor-only pin, and a later graph node is
not overwriting/masking it.

## Variables are not runtime API

MetaSound Variables support internal Get/Set flow. They cannot be accessed by Blueprint, and changing
them externally while a sound plays is not the live-control path. Use Inputs for caller-driven state.
Use Get Delayed Variable only when a one-block delay is intentional, commonly to break a graph cycle.

## Network boundary

Replicate the compact gameplay event/state when other machines need to hear it, then create/update
local Audio Components. Do not replicate DSP samples or every modulation value. Define whether a
one-shot may be dropped, whether a loop must reconstruct for late relevance, and whether predicted
audio must be cancelled or deduplicated after server response.

UE 5.8 primary sources

# UE 5.8 primary sources

- [MetaSounds Overview](https://dev.epicgames.com/documentation/en-us/unreal-engine/metasounds-the-next-generation-sound-sources-in-unreal-engine)
- [MetaSounds Reference Guide](https://dev.epicgames.com/documentation/en-us/unreal-engine/metasounds-reference-guide-in-unreal-engine)
- [MetaSound Plugin API](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/PluginIndex/Metasound)
- [MetaSound Builder API](https://dev.epicgames.com/documentation/en-us/unreal-engine/metasound-builder-api-in-unreal-engine)
- [MetaSound Pages](https://dev.epicgames.com/documentation/en-us/unreal-engine/metasound-pages-in-unreal-engine)
- [MetaSound Templates Quick Start](https://dev.epicgames.com/documentation/en-us/unreal-engine/metasound-templates-quick-start-in-unreal-engine)
- [Audio Modulation Overview](https://dev.epicgames.com/documentation/en-us/unreal-engine/audio-modulation-overview-in-unreal-engine)
- [Audio Modulation Quick Start](https://dev.epicgames.com/documentation/en-us/unreal-engine/audio-modulation-quick-start-guide)
- [Audio Modulation Reference](https://dev.epicgames.com/documentation/en-us/unreal-engine/audio-modulation-reference-guide-in-unreal-engine)
- [Quartz Overview](https://dev.epicgames.com/documentation/en-us/unreal-engine/overview-of-quartz-in-unreal-engine)
- [Quartz Quick Start](https://dev.epicgames.com/documentation/en-us/unreal-engine/quartz-quick-start)

Pages were checked against the UE 5.8 documentation on 2026-07-19. Reconfirm interfaces, Builder
API, template behavior, parameter timing, and modulation routing after an engine upgrade.

# Spatialization, lifetime, and concurrency

MetaSound generates a source; standard Unreal audio systems still own attenuation, spatialization,
occlusion, classes, submixes, concurrency, priority, and virtualization.

## Spatial contract

- Use attenuation assets/settings for distance curves, shape, spatialization, air absorption,
  occlusion, and focus according to the game.
- Add `UE.Attenuation` when graph behavior needs listener distance.
- Add `UE.Spatialization` when graph behavior needs azimuth/elevation.
- Test listener motion, split screen if supported, occlusion transitions, and teleport/discontinuity.

Do not synthesize manual left/right panning as a substitute for the engine spatializer when true 3D
audio is required.

## Lifetime

- Finite Source: terminal trigger -> `On Finished`; component auto-destroy/pool policy verified.
- Indefinite Source: no one-shot interface; external owner controls release/stop.
- Looping Wave Player: graph/source must still define when the overall sound ends.
- Virtualized source: define whether time advances silently or restarts when audible.

## Concurrency

Group semantically interchangeable voices and choose maximum count/resolution rule by information
priority. Test bursts, nearby identical sources, quiet-loop accumulation, and modulation interaction.
Concurrency voice stealing is a mix/design decision: never allow a low-value decorative sound to
steal a critical warning merely because it started later.

System selector

# System selector

| Need | Prefer | Verify |
|---|---|---|
| Playable generated/processed source | MetaSound Source | output format, lifetime, concurrency |
| Reused DSP/control subgraph | MetaSound Patch | documented pins and propagation risk |
| Variants of one graph | MetaSound Preset | inherited defaults, constructor pins |
| Simple fixed sample | Sound Wave/simple playback | no procedural complexity required |
| Category/world mix state | Audio Modulation + Control Buses | routing, activation, unit conversion |
| Beat/bar scheduling | Quartz | clock ownership, latency, quantization |
| Dynamic graph construction | Builder API | lifecycle, handles, asset/runtime boundary |

Decision questions:

1. Does the sound need runtime variation or parameter response?
2. Is change per play, during playback, per category, or global?
3. Must events be sample-accurate or merely frame-aligned?
4. Is the source finite, looping, sustained, or procedurally terminated?
5. How many voices can coexist and which may be stolen/virtualized?

Use the simplest layer that owns the requirement. MetaSound handles per-source generation; Audio
Modulation handles shared mix control; gameplay provides semantic events/state.

Variation and recipes

# Variation and recipes

## Impact/weapon one-shot

Input surface/material category, normalized magnitude, and optional seed. Select from a curated wave
array, avoid immediate repetition, map magnitude to bounded gain/pitch/filter/transient layers, apply a
short envelope, then finish explicitly. Keep hit validation in gameplay.

## Footsteps

Select material-aware sample sets, randomize within narrow authored bounds, and optionally scale by
speed/weight. Concurrency should prevent impossible stacking. Treat footsteps as feedback: preserve
distinguishability from ambience and pair critical enemy cues with visual/accessibility alternatives.

## Engine/machine loop

Maintain an owned indefinite Source. Map normalized RPM/load to crossfade, pitch, filtering, and
layers; smooth control changes. Separate start, sustain, and stop/release behavior. Stop/fade on owner
shutdown and test virtualization/re-entry.

## Adaptive ambience

Use independent bounded layers with randomized intervals and controlled density. Drive broad state via
Modulation or infrequent parameters rather than per-frame updates to every voice. Preserve silence and
headroom; random does not mean unbounded simultaneous playback.

## Procedural tone/UI

Oscillator -> envelope -> filter/gain -> output. Start/end at zero amplitude and avoid instantaneous
frequency/gain jumps to prevent clicks. Limit spectrum and loudness across headphones/speakers.

For deterministic replays or synchronized musical structure, own and pass a seed/clock deliberately.
For ordinary cosmetic variation, exact cross-client random identity is usually unnecessary.