> ## Documentation Index
> Fetch the complete documentation index at: https://docs.marioded.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Style the viewer experience

> Make the viewer experience your own with controls, colors, progress, and messages.

# Style the viewer experience

Change what players see and click during playback: the hotbar controls, the action bar and progress, the sidebar, and all command messages.

| What you want to change | Where to edit |
| - | - |
| Playback items and click actions | `layout.yml` → `playing` |
| Action bar and experience progress | `layout.yml` → `hud` |
| Sidebar | `messages.yml` → `player.scoreboard` |
| Command replies | Role-specific message sections |
| Catalog inventories | [Menu settings](https://docs.marioded.com/owners/menus.md) in `gui.yml` |

After editing, use the role's reload command. Keep a copy of a working layout so you can compare changes.

## MiniMessage

Reverse's configured display text uses MiniMessage:

```yaml theme={null}
name: '<gold><bold>Replay controls'
```

Use tags such as `<yellow>`, `<bold>`, and `<gray>`. `&a`-style legacy color codes are not the intended message syntax. Replay metadata is inserted as literal text; it is not a way to inject formatting into the menu template.

> [!TIP]
>
> **Start small:** change one item name or one HUD line, reload, and check it in a replay. Once that works, customize the rest using the same pattern.

Placeholder names depend on the message or display surface. A command error's `<error>` is not automatically available to every HUD line. Start from the generated message's placeholders when translating it.

## Message structure and defaults

Every role reads `messages.yml`. Player and recorder use `general` and the role section (`player` / `recorder`); lobby message keys are at the root of its file. Comments group help, playback/recording status, catalog actions, input errors, editing and reload feedback. There is no translation registry or additional message nesting.

Defaults use English consistently: aqua for headings/actions, gray for explanations, white for values, green for success, yellow for paused/busy/nonfatal states, and red for errors or destructive actions. Help is split into readable lines; invalid pages, session UUIDs and clip numbers have specific instructions. Technical command failures show a short user message while the details go to the server log.

### Configurable actions

| Setting | Purpose |
| - | - |
| `player.previous-page`, `player.next-page` | Navigation labels, shown only when the page exists. Use paired `<previous_page>` / `<next_page>` action tags. |
| `player.list-item` | Named replay entry. Use `<replay_info>` for UUID hover text and `<watch_action>` / `<prepare_action>` for buttons. |
| `recorder.saved-actions` | Button row appended to saved/clip/degraded replies when a local playback/lobby command exists. |
| `recorder.saved-prepare` | Button row on recorder-only servers; the prepared command is used on the replay server. |
| `recorder.started`, `started-template`, `status-active` | Session feedback. Paired tags `<session_info>`, `<session_status>`, `<session_stop>` provide hover/status/prepare-stop behavior. |

For example, a translated action row can be:

```yaml theme={null}
recorder:
  saved-actions: '<watch_action><green>[Guarda]</watch_action> <prepare_action><aqua>[Prepara comando]</prepare_action>'
  saved-prepare: '<prepare_action><aqua>[Prepara comando]</prepare_action>'
```

Translate the labels, keeping the dynamic action tags. Add standard MiniMessage hover tags for button tooltips, and use native click tags for static commands. Dynamic tags already carry the actual UUID; do not put ordinary text placeholders inside quoted click arguments. Only `run_command` and `suggest_command` are used for compatibility with 1.8.8 clients. Set an action row to `''` to hide the buttons; an empty save reply hides its action row as well.

### Configuration key cleanup

* `reload-failed` replaces `reload-preparation-failure`; unused `reload-restart-required` and `reload-refresh-failure` are removed. Reload failure does not promise that every change was rolled back.
* Unused `player.list-hover`, `player.not-watching`, `player.forward-usage`, `player.backwards-usage`, and `recorder.stopped-hover` are removed. Playback errors use the existing playback messages; skip syntax is explained in the main help.
* `general.command-failed` (player/recorder) and lobby `command-failed` describe unexpected command failures. Lobby has a separate `no-permission` for command permission errors, at the root of its `messages.yml`.
* Player `list-usage` and recorder `clip-usage`, `invalid-clip-number`, `invalid-session`, and `reload-usage` provide focused input help.

New releases supply these as generated defaults. Existing customized values are not replaced automatically: update the relevant text/keys in your current files. Reload applies message edits; startup-only settings still require restart.

## Hotbar configuration

Player's `layout.yml` has `playing` and `hud` sections. Under `playing`, `states` supplies reusable lists of text values and `items` defines the hotbar.

```yaml theme={null}
playing:
  states:
    intervals: ['1.0', '5.0', '10.0', '30.0']
    speeds: ['0.25', '0.5', '1.0', '2.0', '4.0', '8.0']
```

These are string lists. Built-in actions parse the values they own. Use positive finite speeds and nonnegative finite seek values.

Each hotbar item defines `enabled`, `slot` (1–9), a base `appearance`, optional named `states` appearances, and click `bindings`. Slots must be unique among active items.

Example of a fixed seek button under `playing.items`:

```yaml theme={null}
playing:
  items:
    jump_ahead:
      enabled: true
      slot: 8
      appearance:
        material: ARROW
        data: 0
        amount: 1
        name: '<yellow>Forward 10 seconds'
        lore: ['<gray>Left click to jump forward.']
      states: {}
      bindings:
        LEFT:
          action: reverse:seek
          parameters:
            direction: forward
            seconds: '10'
```

Merge this item rather than replacing the other default controls. Slot 8 is unused by the defaults.

## Built-in hotbar actions

| Action | Parameters/behavior |
| - | - |
| `reverse:pause_toggle` | Toggles shared session pause; resuming after the end restarts from tick 0 for all viewers. |
| `reverse:pause` | Pauses the session. |
| `reverse:resume` | Resumes the shared session, or restarts it from tick 0 after the end. |
| `reverse:interval_next` | Cycles the item's selected seek interval. |
| `reverse:interval_previous` | Cycles the interval in the opposite direction. |
| `reverse:speed_increase` | Selects a faster configured speed where available. |
| `reverse:speed_decrease` | Selects a slower configured speed where available. |
| `reverse:speed_set` | `speed`: explicit positive finite speed. |
| `reverse:seek` | `direction`: `forward`/`backwards`; optional `seconds` and `ticks`. Without explicit magnitude, uses the selected interval. |
| `reverse:stop` | Removes/restores only the clicking viewer and attempts their return to the origin lobby if applicable. Other viewers remain; the last departure cleans up the session. |

Hotbar items can show `<seconds>` for the chosen seek interval and `<speed>` for session speed. A `paused` appearance can replace a pause item's normal appearance. Extensions may register more actions; see [UI integrations](https://docs.marioded.com/api/ui-extensions.md).

Natural completion keeps the final scene visible and uses the paused appearance and paused HUD/sidebar text. It does not automatically return viewers to the lobby. The viewer chooses to resume/restart or stop watching.

Existing customized configuration is not overwritten. In `layout.yml`, update `playing.items.pause.states.paused.lore` to explain that resume affects all viewers and restarts after the end. Keep Stop watching text individual in `playing.items.stop.appearance`; the existing `reverse:stop` bindings already use individual exit without changing action IDs. In `messages.yml`, update `player.help` stop/resume descriptions, `player.already-paused` and `player.paused` resume hover text, and `player.stopped` feedback to match these semantics. Reload with `/reverseplayer reload` after editing.

## HUD

```yaml theme={null}
hud:
  action-bar: '<gray><state> <white><time>/<playback_total> <gray><speed>x'
  playing-text: '<green>Playing'
  paused-text: '<yellow>Paused'
  experience-bar: true
```

Set `action-bar: ''` to disable the text. Set `experience-bar: false` to disable the experience progress output. Disabling an already enabled HUD through reload clears its previous output.

## Sidebar

The player's sidebar is under `player.scoreboard` in **`messages.yml`**, not `layout.yml`:

```yaml theme={null}
player:
  scoreboard:
    enabled: true
    title: '<aqua><bold>REPLAY'
    lines:
      - '<gray>Playback: <white><time>/<playback_total>'
      - '<gray>Recorded: <white><duration>'
      - '<gray>Speed: <white><speed>x'
      - '<gray>Status: <state>'
    playing-text: '<green>Playing'
    paused-text: '<yellow>Paused'
```

Set `enabled: false` to remove the sidebar. Empty title/lines are permitted but are not the same as disabling it. Lines beyond the client's supported limit are dropped with a log warning.

## Session placeholders

| Placeholder | Meaning |
| - | - |
| `<speed>` | Session speed multiplier. |
| `<time>` | Current replay timeline time. |
| `<total>`, `<duration>` | Recorded wall-clock duration. |
| `<playback_total>` | Playable timeline extent. |
| `<ticks>` | Current tick. |
| `<total_ticks>` | Timeline tick count including tick 0 and final tick. |
| `<percent>` | Formatted progress percentage. |
| `<state>` | Configured playing/paused text for that surface. |

Use `<playback_total>` beside `<time>` for a meaningful playback progress line. Use `<duration>` when you want to show how long recording lasted in real time.

Time placeholders accept a duration pattern directly, without a separate configuration setting:

```yaml theme={null}
- '<gray>Time: <white><time:mm:ss> / <playback_total:mm:ss>'
- '<gray>Recorded: <white><duration:HH:mm:ss>'
```

Use `H`, `m`, `s` for hours, minutes and seconds; double a token (`HH`, `mm`, `ss`) for a minimum of two digits. `<time:mm:ss>` shows `00:21` at 21 seconds and `62:03` at 3723 seconds. `<time:HH:mm:ss>` shows `01:02:03` at 3723 seconds. Minutes accumulate when hours are omitted; seconds accumulate when both hours and minutes are omitted. Separators may be customized, for example `<time:'mm / ss'>`.

Without an argument, time placeholders use `m:ss`, switching to `H:mm:ss` at one hour. Patterns apply to HUD and scoreboard titles/lines. Existing configurations can opt in by replacing `<time>` with `<time:mm:ss>` and reloading the player.

## Translation and reload

Player and recorder have `general` and role-specific message sections. Lobby has messages inside its main configuration. Keep the existing structure and preserve placeholder names while translating the surrounding text.

Run the role's reload command after editing. Player reload refreshes active session display. Restart is still needed for underlying storage/network/world choices. Other plugins that continuously write the same hotbar, action bar, XP bar, or scoreboard can conflict; test those combinations explicitly.

For the settings that back these changes, see [Configure Reverse](https://docs.marioded.com/owners/configuration.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.