# Open screens on the screen stack

> Show menus of your own on each player's screen stack, beside the Rolly screens: focus, the player's input, Back, the cursor and the pause are handled for you,...

Product: Rolly Save 1.0.0 | Sheet: guide | Updated: 2026-10-31 | HTML: https://rolly-docs.pages.dev/save/guides/screen-stack/

## What the stack does

Each local player has a screen stack, the **Rolly Save Core UI Stack Subsystem** (a local player subsystem, category Rolly Save Core|UI). The top screen has focus; the screens below are hidden, or dimmed behind a dialog. Back (B, Escape) asks the top screen first: a screen can ask before it closes, a dialog answers Cancel.

- **Input:** when the first screen of any local player opens, the stack records the viewport's input flags (ignore input, mouse capture and lock) and the cursor. While a player has a menu screen open, that player's input stops at the screen (keys, sticks and clicks never reach the game), and while every local player has one open the viewport ignores input and frees the mouse. When the last screen closes, input becomes what **Input After Screens** asks for (by default exactly what was recorded, with focus back on the game), however the screens closed: Back, a node, a map change, Remove All Widgets or the player leaving. Keys held while a screen opens or closes are released for the game, so none stays stuck. The cursor shows while the first player (who owns the mouse) has a screen open that wants it, and hides while that player uses a pad.
- **Split screen:** each player has a stack in their own part of the screen, and one player's screen leaves the other players in the game.
- **Pausing:** screens that ask for it pause a **standalone** game, through the game mode's pause with a condition that holds while a screen wants it, so a pause of your game's own is left alone. A listen server, a client and Play In Editor with players over the network never pause for one player's screen. Project Settings > Plugins > **Rolly Save Core UI** > **Pausing** set to Never turns it off everywhere.

Open screens with the stack, never with Add to Viewport: the stack owns focus, the player's input, the cursor, the pause and their restore on every close path.

## Open a screen of your own

### Blueprint

1. Make a Widget Blueprint whose parent class is **Rolly Save Core UI Screen**.
2. In its class defaults set **Input Mode** (Menu or Overlay), **Pause Game**, **Keep Screen Below Visible** and **Show Mouse Cursor**.
3. Open it with **Push Rolly Screen** (from a player controller). Close it with **Pop Rolly Screen**, **Close Rolly Screens** or its own **Close Screen**; **Is Rolly Screen Open** tells whether one is open.
4. Override **On Back** to refuse or ask first; **On Shown**, **On Covered**, **On Closed** and **On Area Changed** tell the screen what happens.

