unreal-umg-commonui

Unreal 5.8 UMG and CommonUI

Build scalable responsive game UI systems

---
name: unreal-umg-commonui
description: Design, implement, optimize, and debug game UI in Unreal Engine 5.8 with UMG and CommonUI. Use for widget architecture, HUDs, menus, modal layers, Common Activatable Widgets, input routing, Enhanced Input integration, focus, gamepad navigation, local-player ownership, split screen, responsive layout, DPI scaling, safe zones, accessibility, MVVM, event-driven updates, ListView virtualization, invalidation, pooling, or UI performance.
---

# Unreal 5.8 UMG and CommonUI

## Ownership boundary

This skill owns widget lifecycle, screen layers, focus, navigation, and UI input routing. Route action,
context, trigger, modifier, and key-profile semantics to
[`unreal-enhanced-input`](../unreal-enhanced-input/SKILL.md), authoritative multiplayer state to
[`unreal-replication`](../unreal-replication/SKILL.md), and durable slot/schema/migration policy to
[`unreal-save-load`](../unreal-save-load/SKILL.md).

## Select the UI stack

- Use **UMG** for every game UI; it is the base authoring layer.
- Add **CommonUI** when the product needs complex layered screens, robust gamepad navigation,
  cross-platform input prompts, or consistent back/input routing.
- Do not add CommonUI solely for a small mouse-driven HUD or a single simple menu.
- Treat **UMG Viewmodel/MVVM as Beta in UE 5.8**. Use it when push binding and UI/backend
  separation justify the maturity risk; otherwise use explicit delegates and setters.
- In UE 5.8 prefer the unified CommonUI + Enhanced Input workflow. Do not copy older tutorials
  that require a parallel UI action-data-table vocabulary unless maintaining legacy content.

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

## Preserve the presentation boundary

1. Keep authoritative gameplay state in gameplay systems, never in widgets.
2. Expose a small local presentation model or Viewmodel per local player.
3. Push changes into the UI with delegates, events, or FieldNotify.
4. Let widgets submit semantic intent; let gameplay code validate and execute it.
5. Replicate model state, not widget instances. Create and update UI locally.

Read [`references/architecture-lifecycle.md`](references/architecture-lifecycle.md) and route
network-state design to `$unreal-replication`.

## Build in dependency order

1. Identify local-player ownership, screen layers, and the authority boundary.
2. Establish one root layout and named HUD, menu, modal, and notification layers.
3. Make screens activatable only when they own an input/focus boundary.
4. Define activation, back, input mode, mouse capture, and desired-focus behavior.
5. Build layouts with anchors, containers, DPI scaling, and Safe Zones.
6. Push state changes; avoid Tick and raw property bindings.
7. Virtualize long collections and load expensive, infrequent screens on demand.
8. Test keyboard/mouse, gamepad, touch if supported, split screen, resolutions, safe zones,
   localization expansion, and accessibility settings.
9. Profile with Slate Insights/Unreal Insights before applying invalidation or retainers.

Use [`references/commonui-routing.md`](references/commonui-routing.md),
[`references/input-focus.md`](references/input-focus.md), and
[`references/responsive-accessibility.md`](references/responsive-accessibility.md).

## Required answer format

Return:

1. **Stack choice**: UMG only, UMG + CommonUI, and whether Beta MVVM is justified.
2. **Ownership diagram**: authoritative model, local presentation model, view, and intent path.
3. **Layer/input/focus policy** for every screen type.
4. **Exact implementation actions**: assets, classes, settings, nodes/APIs, and lifecycle hooks.
5. **Responsive and accessibility matrix**.
6. **Performance risks, measurement method, and verification checklist**.

Do not invent property names, plugin maturity, focus behavior, or performance wins.

## Hard rules

- Never store authoritative gameplay state only in a widget.
- Never replicate widgets or use a widget as a client-to-server RPC owner.
- Use an owning `LocalPlayer`/`PlayerController`; prefer `AddToPlayerScreen` for player UI.
- Do not assume `Construct` runs once; use initialization and activation hooks intentionally.
- Do not make every CommonUI widget activatable.
- Every gamepad screen must define a valid initial focus target and a back path.
- Never encode critical information by color alone; support readable text scaling.
- Avoid raw property binding, widget Tick, and nested Canvas Panels in production UI.
- Do not add Invalidation Boxes or Retainer Panels without profiling and change-frequency analysis.

Read [`references/binding-mvvm.md`](references/binding-mvvm.md),
[`references/performance.md`](references/performance.md), and
[`references/patterns-troubleshooting.md`](references/patterns-troubleshooting.md). See
[`references/sources.md`](references/sources.md) for the UE 5.8 source trail.

## Ownership boundary

This skill owns widget lifecycle, screen layers, focus, navigation, and UI input routing. Route action,
context, trigger, modifier, and key-profile semantics to
[`unreal-enhanced-input`](/unreal/unreal-enhanced-input/), authoritative multiplayer state to
[`unreal-replication`](/unreal/unreal-replication/), and durable slot/schema/migration policy to
[`unreal-save-load`](/unreal/unreal-save-load/).

## Select the UI stack

- Use **UMG** for every game UI; it is the base authoring layer.
- Add **CommonUI** when the product needs complex layered screens, robust gamepad navigation,
  cross-platform input prompts, or consistent back/input routing.
- Do not add CommonUI solely for a small mouse-driven HUD or a single simple menu.
- Treat **UMG Viewmodel/MVVM as Beta in UE 5.8**. Use it when push binding and UI/backend
  separation justify the maturity risk; otherwise use explicit delegates and setters.
- In UE 5.8 prefer the unified CommonUI + Enhanced Input workflow. Do not copy older tutorials
  that require a parallel UI action-data-table vocabulary unless maintaining legacy content.

