# Menu narration

> Every Rolly screen can speak what has focus, through the player's screen reader, a Windows voice, Epic's speech plugin or a voice of your game, and your own...

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

## What players hear

With **Menu Narration** on (a product's accessibility setting, or the console variable `rolly.ui.narration 1`), Rolly screens read:

- a screen's title, its category and the focused row when it opens, then each element focus moves to: name, kind ("switch", "slider", "tab"), value, state ("unavailable", "changed", "restart needed"), caption and place ("2 of 7"); a section heading as focus enters its section;
- a value once it rests (a held slider speaks once, 250 ms after it stops);
- dialogs with their message and countdown, toasts, notices and confirmations ("Changes reverted.");
- the controls once per screen ("A button, Apply."), again after the player changes device.

Detail **Brief** (`rolly.ui.narration.detail 1`) reads names and values only. With two or more local players, a line starts with "Player 2." where it opens a screen, a dialog or a toast.

| Repeat what has focus, or stop the voice | Gamepad | Keyboard | Mouse | Touch |
|---|---|---|---|---|
| | left stick button | Ctrl+Space; Ctrl alone stops | middle button | two-finger tap |

## The voice

`rolly.ui.narration.voice` picks it; Auto takes the first that works:

1. **Screen Reader:** while a screen reader runs (Narrator, NVDA, JAWS), lines go to it as announcements. Its own rate and volume apply.
2. **Windows voices** (`Windows:<voice id>`): the system's voices, played through the game's audio, in the language of the line where a voice of it exists. `rolly.ui.narration.rate` (0.5 to 3) and `rolly.ui.narration.volume` apply.
3. **Engine** speech: Epic's Text To Speech plugin, when your project enables it. Rolly needs no dependency on it.
4. **Game:** a voice of your game. Make a Blueprint subclass of **Rolly Save Core UI Narration Provider**, implement **Speak**, **Stop**, **Is Speaking** and **Is Available**, and name it in Project Settings > Plugins > **Rolly Save Core UI** > **Narration Provider Class**.

The narration choices are shared by every Rolly product a project installs: a player who turns narration on in one product's settings hears every Rolly screen.

## Speak from your game

**Speak Rolly Narration** (the game instance's **Rolly Save Core UI Narration Subsystem**) says a line with a class: Interrupt (stops what speaks), Notice (before queued lines; dropped after 15 s), Queue, or Low (only after 2 s of quiet). **Stop Rolly Narration** stops the voice. Lines speak only while narration is on.

## Make your widgets speak

Widgets derived from `URollySaveCoreUIUserWidget` answer narration through `DescribeForNarration`: the default reads the parts named `NameText`, `TitleText` and `ValueText`, else the widget's Accessible Text. Override it to give the role, value and states:

```cpp
void UMyStatRow::DescribeForNarration(FRollySaveCoreUINarrationItem& OutItem) const
{
	OutItem.Name = StatName;
	OutItem.Role = ERollySaveCoreUINarrationRole::Slider;
	OutItem.Value = FText::AsNumber(Points);
	if (!bUnlocked)
	{
		OutItem.States.Add(FRollySaveCoreUINarrationPhrases::MakeUnavailable(LockedReason));
	}
}
```

A screen derived from `URollySaveCoreUIScreen` reads its title and focused element when it opens; override `NarrateOpened`, `DescribeFocusedItem` or `GetNarrationTitle` for more. A dialog written in two languages overrides `AdjustNarrationLine` to give its countdown lines and the button the player moves to the culture they are written in, so a voice of that language reads them.

## Limits

- Narration reads Rolly screens only; screens of other UI systems keep their own.
- While narration speaks through the screen reader, the Rolly screens are hidden from that screen reader's own reading of the interface, so each element is spoken once. With another voice the screen reader reads the screens as usual.