A main or pause menu of your own made this way shares the stack with the Rolly screens: its Settings button opens the settings screen of a settings product, and Back comes back to it. Made of the Rolly widgets (the palette's Rolly Save Core category), it follows the theme too.

**Get Rolly Screen Stack** gives the player's stack, with **Push Screen**, **Pop Screen**, **Replace Top Screen**, **Close Screen** (a screen and the ones above it), **Close All Screens**, **Handle Back** (does what Back does), **Get Top Screen**, **Get Screen Count**, **Is Any Screen Open** and the events **On Screen Opened**, **On Screen Closed**, **On Stack Opened** (the first screen opened) and **On Stack Closed** (the last one closed).

### C++

```cpp
#include "Screens/RollySaveCoreUIScreen.h"
#include "Widgets/RollySaveCoreUIText.h"
#include "MyCreditsScreen.generated.h"

UCLASS()
class UMyCreditsScreen : public URollySaveCoreUIScreen
{
	GENERATED_BODY()

protected:
	// Runs only when no Blueprint layout replaces the tree.
	virtual void BuildDefaultTree() override
	{
		URollySaveCoreUIText* Title = MakePart<URollySaveCoreUIText>(TEXT("TitleText"));
		Title->SetRoles(ERollySaveCoreUITextRole::Display, ERollySaveCoreUIColorRole::Text);
		Title->SetText(NSLOCTEXT("MyGame", "CreditsTitle", "Credits"));
		WidgetTree->RootWidget = Title;
	}
};

// Opening it for a player (#include "Stack/RollySaveCoreUIStackSubsystem.h"):
if (URollySaveCoreUIStackSubsystem* Stack = URollySaveCoreUIStackSubsystem::Get(LocalPlayer))
{
	Stack->PushScreen(UMyCreditsScreen::StaticClass());
}
```

Build the default tree in `BuildDefaultTree` with parts named like the class's `BindWidgetOptional` members, so a Blueprint layout can replace it. A screen of categories of rows (a codex, a controls list) derives from `URollySaveCoreUICategoryScreen` and supplies data only (`CollectCategories`, `BuildRows`, `CollectDetail`, and what Apply, Revert, Reset and Discard do): it gets the five layouts, layout switching at run time, the navigations, the detail forms, the footer, touch and split screen.

## Add tabs and prompts to your screens

The tabs row and the footer prompts of the category screens (the settings screen is one) are components you can use in your own screens. Both follow the player's input device by themselves.

- A **Rolly Tab Strip** shows tabs between the keys that switch them: **Set Tabs** with the labels, **Set Selected Tab** (no event), **Select Previous Tab** and **Select Next Tab** (they go around and fire **On Tab Selected**, as a click on a tab does). It shows the first key of the player's device from **Previous Tab Keys** and **Next Tab Keys** (the shoulder buttons, Q and E, which sit by place on the keyboard layout in use: A and E on AZERTY; no key caps for a touch player); your screen calls Select Previous Tab and Select Next Tab when those keys are pressed.
- A **Rolly Prompt Bar** shows a prompt per entry of **Set Prompts** (an Id, a gamepad key, a keyboard key, a label, and whether it is available; an empty label hides the prompt, an unavailable one dims) with the key of the device the player uses, and **On Prompt Clicked** gives the Id of a prompt the player clicks or taps.

## Show dialogs and toasts

- **Show Rolly Dialog** (a latent node with Confirmed and Cancelled pins) or the stack's **Show Dialog** shows a title, a message, a confirm and a cancel button (or only confirm; their texts and looks are yours to set), with the safe answer focused unless you ask otherwise, and an optional countdown that answers by itself in real time with a shrinking bar. Back, and a dialog closed from outside (a map change), answer Cancelled. On a dialog: **Answer**, **Get Seconds Remaining** and the event **On Dialog Result**.
- **Show Rolly Toast** (a message and a kind: Info, Success or Warning) shows a short message at the top right of the player's part of the screen that does not take focus or stop the player: newest on top, three at most, for at least the theme's Toast Seconds (6) and longer for longer text. Toasts keep off an open screen's header and its card: where one reaches into that corner, they sit at the top centre of the part of the screen beside it (narrower when that part is), or just below the header when nothing beside it is 240 wide.

## Ask with panels and dialogs

Three screen classes ask more than Show Rolly Dialog does. They are set up and answer in C++ only (`Setup`, the name check, `OnChosen`, `OnConfirmed` have no Blueprint nodes); a Blueprint game asks with Show Rolly Dialog. Create one with the stack's `CreateScreen`, set it up, then open it with `PushCreatedScreen`. Each is a panel over the screen below, which stays visible and dimmed.

- **Panels** (`URollySaveCoreUIPanelScreen`): derive from it for a panel of your own, with a title and a message (`SetTexts`) and your parts added in `BuildContent`; a list added with a filling slot scrolls inside the panel. The panel takes the theme's Dialog Width (640 units), or 720 for a question with three answers side by side, never wider than the area less 48 units (24 on short narrow areas); on Tiny areas it fills the area less the tiny margins.
- **Choice dialog** (`URollySaveCoreUIChoiceDialog`): `Setup` with a title, a message and the answers (`FRollySaveCoreUIChoice`: an Id, a label, a button look and an optional icon), in a row or in a column (a list of actions on a row), the Id that Back answers and the answer focus opens on. Three answers in a row take the wider panel, wider still when their words need it, so they stay on one line. `OnChosen` fires once with the answer, after the dialog left the stack; a close from outside (a map change) answers the Back answer.
- **Name dialog** (`URollySaveCoreUINameDialog`): `Setup` with a title, the text it starts with, the confirm button's words, the longest text in characters (at least 1; an emoji counts as one), a check that returns what is wrong with a text, and where it opens (`ERollySaveCoreUINameStart`). `SetFieldName` names the field ("Title").
  - A keyboard player types into the field with the text selected; a pad or touch player types on the on-screen keyboard, which capitalizes the first letter and each one after a space. In languages typed without keys (Chinese, Japanese, Korean) a pad player sees "Connect a keyboard to type." instead.
  - The check's message shows under the field as the player types and dims the confirm button; pressing it then plays the Error sound and narration says the message. Brackets, quotes and control characters never type.
  - Enter, the keyboard's Done key (the menu button on a pad) and the confirm button confirm (`OnConfirmed` with the text, trimmed); Escape and B cancel (`OnCancelled`).
  - **Keyboard** opens typing. **Confirm** opens on the confirm button with the text offered, so Accept keeps it at once; Up goes to the field (a keyboard player types over the text, a pad player's Accept brings the keyboard), and Back while typing goes back to the confirm button with the text kept.

```cpp
#include "Screens/RollySaveCoreUINameDialog.h"
#include "Stack/RollySaveCoreUIStackSubsystem.h"

URollySaveCoreUIStackSubsystem* Stack = URollySaveCoreUIStackSubsystem::Get(LocalPlayer);
if (URollySaveCoreUINameDialog* Dialog = Stack != nullptr ? Cast<URollySaveCoreUINameDialog>(Stack->CreateScreen(URollySaveCoreUINameDialog::StaticClass())) : nullptr)
{
	Dialog->Setup(NSLOCTEXT("MyGame", "RenameTitle", "Rename Save"), CurrentTitle, NSLOCTEXT("MyGame", "Rename", "Rename"), 32,
		[](const FString& Text) { return Text.IsEmpty() ? NSLOCTEXT("MyGame", "TypeTitle", "Type a title.") : FText::GetEmpty(); },
		ERollySaveCoreUINameStart::Confirm);
	Dialog->OnConfirmed().AddLambda([](const FString& Title) { /* rename the save */ });
	Stack->PushCreatedScreen(*Dialog);
}
```

## Draw over every player's view

A widget that belongs to the whole game rather than one player (a saving indicator, a loading overlay) goes on `FRollySaveCoreUIViewportLayer`: `Add(Widget, Offset)` shows it over every player's screens (Offset above Project Settings > Rolly Save Core UI > **Viewport Z Order**), `AddAtZOrder` at a Z order of your own, and it stays across map changes until `Remove`. `Add` returns false while there is no game viewport yet. A widget that draws itself inside the title-safe area gets the insets every Safe Zone pads by from `FRollySaveCoreUISafeArea::GetInsets`.

## Choose where screens show

With Project Settings > Plugins > **Rolly Save Core UI** > **Screen Layer** set to Player (the default), each player's host (the widget that holds the player's screens) goes into the player's part of the viewport, split-screen aware. A HUD your game adds with Add to Viewport draws above it, so pick **Viewport** (the whole viewport at **Viewport Z Order**) for a single-player game with such a HUD, or place the screens in a panel of your HUD:

### Blueprint

Call **Set Host Panel** on the player's stack with an Overlay of your HUD; None goes back to the game viewport. Every Rolly product can share that panel.

### C++

```cpp
if (URollySaveCoreUIStackSubsystem* Stack = URollySaveCoreUIStackSubsystem::Get(LocalPlayer))
{
	Stack->SetHostPanel(MyHud->ScreensOverlay); // null goes back to the game viewport
}
```

For a layer system of your own, such as Common UI, see [Host screens in Common UI or your own layers](https://rolly-docs.pages.dev/save/guides/hosting-screens/).

A screen that must come before everything the game shows (a first-start setup, a question at boot) ticks **Show Above Game Widgets** in its class defaults. While it is open, the player's screens sit above every widget the game adds to the viewport, at Project Settings > Plugins > Rolly Save Core UI > **Above Game Z Order** (10000), still in the player's part of the screen and with the stack's focus, input and pause handling; when it closes they go back to the Screen Layer, keeping their state. A host panel of your own (Set Host Panel) decides by itself and ignores it.

## Read what the screens do to the game

The game instance's **Rolly Save Core UI Shared Subsystem** tells whether screens pause the game (**Is Paused By Screens**), take every player's input (**Is Game Input Blocked By Screens**) or are open at all (**Are Rolly Screens Open**, which the other Rolly products ask to share the game's input).