Read [`references/system-selector.md`](/unreal/unreal-umg-commonui/system-selector/) before choosing.

## Preserve the presentation boundary

1. Keep authoritative gameplay state in gameplay systems, never in widgets.
2. Expose a small local presentation model or Viewmodel per local player.
3. Push changes into the UI with delegates, events, or FieldNotify.
4. Let widgets submit semantic intent; let gameplay code validate and execute it.
5. Replicate model state, not widget instances. Create and update UI locally.

Read [`references/architecture-lifecycle.md`](/unreal/unreal-umg-commonui/architecture-lifecycle/) and route
network-state design to `$unreal-replication`.

## Build in dependency order

1. Identify local-player ownership, screen layers, and the authority boundary.
2. Establish one root layout and named HUD, menu, modal, and notification layers.
3. Make screens activatable only when they own an input/focus boundary.
4. Define activation, back, input mode, mouse capture, and desired-focus behavior.
5. Build layouts with anchors, containers, DPI scaling, and Safe Zones.
6. Push state changes; avoid Tick and raw property bindings.
7. Virtualize long collections and load expensive, infrequent screens on demand.
8. Test keyboard/mouse, gamepad, touch if supported, split screen, resolutions, safe zones,
   localization expansion, and accessibility settings.
9. Profile with Slate Insights/Unreal Insights before applying invalidation or retainers.

Use [`references/commonui-routing.md`](/unreal/unreal-umg-commonui/commonui-routing/),
[`references/input-focus.md`](/unreal/unreal-umg-commonui/input-focus/), and
[`references/responsive-accessibility.md`](/unreal/unreal-umg-commonui/responsive-accessibility/).

## Required answer format

Return:

1. **Stack choice**: UMG only, UMG + CommonUI, and whether Beta MVVM is justified.
2. **Ownership diagram**: authoritative model, local presentation model, view, and intent path.
3. **Layer/input/focus policy** for every screen type.
4. **Exact implementation actions**: assets, classes, settings, nodes/APIs, and lifecycle hooks.
5. **Responsive and accessibility matrix**.
6. **Performance risks, measurement method, and verification checklist**.

Do not invent property names, plugin maturity, focus behavior, or performance wins.

## Hard rules

- Never store authoritative gameplay state only in a widget.
- Never replicate widgets or use a widget as a client-to-server RPC owner.
- Use an owning `LocalPlayer`/`PlayerController`; prefer `AddToPlayerScreen` for player UI.
- Do not assume `Construct` runs once; use initialization and activation hooks intentionally.
- Do not make every CommonUI widget activatable.
- Every gamepad screen must define a valid initial focus target and a back path.
- Never encode critical information by color alone; support readable text scaling.
- Avoid raw property binding, widget Tick, and nested Canvas Panels in production UI.
- Do not add Invalidation Boxes or Retainer Panels without profiling and change-frequency analysis.

Read [`references/binding-mvvm.md`](/unreal/unreal-umg-commonui/binding-mvvm/),
[`references/performance.md`](/unreal/unreal-umg-commonui/performance/), and
[`references/patterns-troubleshooting.md`](/unreal/unreal-umg-commonui/patterns-troubleshooting/). See
[`references/sources.md`](/unreal/unreal-umg-commonui/sources/) for the UE 5.8 source trail.

