Quick Start

By the end of this page you have the full UI stack running: a policy that creates one root layout per local player, tag-keyed layers registered on it, and a HUD layout pushed onto the Game layer at startup. Every screen you build later is a two-line push onto this stack.

Prerequisites
A UE 5.8 project. Nothing else - every asset is created below. CommonUI, EnhancedInput, and ModelViewViewModel are engine plugins that enable automatically with CrimsonUI.

1. Enable the plugin

Open Edit -> Plugins, type Crimson in the search box, tick CrimsonUI's checkbox (and CrimsonCommon, its dependency), and restart the editor when prompted. For a Blueprint project that is the entire install - you never hand-edit the .uproject or any .Build.cs.

Edit -> Plugins -> search 'Crimson' -> tick CrimsonUI's Enabled checkbox -> restart the editor.

C++ projects: after enabling the plugin, add its module to your build file so your game code can use its types:

csharp
// YourGame.Build.cs
PublicDependencyModuleNames.Add("CrimsonUI");
PublicDependencyModuleNames.Add("CrimsonCommon"); // policy/layout base layer
Verify
CrimsonUI shows as enabled in the Plugins window and the editor restarts without errors.

2. Set the Game Instance and Local Player classes

The UI manager boots off two classes from CrimsonCommon. UCrimsonCommonGameInstance broadcasts player-added/removed events the manager subscribes to; UCrimsonCommonLocalPlayer is the local-player type the manager requires (players of any other class are silently ignored). UCrimsonCommonGameInstance is Abstract, so make a subclass first.

Content Browser -> Blueprint Class -> parent = Crimson Common Game Instance -> name it BP_GameInstance. Then Project Settings -> Maps & Modes -> Game Instance Class = BP_GameInstance.
Skip this and nothing ever appears
UCrimsonUIManagerSubsystem casts the game instance to UCrimsonCommonGameInstance to hear about players, and only creates a layout for local players that are UCrimsonCommonLocalPlayer subclasses. Wrong class on either = no layout, no widgets, no error message.
Verify
Project Settings -> Maps & Modes shows your game instance; DefaultEngine.ini has the LocalPlayerClassName line.

3. Set the viewport client

UCrimsonGameViewportClient (a UCommonGameViewportClient) drives hardware vs software cursor from the Platform.Trait.Input.HardwareCursor platform trait. CommonUI needs a UCommonGameViewportClient for its input routing, so set it even if you never touch cursors:

Edit -> Project Settings -> Engine -> General Settings -> Default Classes -> Game Viewport Client Class = Crimson Game Viewport Client.

Open Edit -> Project Settings -> Engine -> General Settings, expand the Default Classes section, and set Game Viewport Client Class = Crimson Game Viewport Client. The editor prompts to restart - accept it, because the viewport client class is only swapped in on startup. No .ini editing needed; the picker writes the same GameViewportClientClassName line for you.

Verify
PIE still launches normally. CommonUI input routing (step 4) depends on this class.

4. Give CommonUI its Click and Back actions

CommonUI's action router needs a Click and a Back input action to drive activatable widgets. Create two Input Action assets (Content Browser -> right-click -> Input -> Input Action), e.g. IA_UI_Confirm and IA_UI_Back, then register them. On UE 5.8 use the Enhanced Input path - it resolves live key bindings so button glyphs update on rebind:

ini
; Config/DefaultGame.ini
[/Script/CommonInput.CommonInputSettings]
bEnableEnhancedInputSupport=True
EnhancedInputClickAction=/Game/Input/IA_UI_Confirm.IA_UI_Confirm
EnhancedInputBackAction=/Game/Input/IA_UI_Back.IA_UI_Back
Legacy path
Without Enhanced Input support, set DefaultClickAction / DefaultBackAction under [/Script/CommonUI.CommonUISettings] instead, and CommonUI reads key bindings from a UCommonUIInputData DataTable. The Enhanced Input path above is recommended for new 5.8 projects. bEnableEnhancedInputSupport also unlocks the EscapeInputAction binding in How-To: HUD Layout & Escape Menu and per-layer input domains via an ActionDomainTable (see Concept: Input Routing & Activatable Widgets).
Verify
The ini lines are in place and the two UInputAction assets exist. Routing is exercised the first time you push an activatable widget (step 9).

5. Define your layer tags

Layers are gameplay tags under the UI.Layer parent. CrimsonUI defines UI.Layer.Menu and UI.Layer.Modal natively (CrimsonCommon adds UI.Layer.ContextMenu); your project defines the rest. Add at least the Game layer in Project Settings -> Project -> GameplayTags -> Gameplay Tag List, or in ini:

ini
; Config/DefaultGameplayTags.ini
[/Script/GameplayTags.GameplayTagsSettings]
+GameplayTagList=(Tag="UI.Layer.Game",DevComment="Always-visible HUD content")
+GameplayTagList=(Tag="UI.Layer.GameMenu",DevComment="In-game menus: inventory, map")
Tags must live under UI.Layer
RegisterLayer and the push functions restrict their tag pickers to the UI.Layer category (meta = (Categories = "UI.Layer")). A tag outside that parent will not appear in the dropdowns.
Verify
The tag picker on any UI.Layer field (step 6) lists UI.Layer.Game, UI.Layer.GameMenu, UI.Layer.Menu, UI.Layer.Modal, and UI.Layer.ContextMenu.

6. Create the root layout Blueprint

The root layout is one widget Blueprint deriving from UCrimsonPrimaryGameLayout (CrimsonCommon). It holds one UCommonActivatableWidgetStack per layer and registers each stack under its tag.

