21. User interface
In short: every built-in screen (menus, party menu, options, dialog, shops, HUDs) takes its look from one UI Style asset, and its arrangement from small layout classes. Ten styles ship in the plugin; change one field and the whole game changes. When you want your own design, you replace any screen with a Widget Blueprint that receives a ready-made view-model, so you never re-implement a rule. This chapter also covers Common UI hosting, accessibility, and touch and phone UI.
21.1 Basics
21.1.1 The three levels of UI work
| You want | Do this | Needs |
|---|---|---|
| A different color, font or frame | Edit or duplicate a UI Style asset | Nothing: editor clicks |
| A different arrangement (bubble dialog, side tabs, shooter-minimal HUD) | Pick a layout in the style, or write a small layout class | Editor clicks, or a little Blueprint |
| A completely different screen | Make a Widget Blueprint derived from RSE Screen Widget and put it in the screen's slot | UMG |
21.1.2 Pick a style
- Open Project Settings → RPG Saga Engine → UI Theme → UI Style.
- Set Default Style to one of the ten shipped styles (the assets are
DA_UIStyle_*in the plugin'sUI/Stylesfolder). Keep several in Selectable Styles and the player gets an Interface style row in Options → Display. - Press Play. Every menu, the dialog, the party menu and the HUDs use it.
The ten styles:
| Style | Look |
|---|---|
| Classic | Deep-blue gradient windows, thin light double frame, gold cursor |
| Parchment | Warm paper, ink-brown double line, sepia text (a light style); visual-novel dialog |
| Gothic | Near-black windows, silver double line, crimson accent, capitals; cinematic dialog |
| Holo | Translucent cyan panels, scanlines, glowing outline; shooter-minimal live HUD, grid inventory |
| Brass | Dark wood and leather, brass border with rivets, amber text |
| Minimal | Flat white surfaces, hairline borders, one blue accent (a light style) |
| Pixel16 | Stepped pixel corners, hard borders, dithered gradient, pixel fonts |
| Anime | Saturated plum, magenta and teal, thick outlines, speech-bubble dialog, radial battle menu |
| Tactical | Olive and graphite, hex-grid pattern, stencil capitals; also fits RPG shooters |
| Sylvan | Translucent moss-green panels, soft gold glow, round corners |
Each style also suggests a battle menu style, an inventory (list or grid) and a Growth board look; the player's own options always win. The Studio's foundation presets pick a matching default style (for example Dark Fantasy → Gothic, Sci-fi RPG → Holo).
21.1.3 Change the whole look with one field
- Open
DA_UIStyle_Classic(or better, press Duplicate to project in the Style Editor first; plugin content is read-only for Fab installs). - Colors → Tokens → Primary → Color: pick a green.
- Save. Every window, frame line, selected row and tab turns green; text, gold highlights and HP bars stay.
Or drag the Hue, Saturation and Lightness sliders in the Style Editor toolbar: they write Colors → Global Shift (hue-locked tokens such as Health, Positive and Negative keep their meaning).
21.2 How it works
21.2.1 Colors are tokens
A style has a few seed colors (Primary, Secondary, Accent, Neutral, Text; Positive, Negative, Warning, Info; Health, Mana, Charge, Rare). Each seed has ten derived shades, S50 (lightest) to S900, computed in the perceptual OKLCH space, and roles (Surface0–3, Border, Highlight, Selection, TextMuted, Disabled, Shadow) derived from seeds. Every color field of a style, and of the settings that use UI colors, is a UI Color (FRSEUIColor): a token, a shade, an opacity and an optional fine tune. Tick Fixed to use a plain color that ignores the style. You can add your own tokens (element colors, factions) under Tokens → Custom Tokens.
21.2.2 Frames, fonts, sounds, motion
- Frames: each panel kind (Window, Inset, Plate, Hud, Tooltip, Modal) has a fill gradient, outline, optional double line and glow, a corner shape (Round, Chamfer, Square, Stepped, Notch, Bevel), a procedural pattern (Noise, Paper, Scanlines, HexGrid, BrushedMetal, Dither) and corner ornaments (Dot, Rivet, Bracket). They are drawn by one plugin material, with no textures, in UI units that follow DPI scaling. To use your own art, set Image Override → Brush Image with its Nine Slice margins.
- Fonts: eight text roles (Display, Title, Heading, Body, Label, Caption, Numeric, KeyCap) with font, size, spacing, outline and color; Font Scale resizes all. A role whose font asset is missing is drawn in Roboto with the style's own size and color, so you can ship without the bundled fonts (delete the plugin's
Content/UI/Fontsfolder). - Sounds: Navigate, Confirm, Back, Error, Open, Close, Tab, Purchase, Text Tick. An empty slot plays the sound catalog's
Audio.UI.*sound. - Motion: Transition (Fade, Slide, Scale, Wipe, None), open seconds and curve, row-selection slide, typewriter speed.
21.2.3 Layouts
A style also decides how screens are arranged. Each screen has a few layouts, and every layout works with every style, with mouse and gamepad, from 1280×800 to 4K:
| Screen | Layouts |
|---|---|
| Dialog | Bottom Box, Bubble (speech bubble over the speaker), Cinematic (letterbox), Novel Portrait (large portrait) |
| Party menu | Top Tabs, Side Tabs |
| ATB / turn-based HUD | Bottom Window, Compact Corner |
| Grid Tactics HUD | Corners, Bottom Bar |
| Live Tactics HUD | Corners, Shooter Minimal |
Changing the style at run time rebuilds the open screens with the new layout. Sizes the layouts use (bubble width, side tab column, shooter edge inset) are in Project Settings → RPG Saga Engine → UI Layouts.
21.2.4 Battle HUDs and menus
Each battle mode has its HUD, built from a view-model: the Grid Tactics HUD (RSETacticsHUDViewModel), the classic ATB and turn-based HUD (RSEATBHUDViewModel) and the Live Tactics HUD, plus results, game over, banners and the action-command ring. ARSEBattleHUD is the framework's HUD class and hosts them.
Battle menus are data. A Battle Menu Config (URSEBattleMenuConfig) lists providers (URSEBattleMenuProvider: Movement, Command Layout, Pact, Items, Flee, Doors, End Turn, Custom) and category definitions. A Battle Menu Style (URSEBattleMenuStyle) picks the look: List, Radial or Hotbar. The default is chosen in Project Settings → Battle Menus and the player can change it in Options. A new menu look is a new presenter widget class plus a style asset; a new source of commands is a new provider. Menus never act on their own: every entry goes through the same command path, so all menu styles give the same commands.
21.2.5 The screen, the view-model and the slot
Every screen is built the same way:
- a settings slot (Project Settings → RPG Saga Engine → page → Widget Class): empty means the built-in themed screen;
- a view-model (
URSEScreenViewModeland subclasses): a Blueprint-readable object with everything the screen shows, already formatted, plus every action it can take (buy, equip, choose, continue); - a screen base (
URSEScreenWidget): the built-in screens and your Widget Blueprints derive from it and receive the view-model.
The built-in screens use exactly the same view-models and actions as yours, so a replacement cannot forget a rule (money, stock limits, formation limits, save restrictions).
21.2.6 Replace a screen
- Create a Widget Blueprint whose parent class is RSE Screen Widget (for a character card, RSE Member Card Widget).
- Design it freely in UMG.
- In its Event Graph, implement On View Model Changed: Cast To the screen's view-model class (for example
RSEShopViewModel), then copy its data to your widgets. It runs once when the screen gets its view-model and after every change. - Call the view-model's actions from buttons (On Clicked → Buy, Equip, Continue). Keyboard and gamepad already work: On Confirm, On Back, On Navigate and On Page forward to the view-model by default.
- Set your Widget Blueprint in the screen's slot.
Slots include: Tactics HUD (UI → Tactics HUD Widget Class), classic HUD (UI → ATB HUD Widget Class), party menu (UI → Party Menu Widget Class, or one page via Party Menu Page Widget Classes), dialog (Dialog UI → Dialog Widget Class), shop (Economy UI → Shop Widget Class), save and load (Save UI → Slot Widget Class), options (Options → Widget Class), battle results and game over (Battle Flow UI), world map and travel overlay (Travel UI), card table and album (Cards UI), code lock (Puzzle UI), interaction prompt (Interaction → Prompt Widget Class), quest tracker (Quest UI → Quest HUD Class), main menu (Game Flow → Main Menu Widget Class), scene overlay (Scenes), battle banners and the action command ring (Battle Presentation). The full table with the view-model of each is in docs/product/custom-ui.md. A class that cannot be used (missing, abstract, not an RSE Screen Widget) is reported in the log and the built-in screen is used instead.
You can replace part of a screen: one party-menu page, the Tactics forecast panel or deployment panel, or just the character cards. A card Widget Blueprint derived from RSE Member Card Widget fills itself if its widgets are named NameText, ClassText, LevelText, HPText, HPBar, StatusText and Portrait: no graph needed.
Four examples ship in /RPGSagaEngine/Examples/UI (WBP_Example_PartyPage, WBP_Example_MemberCard, WBP_Example_ResultsScreen, WBP_Example_DialogBox). Copy one into your project before editing it.
21.2.7 Accessibility
Accessibility is applied on top of the active style, so every style (and your screens, if they read the style) gets it. Options → Display has: Interface style, Color vision (Off, Protanopia, Deuteranopia, Tritanopia: replaces the signal colors; Health stays red), High contrast (opaque near-black surfaces, white text, strong outlines), Text size (80% to 150%, never below UI Theme → Minimum Font Size) and Reduce motion. Changes apply live. A style that cannot be read is an invalid asset: Validate (contrast) in the Style Editor checks text on surface (4.5:1), selected row (4.5:1) and caption (3:1) for normal vision, the three color-vision modes and high contrast.
21.2.8 Common UI integration
The module RSECommonUI hosts the plugin's screens on Epic's CommonUI layer stacks, so your Common Activatable Widgets and ours share one focus and back order. It is a host layer, not a migration: our screens keep their own build path, style, layouts and view-models, and the host is off by default.
Turn it on in Project Settings → RPG Saga Engine → Common UI: Route Screens (our screens go onto the layers), Party Menu Host (Fallback or Always) and Use Common Input Key Prompts (CommonInput controller icons in key prompts). The four layers are Game, Game Menu (the party menu), Menu (options, save, shops, maps) and Modal (popups). Your own primary layout: derive a Widget Blueprint from RSE Common UI Layout and name its stacks GameLayer, GameMenuLayer, MenuLayer, ModalLayer; or, if you already have a layout, call Register Layer Stack on Get RSE Common UI. Each screen is wrapped in an RSE Common Screen Host that applies the input config and routes CommonUI's back and navigation to it. Key prompt icons come from your CommonInput controller data, else generic glyphs drawn in code (the plugin ships no platform logos).
21.2.9 Touch and phone UI
Touch is a third control device next to keyboard and gamepad. Every on-screen control and gesture presses one of the input actions the game already uses (Enhanced Input injection), so exploration, all battle modes and the menus behave as with a key. Five Touch Layout data assets ship (DA_TouchLayout_Exploration, GridTactics, LiveTactics, ClassicBattle, Action) in /RPGSagaEngine/Input/Touch, picked in Project Settings → RPG Saga Engine → Touch → Layouts. Controls are placed in the safe area in millimetres, so they are the same physical size on every phone. The phone UI adds physical DPI scaling (set User Interface → DPI Scaling → Custom with RSE Physical Scaling Rule), a 9 mm minimum touch target, safe-area handling, and a Phone variant of every screen layout. Options → Controls has touch size, opacity and a left-handed mode.
Status: the touch and phone code is complete and tested headless, but mobile has not yet been tested on a real phone; treat it as pre-release until your own device tests pass (see 23-platforms-and-performance.md). To try it on PC: RSE.Input.Touch.Emulate 1 (mouse as a finger; hold Alt for a second finger), RSE.UI.Phone.Simulate 1, RSE.Input.Device Touch.
21.3 Key classes and assets
| Class / asset | Module | Role |
|---|---|---|
URSEUIStyle | RSE | The style data asset: seeds, frames, fonts, sounds, motion, layouts |
URSEUIStyleSubsystem | RSE | One per local player: the active style, On Style Changed |
URSEUIStyleLibrary | RSE | Blueprint nodes for style colors, fonts, frames, accessibility |
URSEUIThemeSettings | RSE | Project Settings → UI Theme |
URSEUIStyleEditorSettings | RSEEditor | Project Settings → UI Style Editor (the Style Editor and gallery) |
URSEScreenWidget, URSEScreenViewModel | RSE | Base of every screen and of every view-model |
URSEMemberCardWidget | RSE | A self-filling character card |
URSEHUDWidgetBase | RSE | Base of the built-in screens; style helpers for C++ |
URSEDialogLayout, URSEPartyMenuLayout, URSEATBHUDLayout, URSEGridHUDLayout, URSELiveHUDLayout | RSE | Layout bases |
URSEBattleMenuConfig, URSEBattleMenuProvider | RSECore | What a battle menu offers |
URSEBattleMenuStyle (+ _List, _Radial, _Hotbar), URSEBattleMenuPresenter | RSE | How a battle menu looks |
ARSEBattleHUD | RSE | The framework HUD that hosts battle screens |
URSELocalPlayerUISubsystem | RSE | Finds the UI host of each player; opens screens |
URSECommonUISubsystem, URSECommonUISettings, URSECommonUILayout, URSECommonScreenHost | RSECommonUI | The Common UI host |
URSETouchLayout, URSETouchInputSubsystem, URSETouchControlsWidget, URSEPhoneUISettings, URSEPhysicalScalingRule | RSE | Touch and phone UI |
21.4 Settings
Project Settings → RPG Saga Engine. Full list: Appendix B.
- UI Theme: Default Style, Selectable Styles, Frame Material, Minimum Font Size, accessibility remaps and contrast rules, Player Can Choose Style.
- UI Layouts: the sizes the layouts use.
- UI: the widget class slots of the HUDs and the party menu.
- Dialog UI, Economy UI, Save UI, Options, Travel UI, Cards UI, Puzzle UI, Quest UI, Battle Flow UI, Battle Presentation, Game Flow: one Widget Class slot per screen.
- Battle Menus: the styles, the default and the default icons.
- UI Style Editor: the folder of project copies (
/Game/UI/Styles), the preview map, the gallery commands. - Common UI: Route Screens, Party Menu Host, Use Common Input Key Prompts, layers, Bind Action Bar, Silence Viewport Client Check.
- Touch and Phone UI: layouts, long-press time, emulation, target unit millimetres, minimum touch target, phone layouts, Simulate Phone.
21.5 Blueprint usage
RPG Saga | UI Style nodes (editor and runtime): Get UI Color (token, shade, opacity), Resolve UI Color, Get UI Font (text role), Get UI Frame Brush (panel kind, for a Border or an Image), Get Active UI Style, Set UI Style (by Style Id), Get Selectable UI Styles, Get Selectable UI Style Ids, Preview UI Style and End UI Style Preview, Get UI Accessibility, Set UI Accessibility, Set UI Color Vision, Set UI High Contrast, Set UI Text Scale, Set UI Reduce Motion. Widgets derived from the plugin's screen classes get the event On UI Style Changed: rebuild what shows style colors there.
Example, a style picker for your own options screen:
- Event Construct → Get Selectable UI Style Ids → For Each Loop.
- For each id, Create Widget (a button) and bind its click to Set UI Style (Style Id = the id).
- Bind On UI Style Changed to refresh your own colors with Get UI Color.
Example, a custom shop screen:
- Create a Widget Blueprint with parent RSE Screen Widget.
- Event On View Model Changed → Cast To RSEShopViewModel (Object = View Model) → read its lists into your widgets (Join Text Lines, Fill Member Cards shorten the graph).
- Button On Clicked → the view-model's Buy action.
- Set it in Economy UI → Shop Widget Class.
Other useful nodes (RPG Saga | UI): Get Theme Font, Get Panel Brush, Get Key Label, Get Action Key Label, Make Menu Prompt, Is Using Gamepad, Play UI Sound, and the screen openers Open Inventory, Open Growth and Open Party Menu (Player), which work with any HUD class. Common UI: Get RSE Common UI → Push Widget To Layer, Push Screen, Pop Screen, Register Layer Stack.
A custom layout in Blueprint: create a class from the screen's layout base (RSE Dialog Layout, RSE Party Menu Layout, RSE ATB HUD Layout, RSE Grid HUD Layout, RSE Live HUD Layout), override Arrange, and use the context nodes Place Part, Place Part Stretched, Place Part Fitted, Place Part Full Screen, Group Parts, Hide Part, Get Margin, Get Canvas Size, Has Flag. Pick it in the style under Layout → Layouts → Custom ... Layout. Layouts only place the parts a screen built and keep no state.
21.6 C++ usage
// A widget derived from URSEHUDWidgetBase: colors and fonts follow the style.
void UMyBadgeWidget::NativeOnStyleChanged()
{
Super::NativeOnStyleChanged();
const FLinearColor Border = Color(RSEUITokens::Accent);
const FSlateFontInfo Label = Font(ERSETextRole::Label);
// rebuild what shows these
}
// A layout in C++.
UCLASS()
class UMyDialogLayout : public URSEDialogLayout
{
GENERATED_BODY()
virtual void Arrange_Implementation(URSEScreenLayoutContext* Context) const override;
};
In your own settings, use FRSEUIColor instead of FLinearColor for any color that should follow the style. For a view-model of your own system, derive from URSEScreenViewModel, expose data and actions, and let OnChanged tell the widget. Layout part names are in UI/Layout/RSEScreenLayouts.h.
21.7 Advanced
- Contrast and tokens in your own content. Use tokens for anything that carries meaning; Fixed colors never follow high contrast or color-vision changes.
- Shipping without bundled fonts. Remove the plugin's
Content/UI/Fontsfolder; the automation testRSE.UI.Style.Shippedchecks that all styles still pass contrast. - Split-screen. The UI Style Subsystem is per local player, so players can use different styles.
- Growth board. Board styles follow the UI style by default (Color Mode: Follow UI Style, Follow Shift Only, Fixed).
- CommonUI and the viewport client. Our layers work without
CommonGameViewportClient; with it, CommonUI's back also reaches our screens, and a press arriving both ways counts once. The action bar lists Confirm, Back and tab switches, with CommonInput icons; you provide the Common Bound Action Bar and button widget in your layout. - Debug commands (development builds).
RSE.UI.Style.Set <StyleId>,RSE.UI.Style.Seed <Token> <R> <G> <B>,RSE.UI.Style.HueShift <deg>,RSE.UI.Style.Frame <Corner> [Pattern] [Ornament] [Glow],RSE.UI.Style.Refresh,RSE.UI.ProceduralFrames 0,RSE.UI.Layout <Screen> <Variant|Off>(for exampleRSE.UI.Layout Dialog Bubble),RSE.UIStyle.Preview <StyleId> [capture], and the phone commands above. The live copy a command edits is never saved. See Appendix C.
21.8 Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| My Widget Blueprint is ignored | Wrong parent class or empty slot; the log says why | Derive from RSE Screen Widget and set the slot in the right settings page |
| My screen shows nothing | The view-model data is read only at construct | Read it in On View Model Changed, which also runs after every change |
| Input fires twice | Reading keys yourself while the controller forwards them | Use the default On Confirm and the other input events; do not bind the same keys again |
| A color does not follow the style | It is a plain Linear Color or marked Fixed | Use a UI Color (FRSEUIColor), or untick Fixed |
| I cannot edit a shipped style | Plugin content is read-only on Fab installs | Duplicate to project in the Style Editor |
| The frames are slow on a weak device | Procedural frames with glow and patterns | Use simpler frames, or RSE.UI.ProceduralFrames 0 to test |
| Common UI back does nothing | The viewport client is not CommonGameViewportClient | Set it in Project Settings → Engine → General Settings, and set a Default Back Action |
| Our screens appear in the viewport, not on layers | Route Screens is off | Turn it on in the Common UI settings |
| Touch controls are tiny or huge | DPI rule not set | Set the physical scaling rule (User Interface → DPI Scaling → Custom) |
| Style change does not show in my screen | It is not derived from the framework screen classes | Bind On Style Changed on the UI Style Subsystem and refresh |
21.9 See also
- 03-game-foundation-and-archetypes.md for the foundation presets that pick a default style.
- 08-battle-common.md and the per-mode battle chapters for the HUDs.
- 14-narrative.md for dialog.
- 19-camera-and-presentation.md for battle banners and presentation.
- 22-networking.md for per-player UI in co-op.
- 23-platforms-and-performance.md for Steam Deck and mobile.
- Product pages:
docs/product/ui-styles.md,custom-ui.md,common-ui.md,mobile.md.