unreal 5.8 umg and commonui design, implement, optimize, and debug game ui in unreal engine 5.8 with umg and commonui. use for widget architecture, huds, menus, modal layers, common activatable widgets, input routing, enhanced input integration, focus, gamepad navigation, local-player ownership, split screen, responsive layout, dpi scaling, safe zones, accessibility, mvvm, event-driven updates, listview virtualization, invalidation, pooling, or ui performance. architecture and lifecycle architecture and lifecycle ownership chain use this default chain: text server-authoritative gameplay state -> replicated actor/component/property -> local player presentation model or viewmodel -> local widget tree widget interaction -> semantic local intent -> owning playercontroller/pawn/component -> validated gameplay call or server rpc widgets are local presentation objects. they must not own canonical inventory, health, match, or save state. ui may predict presentation, but authoritative correction comes from gameplay. local-player ownership - create player ui with an owning playercontroller/localplayer. - prefer addtoplayerscreen for player-specific full-screen ui; it targets the player's viewport section. use addtoviewport only when the ui is intentionally viewport-global. - in split screen, keep one root layout/presentation model per local player. - set the owning player on world-space widget components when per-player display matters. - never fetch player zero as a substitute for correct ownership. widget lifecycle - oninitialized/nativeoninitialized: one-time instance initialization. - construct/nativeconstruct: slate construction; it may run multiple times when the widget leaves and re-enters the hierarchy. - destruct/nativedestruct: release hierarchy-time subscriptions/resources, while allowing that the uobject can still exist. - nativeonactivated/nativeondeactivated: common activatable widget screen-active lifetime. bind and unbind symmetrically. guard against duplicate delegate registration if construction or activation can repeat. keep activation-time subscriptions scoped to activation. state placement | state | owner | |---|---| | health, inventory, score, match phase | replicated gameplay model | | display-formatted health, selected tab, sorted rows | local presentation model/viewmodel | | hover, focus, animation progress | widget | | input mapping/profile | local player input subsystem/user settings | | screen stack and modal state | local root ui/commonui layer manager | failure checks - ui works for client 1 but not client 2: inspect owning local player and player-zero lookups. - callbacks duplicate after reopening: inspect construct/activation bindings and unbind path. - client ui changes but server state does not: route intent through an owned replicated actor. - listen server appears correct: repeat on a remote client; host-local ownership can hide bugs. event-driven binding and mvvm event-driven binding and mvvm default: explicit push updates 1. gameplay model exposes a typed change delegate/event. 2. local presenter subscribes and converts raw state into display state. 3. presenter calls a small widget setter such as sethealth(current, max). 4. widget updates only the affected controls. 5. unbind in the matching lifecycle hook. this keeps gameplay independent of widget classes and avoids per-frame polling. mvvm path use the umg viewmodel plugin when reusable view state and declarative bindings justify a beta dependency. 1. enable umg viewmodel. 2. create a umvvmviewmodelbase subclass or implement inotifyfieldvaluechanged in c++. 3. expose display fields with fieldnotify. 4. keep fields private/protected and mutate through setters that broadcast only on change. 5. prefer one-way-to-widget for authoritative/display state. 6. use two-way binding only for genuine editable form state; submit validated intent separately. 7. test cooked builds and reassignment paths. epic documents a current binding-invalidity caveat when a designer-bound viewmodel is reassigned in the details panel. record that mvvm is beta in ue 5.8 in the technical-risk register. replicated state to ui text server changes replicated property -> client repnotify/delegate -> local presenter or viewmodel setter -> fieldnotify/delegate -> widget update do not poll the replicated actor from a widget binding. do not play irreversible one-shot vfx solely because initial replication invoked a state onrep; distinguish current state from a newly observed event. rules - raw umg property/function binding is not the event-driven mvvm path. - directly setting a widget property can break a classic property binding. - a viewmodel formats and exposes presentation state; it does not become gameplay authority. - keep async asset/data readiness explicit with loading, ready, empty, and error states. - store list item identity in data objects, not recycled entry-widget instances. commonui routing and layers commonui routing and layers project setup 1. enable commonui and enhanced input. 2. set the game viewport client class to commongameviewportclient, or derive the custom viewport client from it. 3. in ue 5.8, enable/use the unified enhanced input support and attach commonui metadata to ui input actions as required by the project. 4. define default accept and back actions and controller/input glyph data. 5. build one root layout with explicit named layers. recommended layers | layer | typical content | container | |---|---|---| | hud | persistent nonmodal gameplay display | persistent root/content | | game menu | inventory, map, pause | activatable stack | | modal | confirmations, blocking dialogs | higher-priority activatable stack | | notification | toasts, rewards, transient messages | queue or nonblocking overlay | use a ucommonactivatablewidgetstack when only the top screen should be displayed and active. use a queue for sequential transient presentation. do not drive layer priority with scattered viewport z-orders once the ui has a layer system. activatable widget rule make a screen activatable when it is a meaningful node in the input hierarchy, needs an activation lifetime, or owns back behavior. keep leaf controls and passive display widgets as ucommonuserwidget or regular uuserwidget. on activation: 1. apply the screen's input configuration/mapping context. 2. bind activation-scoped model events. 3. establish the desired focus target. 4. start entrance presentation after valid data exists. on deactivation: 1. stop screen-owned async work and animation callbacks. 2. unbind activation-scoped events. 3. remove screen-owned input contexts/configuration. 4. let the stack restore the preceding active screen. routing mental model commonui routes input through the active activatable widget tree. the viewport hands input to the action router, which begins at the topmost painted active root and recursively checks active nodes/bindings. deactivated widgets are not routing nodes. back handling - define one universal back action. - the topmost dismissible activatable screen handles it. - a modal closes before the menu under it. - root screens either decline back or route it to an intentional product action. - never bind independent escape/gamepad-face-right handlers throughout the tree. verification - open two nested screens and a modal; back must unwind in exact reverse order. - switch mouse to gamepad at runtime; prompts and focus must update without a click. - deactivate a screen; it must no longer consume input. - reopen repeatedly; bindings and mapping contexts must not accumulate. input, focus, and navigation input, focus, and navigation define per-screen policy for each screen record: - input mode: game only, ui only, or game and ui; - mouse cursor/capture/lock policy; - enhanced input mapping contexts applied while active; - initial desired-focus widget; - back behavior; - whether gameplay input continues beneath the screen. do not let individual buttons decide global input mode. focus lifecycle 1. populate or restore screen data. 2. ensure the target widget is visible, enabled, focusable, and in the active hierarchy. 3. return/set the desired focus target during activation. 4. when a focused entry disappears, move focus to a deterministic neighbor or parent control. 5. when a modal closes, restore focus to the action that opened it when still valid. avoid arbitrary delays as a focus fix. a delay can mask invalid lifecycle or asynchronous list population. focus after the target exists, using the activation/data-ready event. navigation - build logical visual order so automatic cardinal navigation is predictable. - add explicit navigation rules only where spatial layout makes automatic choice ambiguous. - test keyboard tab/arrow navigation and gamepad cardinal navigation separately. - keep focus visible with a non-color-only indicator. - prevent focus from entering hidden, disabled, decorative, or offscreen controls. - for scroll/list screens, keep the selected entry scrolled into view. unified commonui + enhanced input - use semantic ui input actions, not hard-coded keys. - mark generic actions so commonui handles routing without broadcasting unwanted global enhanced input events. - apply screen-specific mapping contexts on activation and remove them on deactivation. - keep gameplay and ui action namespaces clear; prioritize contexts intentionally. - route remapping/profile details to $unreal-enhanced-input. split-screen check run with two local players. each player must have an independent focus user, root ui, action router/context state, and prompts. getplayercontroller(0) in reusable ui is a defect signal. common failures | symptom | check | |---|---| | gamepad moves character behind menu | input mode/context priority and screen activation | | accept fires twice | duplicate action binding or both generic and specific action paths | | focus vanishes after list refresh | recycled entry was focus target; restore by item identity | | mouse works, gamepad does not | focusability, desired focus, viewport class, navigation | | back closes wrong screen | layer priority or competing local back handlers | patterns and troubleshooting patterns and troubleshooting hud from replicated health 1. server owns and mutates health. 2. health replicates with repnotify or gas attribute delegates. 3. local presenter subscribes for the owning player. 4. presenter emits normalized value and formatted text. 5. hud updates progress/text once per change. route gas-owned health to $unreal-gas-attributes-effects and replication to $unreal-replication. pause/inventory screen 1. push an activatable screen onto the game-menu stack. 2. apply the screen input config and ui mapping context. 3. populate data before selecting desired focus. 4. back deactivates the top screen. 5. deactivation removes context/subscriptions and restores prior focus. remember that a local pause does not automatically pause an authoritative multiplayer server. inventory list - store inventory entries as item data/uobjects, not entry widgets. - use listview or tileview virtualization. - in entry initialization/assignment, overwrite every visual field and selection state. - preserve selection by stable item identity across refresh. - submit move/equip/drop intent to authoritative gameplay; wait for replicated confirmation. modal confirmation - push to the modal layer above menus. - give it an explicit default focus and cancel/back route. - disable duplicate submission after accept. - return a semantic result callback; do not let the modal mutate distant gameplay state directly. diagnostic table | symptom | likely cause | first check | |---|---|---| | ui only works for host | wrong local-player ownership or client lacks presentation hookup | remote client + owning player | | event fires repeatedly after reopen | duplicate construct/activation binding | symmetric unbind and guard | | controller cannot enter screen | no focusable desired target | activation focus path | | back leaks to gameplay | inactive/mis-layered screen or duplicate actions | action router and contexts | | list rows show stale data | pooled entry not fully reset | item-assignment handler | | screen hitches on first open | synchronous construction/asset load | trace load and split/preload | | static screen costs every frame | tick/raw bindings/invalidations | slate insights and compiler rules | | ui claims action succeeded early | local widget mutated canonical state | authoritative confirmation path | shipping gate - all screens operable with every supported input device. - deterministic focus and back behavior at every layer. - split-screen/local-player isolation verified if supported. - resolution, dpi, safe-zone, localization, and maximum-text-scale matrix passes. - remote-client state matches authoritative gameplay under latency and packet loss. - ui trace meets target budget with no growing widget/delegate count. ui performance ui performance measure first profile a representative screen on target hardware with unreal insights and slate insights. record cpu time, paint/layout invalidations, widget count, construction hitches, draw elements, and memory. apply one optimization, then re-profile. highest-value actions 1. replace raw property bindings and widget tick with events/delegates/fieldnotify. 2. remove unused children; hidden children are still loaded and constructed. 3. split huge screens into always-ready, preload, and asynchronously loaded sections. 4. use listview/tileview/treeview for large collections. they virtualize entries and create only enough entry widgets for the visible region. 5. reuse/pool dynamic widgets when churn is measured; clear all item state on reuse. 6. reduce nested canvas panels and rich text where simpler containers/text suffice. 7. avoid overlapping layers that create unnecessary slate layer/draw cost. invalidation selector - global invalidation: evaluate for broad mostly-static ui; measure project-wide behavior. - invalidation box: cache a mostly-static subtree whose geometry/paint rarely changes. - volatile widget: isolate a widget that changes every frame inside an invalidated tree. - retainer panel: flatten a subtree to a texture, optionally reducing render frequency or applying an effect; costs render-target memory and can add latency/artifacts. do not wrap constantly changing trees in invalidation and repeatedly destroy the cache benefit. do not use a retainer panel as a generic speed button. construction strategy | screen type | strategy | |---|---| | always-visible hud | create once; push small updates | | frequent critical menu | preload or keep pooled/hidden if memory permits | | rare expensive menu | async load and release when dismissed | | long inventory | virtualized list; item objects separate from entries | | transient notifications | queue + bounded pool | regression checks - open/close the screen 50 times: widget and delegate counts must stabilize. - scroll thousands of items: entry count should track visible rows, not item count. - change one field: confirm the entire tree is not invalidated unnecessarily. - profile editor and packaged target build; trust the representative target result. responsive layout and accessibility responsive layout and accessibility layout procedure 1. choose one design resolution and author screens consistently at it. 2. configure the project dpi scale rule and curve; shortest-side is the common default, not a universal law. 3. use anchors for edge/corner/center relationships. 4. prefer vertical/horizontal/grid/overlay containers to absolute canvas positioning. 5. put critical edge ui under a safe zone. 6. constrain text and dynamic content deliberately; test expansion rather than clipping it. 7. preview device profiles, aspect ratios, dpi scales, and portrait/landscape when applicable. accessibility baseline - user-adjustable text/ui scale; ue 5.8 also adds commonui.textglobalscaling for commonui text. - critical state encoded with text, icon/shape, or pattern in addition to color. - high-contrast focus state and readable selected/disabled states. - remappable semantic inputs and device-correct prompts. - captions/subtitles with size and contrast options when the game uses speech or critical sound. - toggle or scale screen shake, flashes, motion-heavy ui, and auto-advancing text where relevant. - avoid time-limited menu interactions unless the design truly requires them. test matrix test at minimum: - smallest and largest supported resolution; - 16:9, ultrawide, and supported narrow aspect ratios; - platform safe zones and mobile notches if applicable; - 100%, larger, and maximum supported ui/text scale; - keyboard/mouse, generic gamepad, and supported touch flow; - longest localized strings and right-to-left layout if supported; - color-vision simulation and grayscale readability; - focus-only operation without a pointer. failure recovery - edge content clipped: verify safe zone placement and anchors before adding offsets. - layout drifts by resolution: remove fixed pixel positioning and inspect dpi rule/curve. - large text overlaps: allow content-driven sizing/wrapping and define overflow behavior. - input glyph missing: verify active input type, platform controller data/metadata, and exact gamepad identifiers. ue 5.8 primary sources ue 5.8 primary sources all links were checked against epic's ue 5.8 documentation on 2026-07-19. commonui and input - common ui - commonui design guidelines - commonui overview - commonui input technical guide - commonui quickstart - ue 5.8 release notes: unified commonui and enhanced input - ucommonactivatablewidget - ucommonactivatablewidgetstack umg architecture, layout, and performance - umg viewmodel - umg optimization guidelines - widget designer team settings - dpi scaling - umg safe zones - uuserwidget - uuserwidget::construct - ulistview - using the invalidation box scope and maturity notes - commonui is appropriate principally for complex layered and cross-platform interfaces. - ue 5.8 release notes supersede the stale warning on the older commonui-with-enhanced-input guide by documenting the unified workflow. - umg viewmodel is marked beta in ue 5.8. system selector system selector use umg only choose plain umg when all are true: - screen layering is simple; - mouse/keyboard is primary or gamepad navigation is small; - input prompts do not need automatic platform/device swapping; - the team benefits more from a small dependency surface than commonui routing. umg remains the view layer even when commonui is added. add commonui choose commonui when one or more are load-bearing: - multiple stacked screens or modal layers; - controller-first focus and cardinal navigation; - a universal back action; - platform-specific button glyphs or runtime input-method switching; - selective input routing between overlapping ui layers. commonui is an extensive paradigm, not a general requirement. epic specifically identifies complex multi-layered and cross-platform interfaces as its main use cases. choose the update model | need | preferred mechanism | note | |---|---|---| | small explicit screen | delegates/events + widget setters | stable and easy to trace | | reusable presentation model | viewmodel + fieldnotify | mvvm is beta in ue 5.8 | | one-time construction data | expose-on-spawn/init function | do not poll it | | per-frame visual motion | umg animation/material/limited tick | profile and isolate | do not use raw property/function bindings as the default; they poll and can have a large performance impact. do not adopt beta mvvm without documenting fallback and platform testing. ue 5.8 input choice ue 5.8 release notes describe unification of enhanced input and common input/ui, including removing duplicate data assets. prefer enhanced input actions and metadata for new 5.8 work. treat older commonui action data tables as a legacy-compatible path, not the default new design. related constitution principles - gdc-l1-ux-0002: reveal complexity progressively. - gdc-l1-ux-0003: make the interface communicate. - gdc-l1-ux-0006: build accessibility in early. - gdc-l1-arch-0003: decouple cross-system reactions through events. - gdc-l1-arch-0006: distinguish authoritative from transient state.