Widget Blueprint BP_RootLayout (parent: Crimson Primary Game Layout). Designer: an Overlay with four Common Activatable Widget Stack children (GameStack, GameMenuStack, MenuStack, ModalStack), each Anchors = Fill. Graph: Event On Initialized -> four Register Layer calls pairing each stack with its UI.Layer tag.

In the Designer add an Overlay, then four Common Activatable Widget Stack children named GameStack, GameMenuStack, MenuStack, ModalStack (each slot set to fill). In the Event Graph, from Event On Initialized call Register Layer four times: (UI.Layer.Game, GameStack), (UI.Layer.GameMenu, GameMenuStack), (UI.Layer.Menu, MenuStack), (UI.Layer.Modal, ModalStack). Register Layer is callable because your Blueprint is the layout class - it does not appear on external references.

A missing RegisterLayer fails silently
Pushing to a tag no stack was registered under does nothing - no warning, the widget just never appears. If a screen refuses to show, check this first.
Verify
The Blueprint compiles with four Register Layer calls, one per stack.

7. Create the policy Blueprint

The policy (UCrimsonGameUIPolicy, CrimsonCommon) decides which layout class to spawn and how local multiplayer shares the screen. Create a Blueprint Class with parent Crimson Game UI Policy, name it BP_UIPolicy, and set:

PropertyValueNotes
LayoutClassBP_RootLayoutRequired. The root layout instantiated per local player.
LocalMultiplayerInteractionModePrimaryOnly (default)PrimaryOnly = only the first local player gets UI. SingleToggle = one player at a time owns it. Simultaneous = every local player gets a layout (couch co-op).
BP_UIPolicy (parent: Crimson Game UI Policy) Class Defaults: Layout Class = BP_RootLayout, Local Multiplayer Interaction Mode = Primary Only.
Verify
BP_UIPolicy's Class Defaults show both properties set.

8. Point Project Settings at the policy

Open Project Settings -> Crimson -> Crimson UI (UCrimsonUISettings, saved to DefaultGame.ini) and set:

SettingRequiredDescription
DefaultUIPolicyClassYesYour BP_UIPolicy. Loaded once when the game instance initializes.
ConfirmationDialogClassFor dialogsA UCrimsonConfirmationScreen subclass - see How-To: Show Confirmation Dialogs.
ErrorDialogClassFor dialogsA UCrimsonConfirmationScreen subclass used by ShowError.
Project Settings -> Crimson -> Crimson UI: Default UI Policy Class = BP_UIPolicy (Confirmation/Error dialog classes can be set later).
DefaultUIPolicyClass is load-bearing
It is read once in UCrimsonUIManagerSubsystem::Initialize (game-instance startup). Null = no policy = no layout for any player. Changing it requires restarting PIE.
Verify
Press Play, then open Window -> Developer Tools -> Widget Reflector: one BP_RootLayout instance exists. Empty screen is correct - nothing is pushed yet.

9. Create a HUD layout and push it

Create a widget Blueprint BP_HUDLayout with parent Crimson HUD Layout (UCrimsonHUDLayout) - it is the always-present root HUD screen (leave its defaults alone for now; How-To: HUD Layout & Escape Menu wires the pause menu). Push it onto the Game layer when the local player is ready:

In your PlayerController Blueprint: Event BeginPlay -> Is Local Player Controller (Branch) -> Push Content To Layer For Player (Owning Player = Self, Widget Class = BP_HUDLayout, Layer Name = UI.Layer.Game). The node is async - it loads the soft class reference before pushing.

The node is Push Content To Layer For Player (async, from UCrimsonAsyncAction_PushToLayer). Its BeforePush pin fires with the created widget before activation - use it to set variables the widget reads on activate; AfterPush fires once it is live.

Verify
Press Play: the Widget Reflector shows BP_HUDLayout inside the Game layer stack. Anything you design into BP_HUDLayout is now always on screen.

10. (Recommended) Set the HUD actor class

ACrimsonHUD registers itself with UGameFrameworkComponentManager, which lets GameFeature actions attach HUD widgets/components later, and feeds the ability-system debugger a useful actor list. Set it as your GameMode's HUD Class:

Project Settings -> Maps & Modes -> Selected GameMode -> HUD Class = Crimson HUD (Default GameMode set to your GameMode Blueprint).

Open Project Settings -> Maps & Modes. Under Default Modes, set Default GameMode to your GameMode Blueprint, then set Selected GameMode -> HUD Class = Crimson HUD (or a Blueprint subclass of it). This saves onto your GameMode Blueprint - no .ini editing required.

The Selected GameMode rows are editable only while the Default GameMode is a Blueprint. You can set the same value directly on the GameMode Blueprint instead: open it and use Class Defaults -> Classes -> HUD Class.

What's next
Learn the getter chains once (How-To: Get the Building Blocks), wire the pause menu (How-To: HUD Layout & Escape Menu), push your first real screen (How-To: Push & Pop Screens), and add dialogs (How-To: Show Confirmation Dialogs).
On the full Crimson stack this is automatic
With CrimsonCore installed, steps 2, 6, 7, 8, and 9 are pre-wired: it ships B_CrimsonGameInstance, CrimsonCoreLocalPlayer, B_CrimsonGameUIPolicy, a root layout, and a GFA_AddWidget GameFeature action that pushes W_CrimsonHUD_Layout when the HUD spawns. See Concept: Full-Stack Integration & Multiplayer.