Architecture and lifecycle

# Architecture and lifecycle

## Ownership chain

Use this default chain:

```text
server-authoritative gameplay state
  -> replicated actor/component/property
  -> local player presentation model or Viewmodel
  -> local widget tree

widget interaction
  -> semantic local intent
  -> owning PlayerController/Pawn/component
  -> validated gameplay call or Server RPC
```

Widgets are local presentation objects. They must not own canonical inventory, health, match,
or save state. UI may predict presentation, but authoritative correction comes from gameplay.

## Local-player ownership

- Create player UI with an owning `PlayerController`/`LocalPlayer`.
- Prefer `AddToPlayerScreen` for player-specific full-screen UI; it targets the player's
  viewport section. Use `AddToViewport` only when the UI is intentionally viewport-global.
- In split screen, keep one root layout/presentation model per local player.
- Set the owning player on world-space Widget Components when per-player display matters.
- Never fetch player zero as a substitute for correct ownership.

## Widget lifecycle

- `OnInitialized`/`NativeOnInitialized`: one-time instance initialization.
- `Construct`/`NativeConstruct`: Slate construction; it may run multiple times when the widget
  leaves and re-enters the hierarchy.
- `Destruct`/`NativeDestruct`: release hierarchy-time subscriptions/resources, while allowing
  that the UObject can still exist.
- `NativeOnActivated`/`NativeOnDeactivated`: Common Activatable Widget screen-active lifetime.

Bind and unbind symmetrically. Guard against duplicate delegate registration if construction or
activation can repeat. Keep activation-time subscriptions scoped to activation.

## State placement

| State | Owner |
|---|---|
| Health, inventory, score, match phase | Replicated gameplay model |
| Display-formatted health, selected tab, sorted rows | Local presentation model/Viewmodel |
| Hover, focus, animation progress | Widget |
| Input mapping/profile | Local Player input subsystem/user settings |
| Screen stack and modal state | Local root UI/CommonUI layer manager |

## Failure checks

- UI works for client 1 but not client 2: inspect owning local player and player-zero lookups.
- callbacks duplicate after reopening: inspect Construct/activation bindings and unbind path.
- client UI changes but server state does not: route intent through an owned replicated actor.
- listen server appears correct: repeat on a remote client; host-local ownership can hide bugs.

Event-driven binding and MVVM

# Event-driven binding and MVVM

## Default: explicit push updates

1. Gameplay model exposes a typed change delegate/event.
2. Local presenter subscribes and converts raw state into display state.
3. Presenter calls a small widget setter such as `SetHealth(Current, Max)`.
4. Widget updates only the affected controls.
5. Unbind in the matching lifecycle hook.

This keeps gameplay independent of widget classes and avoids per-frame polling.

## MVVM path

Use the UMG Viewmodel plugin when reusable view state and declarative bindings justify a Beta
dependency.

1. Enable UMG Viewmodel.
2. Create a `UMVVMViewModelBase` subclass or implement `INotifyFieldValueChanged` in C++.
3. Expose display fields with `FieldNotify`.
4. Keep fields private/protected and mutate through setters that broadcast only on change.
5. Prefer one-way-to-widget for authoritative/display state.
6. Use two-way binding only for genuine editable form state; submit validated intent separately.
7. Test cooked builds and reassignment paths. Epic documents a current binding-invalidity caveat
   when a designer-bound Viewmodel is reassigned in the Details panel.

Record that MVVM is **Beta in UE 5.8** in the technical-risk register.

## Replicated state to UI

```text
server changes replicated property
  -> client RepNotify/delegate
  -> local presenter or Viewmodel setter
  -> FieldNotify/delegate
  -> widget update
```

Do not poll the replicated actor from a widget binding. Do not play irreversible one-shot VFX
solely because initial replication invoked a state OnRep; distinguish current state from a newly
observed event.

## Rules

- Raw UMG property/function binding is not the event-driven MVVM path.
- Directly setting a widget property can break a classic property binding.
- A Viewmodel formats and exposes presentation state; it does not become gameplay authority.
- Keep async asset/data readiness explicit with loading, ready, empty, and error states.
- Store list item identity in data objects, not recycled entry-widget instances.

CommonUI routing and layers

# CommonUI routing and layers

## Project setup

1. Enable CommonUI and Enhanced Input.
2. Set the Game Viewport Client Class to `CommonGameViewportClient`, or derive the custom
   viewport client from it.
3. In UE 5.8, enable/use the unified Enhanced Input support and attach CommonUI metadata to UI
   Input Actions as required by the project.
4. Define default Accept and Back actions and controller/input glyph data.
5. Build one root layout with explicit named layers.

## Recommended layers

| Layer | Typical content | Container |
|---|---|---|
| HUD | persistent nonmodal gameplay display | persistent root/content |
| Game menu | inventory, map, pause | activatable stack |
| Modal | confirmations, blocking dialogs | higher-priority activatable stack |
| Notification | toasts, rewards, transient messages | queue or nonblocking overlay |

Use a `UCommonActivatableWidgetStack` when only the top screen should be displayed and active.
Use a queue for sequential transient presentation. Do not drive layer priority with scattered
viewport Z-orders once the UI has a layer system.

## Activatable widget rule

Make a screen activatable when it is a meaningful node in the input hierarchy, needs an
activation lifetime, or owns Back behavior. Keep leaf controls and passive display widgets as
`UCommonUserWidget` or regular `UUserWidget`.

On activation:

1. Apply the screen's input configuration/mapping context.
2. Bind activation-scoped model events.
3. Establish the desired focus target.
4. Start entrance presentation after valid data exists.

On deactivation:

1. Stop screen-owned async work and animation callbacks.
2. Unbind activation-scoped events.
3. Remove screen-owned input contexts/configuration.
4. Let the stack restore the preceding active screen.

## Routing mental model

CommonUI routes input through the active Activatable Widget tree. The viewport hands input to
the action router, which begins at the topmost painted active root and recursively checks active
nodes/bindings. Deactivated widgets are not routing nodes.

## Back handling

- Define one universal Back action.
- The topmost dismissible activatable screen handles it.
- A modal closes before the menu under it.
- Root screens either decline Back or route it to an intentional product action.
- Never bind independent Escape/Gamepad-Face-Right handlers throughout the tree.

## Verification

- Open two nested screens and a modal; Back must unwind in exact reverse order.
- Switch mouse to gamepad at runtime; prompts and focus must update without a click.
- Deactivate a screen; it must no longer consume input.
- Reopen repeatedly; bindings and mapping contexts must not accumulate.

Input, focus, and navigation

# Input, focus, and navigation

## Define per-screen policy

For each screen record:

- input mode: game only, UI only, or game and UI;
- mouse cursor/capture/lock policy;
- Enhanced Input Mapping Contexts applied while active;
- initial desired-focus widget;
- Back behavior;
- whether gameplay input continues beneath the screen.

Do not let individual buttons decide global input mode.

## Focus lifecycle

1. Populate or restore screen data.
2. Ensure the target widget is visible, enabled, focusable, and in the active hierarchy.
3. Return/set the desired focus target during activation.
4. When a focused entry disappears, move focus to a deterministic neighbor or parent control.
5. When a modal closes, restore focus to the action that opened it when still valid.

Avoid arbitrary delays as a focus fix. A delay can mask invalid lifecycle or asynchronous list
population. Focus after the target exists, using the activation/data-ready event.

## Navigation

- Build logical visual order so automatic cardinal navigation is predictable.
- Add explicit navigation rules only where spatial layout makes automatic choice ambiguous.
- Test keyboard Tab/arrow navigation and gamepad cardinal navigation separately.
- Keep focus visible with a non-color-only indicator.
- Prevent focus from entering hidden, disabled, decorative, or offscreen controls.
- For scroll/list screens, keep the selected entry scrolled into view.

## Unified CommonUI + Enhanced Input

- Use semantic UI Input Actions, not hard-coded keys.
- Mark generic actions so CommonUI handles routing without broadcasting unwanted global
  Enhanced Input events.
- Apply screen-specific Mapping Contexts on activation and remove them on deactivation.
- Keep gameplay and UI action namespaces clear; prioritize contexts intentionally.
- Route remapping/profile details to `$unreal-enhanced-input`.

## Split-screen check

Run with two local players. Each player must have an independent focus user, root UI, action
router/context state, and prompts. `GetPlayerController(0)` in reusable UI is a defect signal.

## Common failures

| Symptom | Check |
|---|---|
| Gamepad moves character behind menu | input mode/context priority and screen activation |
| Accept fires twice | duplicate action binding or both generic and specific action paths |
| Focus vanishes after list refresh | recycled entry was focus target; restore by item identity |
| Mouse works, gamepad does not | focusability, desired focus, viewport class, navigation |
| Back closes wrong screen | layer priority or competing local Back handlers |

Patterns and troubleshooting

# Patterns and troubleshooting

## HUD from replicated health

1. Server owns and mutates health.
2. Health replicates with RepNotify or GAS attribute delegates.
3. Local presenter subscribes for the owning player.
4. Presenter emits normalized value and formatted text.
5. HUD updates progress/text once per change.

Route GAS-owned health to `$unreal-gas-attributes-effects` and replication to
`$unreal-replication`.

## Pause/inventory screen

1. Push an activatable screen onto the game-menu stack.
2. Apply the screen input config and UI Mapping Context.
3. Populate data before selecting desired focus.
4. Back deactivates the top screen.
5. Deactivation removes context/subscriptions and restores prior focus.

Remember that a local pause does not automatically pause an authoritative multiplayer server.

## Inventory list

- Store inventory entries as item data/UObjects, not entry widgets.
- Use `ListView` or `TileView` virtualization.
- In entry initialization/assignment, overwrite every visual field and selection state.
- Preserve selection by stable item identity across refresh.
- Submit move/equip/drop intent to authoritative gameplay; wait for replicated confirmation.

## Modal confirmation

- Push to the modal layer above menus.
- Give it an explicit default focus and cancel/Back route.
- Disable duplicate submission after accept.
- Return a semantic result callback; do not let the modal mutate distant gameplay state directly.

## Diagnostic table

| Symptom | Likely cause | First check |
|---|---|---|
| UI only works for host | wrong local-player ownership or client lacks presentation hookup | remote client + owning player |
| Event fires repeatedly after reopen | duplicate Construct/activation binding | symmetric unbind and guard |
| Controller cannot enter screen | no focusable desired target | activation focus path |
| Back leaks to gameplay | inactive/mis-layered screen or duplicate actions | action router and contexts |
| List rows show stale data | pooled entry not fully reset | item-assignment handler |
| Screen hitches on first open | synchronous construction/asset load | trace load and split/preload |
| Static screen costs every frame | Tick/raw bindings/invalidations | Slate Insights and compiler rules |
| UI claims action succeeded early | local widget mutated canonical state | authoritative confirmation path |

## Shipping gate

- All screens operable with every supported input device.
- Deterministic focus and Back behavior at every layer.
- Split-screen/local-player isolation verified if supported.
- Resolution, DPI, safe-zone, localization, and maximum-text-scale matrix passes.
- Remote-client state matches authoritative gameplay under latency and packet loss.
- UI trace meets target budget with no growing widget/delegate count.

UI performance

# UI performance

## Measure first

Profile a representative screen on target hardware with Unreal Insights and Slate Insights.
Record CPU time, paint/layout invalidations, widget count, construction hitches, draw elements,
and memory. Apply one optimization, then re-profile.

## Highest-value actions

1. Replace raw property bindings and widget Tick with events/delegates/FieldNotify.
2. Remove unused children; hidden children are still loaded and constructed.
3. Split huge screens into always-ready, preload, and asynchronously loaded sections.
4. Use `ListView`/`TileView`/`TreeView` for large collections. They virtualize entries and create
   only enough entry widgets for the visible region.
5. Reuse/pool dynamic widgets when churn is measured; clear all item state on reuse.
6. Reduce nested Canvas Panels and rich text where simpler containers/text suffice.
7. Avoid overlapping layers that create unnecessary Slate layer/draw cost.

## Invalidation selector

- **Global Invalidation**: evaluate for broad mostly-static UI; measure project-wide behavior.
- **Invalidation Box**: cache a mostly-static subtree whose geometry/paint rarely changes.
- **Volatile widget**: isolate a widget that changes every frame inside an invalidated tree.
- **Retainer Panel**: flatten a subtree to a texture, optionally reducing render frequency or
  applying an effect; costs render-target memory and can add latency/artifacts.

Do not wrap constantly changing trees in invalidation and repeatedly destroy the cache benefit.
Do not use a Retainer Panel as a generic speed button.

## Construction strategy

| Screen type | Strategy |
|---|---|
| Always-visible HUD | create once; push small updates |
| Frequent critical menu | preload or keep pooled/hidden if memory permits |
| Rare expensive menu | async load and release when dismissed |
| Long inventory | virtualized list; item objects separate from entries |
| Transient notifications | queue + bounded pool |

## Regression checks

- Open/close the screen 50 times: widget and delegate counts must stabilize.
- Scroll thousands of items: entry count should track visible rows, not item count.
- Change one field: confirm the entire tree is not invalidated unnecessarily.
- Profile editor and packaged target build; trust the representative target result.

Responsive layout and accessibility

# Responsive layout and accessibility

## Layout procedure

1. Choose one design resolution and author screens consistently at it.
2. Configure the project DPI Scale Rule and curve; shortest-side is the common default, not a
   universal law.
3. Use anchors for edge/corner/center relationships.
4. Prefer Vertical/Horizontal/Grid/Overlay containers to absolute Canvas positioning.
5. Put critical edge UI under a Safe Zone.
6. Constrain text and dynamic content deliberately; test expansion rather than clipping it.
7. Preview device profiles, aspect ratios, DPI scales, and portrait/landscape when applicable.

## Accessibility baseline

- User-adjustable text/UI scale; UE 5.8 also adds `CommonUI.TextGlobalScaling` for CommonUI text.
- Critical state encoded with text, icon/shape, or pattern in addition to color.
- High-contrast focus state and readable selected/disabled states.
- Remappable semantic inputs and device-correct prompts.
- Captions/subtitles with size and contrast options when the game uses speech or critical sound.
- Toggle or scale screen shake, flashes, motion-heavy UI, and auto-advancing text where relevant.
- Avoid time-limited menu interactions unless the design truly requires them.

## Test matrix

Test at minimum:

- smallest and largest supported resolution;
- 16:9, ultrawide, and supported narrow aspect ratios;
- platform safe zones and mobile notches if applicable;
- 100%, larger, and maximum supported UI/text scale;
- keyboard/mouse, generic gamepad, and supported touch flow;
- longest localized strings and right-to-left layout if supported;
- color-vision simulation and grayscale readability;
- focus-only operation without a pointer.

## Failure recovery

- Edge content clipped: verify Safe Zone placement and anchors before adding offsets.
- Layout drifts by resolution: remove fixed pixel positioning and inspect DPI rule/curve.
- Large text overlaps: allow content-driven sizing/wrapping and define overflow behavior.
- Input glyph missing: verify active input type, platform Controller Data/metadata, and exact
  gamepad identifiers.

UE 5.8 primary sources

# UE 5.8 primary sources

All links were checked against Epic's UE 5.8 documentation on 2026-07-19.

## CommonUI and input

- [Common UI](https://dev.epicgames.com/documentation/en-us/unreal-engine/common-ui-plugin-for-advanced-user-interfaces-in-unreal-engine)
- [CommonUI design guidelines](https://dev.epicgames.com/documentation/en-us/unreal-engine/design-guidelines-for-using-commonui-in-unreal-engine)
- [CommonUI overview](https://dev.epicgames.com/documentation/en-us/unreal-engine/overview-of-advanced-multiplatform-user-interfaces-with-common-ui-for-unreal-engine)
- [CommonUI input technical guide](https://dev.epicgames.com/documentation/en-us/unreal-engine/commonui-input-technical-guide-for-unreal-engine)
- [CommonUI quickstart](https://dev.epicgames.com/documentation/en-us/unreal-engine/common-ui-quickstart-guide-for-unreal-engine)
- [UE 5.8 release notes: unified CommonUI and Enhanced Input](https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-engine-5-8-release-notes)
- [`UCommonActivatableWidget`](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Plugins/CommonUI/UCommonActivatableWidget)
- [`UCommonActivatableWidgetStack`](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Plugins/CommonUI/UCommonActivatableWidgetStack)

## UMG architecture, layout, and performance

- [UMG Viewmodel](https://dev.epicgames.com/documentation/en-us/unreal-engine/umg-viewmodel-for-unreal-engine)
- [UMG optimization guidelines](https://dev.epicgames.com/documentation/en-us/unreal-engine/optimization-guidelines-for-umg-in-unreal-engine)
- [Widget Designer team settings](https://dev.epicgames.com/documentation/en-us/unreal-engine/widget-designer-team-settings-in-the-unreal-engine-project-settings)
- [DPI scaling](https://dev.epicgames.com/documentation/en-us/unreal-engine/dpi-scaling-in-unreal-engine)
- [UMG Safe Zones](https://dev.epicgames.com/documentation/en-us/unreal-engine/umg-safe-zones-in-unreal-engine)
- [`UUserWidget`](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/UMG/UUserWidget)
- [`UUserWidget::Construct`](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/UMG/UUserWidget/Construct)
- [`UListView`](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/UMG/UListView)
- [Using the Invalidation Box](https://dev.epicgames.com/documentation/en-us/unreal-engine/using-the-invalidation-box-for-umg-in-unreal-engine)

## Scope and maturity notes

- CommonUI is appropriate principally for complex layered and cross-platform interfaces.
- UE 5.8 release notes supersede the stale warning on the older CommonUI-with-Enhanced-Input
  guide by documenting the unified workflow.
- UMG Viewmodel is marked **Beta** in UE 5.8.

System selector

# System selector

## Use UMG only

Choose plain UMG when all are true:

- screen layering is simple;
- mouse/keyboard is primary or gamepad navigation is small;
- input prompts do not need automatic platform/device swapping;
- the team benefits more from a small dependency surface than CommonUI routing.

UMG remains the view layer even when CommonUI is added.

## Add CommonUI

Choose CommonUI when one or more are load-bearing:

- multiple stacked screens or modal layers;
- controller-first focus and cardinal navigation;
- a universal back action;
- platform-specific button glyphs or runtime input-method switching;
- selective input routing between overlapping UI layers.

CommonUI is an extensive paradigm, not a general requirement. Epic specifically identifies
complex multi-layered and cross-platform interfaces as its main use cases.

## Choose the update model

| Need | Preferred mechanism | Note |
|---|---|---|
| Small explicit screen | Delegates/events + widget setters | Stable and easy to trace |
| Reusable presentation model | Viewmodel + FieldNotify | MVVM is Beta in UE 5.8 |
| One-time construction data | Expose-on-spawn/init function | Do not poll it |
| Per-frame visual motion | UMG animation/material/limited Tick | Profile and isolate |

Do not use raw property/function bindings as the default; they poll and can have a large
performance impact. Do not adopt Beta MVVM without documenting fallback and platform testing.

## UE 5.8 input choice

UE 5.8 release notes describe unification of Enhanced Input and Common Input/UI, including
removing duplicate data assets. Prefer Enhanced Input Actions and metadata for new 5.8 work.
Treat older CommonUI action Data Tables as a legacy-compatible path, not the default new design.

## Related Constitution principles

- `GDC-L1-UX-0002`: reveal complexity progressively.
- `GDC-L1-UX-0003`: make the interface communicate.
- `GDC-L1-UX-0006`: build accessibility in early.
- `GDC-L1-ARCH-0003`: decouple cross-system reactions through events.
- `GDC-L1-ARCH-0006`: distinguish authoritative from transient state.