> For the complete documentation index, see [llms.txt](https://esmp-fun.gitbook.io/plugins/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://esmp-fun.gitbook.io/plugins/better-trial-chambers/configuration/localization.md).

# Localization

Every user-visible string in BetterTrialChambers lives in `plugins/BetterTrialChambers/messages.yml` and can be overridden — including the entire admin GUI as of v1.3.0. This page covers how to translate, the key naming conventions, and the placeholder syntax.

{% hint style="info" %}
**TL;DR**: edit `messages.yml`, run `/trial reload`, and you're done. The plugin never overwrites this file once it exists, so your translations survive plugin updates.
{% endhint %}

## File location and reload

* **Path:** `plugins/BetterTrialChambers/messages.yml`
* **Generated on first run** — copy from the bundled defaults, then never touched again.
* **Reload after editing:** `/trial reload` rereads `config.yml`, `loot.yml`, and `messages.yml` together. No restart required.

## Top-level structure

```yaml
prefix: "&8[&6TCP&8]&r "

# Per-feature message keys (chat output, command help, etc.)
chamber-not-found: "&cChamber '{chamber}' not found."
no-permission: "&cYou don't have permission to do that."

# All admin GUI strings live under a single nested gui.* tree.
gui:
  common:
    back-button: "&e« Back to {destination}"
    close-button: "&cClose"
    # ... shared toggle/lore templates ...

  main-menu:
    title: "BetterTrialChambers Admin"
    header-name: "&6&lBetterTrialChambers"
    header-lore:
      - "&7Version &f{version}"
      - ""
      - "&eRegistered Chambers: &f{chambers}"
      - "&eLoot Tables: &f{tables}"
    # ... one section per GUI view ...
```

## Color codes

Use the legacy ampersand format (`&a`, `&l`, `&r`, etc.) — it's converted at runtime to Adventure components. Standard codes:

* `&0`–`&9`, `&a`–`&f` — colors
* `&l` bold, `&n` underline, `&o` italic, `&m` strikethrough, `&k` obfuscated
* `&r` reset all formatting

Section-sign (`§`) escapes also work but ampersand is preferred for editability. Hex colors (`&#RRGGBB`) are *not* currently supported — open an issue if you need them.

{% hint style="info" %}
GUI item names default to **non-italic** even though Minecraft normally italicizes renamed items. This is intentional — every `gui.*` key passes through `TextDecoration.ITALIC=false` so admin tools look clean. If you actually want italic, prepend `&o` to the value.
{% endhint %}

## Placeholders

Messages can include `{placeholder}` tokens that the plugin substitutes at send time:

```yaml
chamber-created: "&aChamber &f{chamber}&a created with volume {volume}."
```

Supplied at the call site by the plugin code:

```kotlin
plugin.getMessage("chamber-created",
    "chamber" to chamber.name,
    "volume" to chamber.getVolume())
```

The placeholders available for each key are listed inline next to the key in the bundled `messages.yml`. Unknown placeholders are left as literal `{token}` text rather than throwing — useful for spotting typos.

### Translatable `{type}` labels *(1.5.19+)*

Some placeholder **values** used to be hardcoded English. The `{type}` label is now itself looked up from messages.yml, so "Normal"/"Ominous"/etc. translate everywhere they appear:

| Key                                                | Default                           | Used in                                                           |
| -------------------------------------------------- | --------------------------------- | ----------------------------------------------------------------- |
| `vault-type-normal` / `vault-type-ominous`         | `Normal` / `Ominous`              | vault messages (open / locked / reopen) **and** `/trial key give` |
| `wave-type-normal` / `wave-type-ominous`           | `Trial` / `Ominous`               | the "{type} Spawner wave complete!" message                       |
| `wave-boss-type-normal` / `wave-boss-type-ominous` | `Trial Spawner` / `Ominous Trial` | the spawner-wave boss-bar progress line                           |

Translate these once and every `{type}` in those messages follows.

## Multi-line lore

GUI lore (and any other list-typed value) is a YAML list:

```yaml
gui:
  main-menu:
    header-lore:
      - "&7Version &f{version}"
      - ""        # blank line in-game
      - "&eRegistered Chambers: &f{chambers}"
```

Each entry becomes one lore line. Blank entries (`""`) render as visual separators. Placeholders work in every line.

## The `gui.*` namespace

All GUI strings live under a single nested `gui:` tree, organized one sub-section per view:

| Section                                                                               | Owns                                                               |
| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| `gui.common`                                                                          | Back/close/prev/next buttons, destination labels, toggle templates |
| `gui.main-menu`                                                                       | Main hub                                                           |
| `gui.chamber-list` / `gui.chamber-detail` / `gui.chamber-settings`                    | Chamber browse + manage                                            |
| `gui.vault-management`                                                                | Vault cooldown management                                          |
| `gui.custom-mob`                                                                      | Per-chamber mob provider config                                    |
| `gui.loot-table-list` / `gui.pool-selector` / `gui.loot-editor` / `gui.amount-editor` | Loot editing flow                                                  |
| `gui.stats-menu` / `gui.leaderboard` / `gui.player-stats`                             | Statistics views                                                   |
| `gui.global-settings` / `gui.protection-menu`                                         | Toggle screens (reachable directly from the main menu)             |
| `gui.help-menu`                                                                       | In-GUI command reference                                           |

Within a section, key suffixes follow a consistent pattern:

* `<thing>-name` — item display name (single string)
* `<thing>-lore` — item lore (list of strings)
* `<thing>-lore-<state>` — state-dependent lore (e.g. `protection-lore-enabled` / `protection-lore-disabled`)
* `empty-name` / `empty-lore` — placeholder when a list/grid view has zero entries
* `title` — `ChestGui` title

Keys under `gui.*` automatically skip the chat prefix — the GUI doesn't want `[BTC]` prepended to every item name.

## Shared toggle templates

Settings views with on/off toggles all use the same shared templates so translators don't have to retranslate "Enabled / Disabled / Click to toggle" for every setting:

```yaml
gui:
  common:
    toggle-name-enabled: "&a&l{label}"
    toggle-name-disabled: "&c&l{label}"
    toggle-lore-enabled:
      - "&7{description}"
      - ""
      - "&aStatus: Enabled"
      - ""
      - "&eClick to toggle"
    toggle-lore-disabled:
      - "&7{description}"
      - ""
      - "&cStatus: Disabled"
      - ""
      - "&eClick to toggle"
```

Each toggle then provides only its own `<setting>-label` and `<setting>-desc`:

```yaml
gui:
  protection-menu:
    block-break-label: "Prevent Block Break"
    block-break-desc: "Stop players from breaking blocks"
```

Translate the templates once, translate per-toggle labels/descs, and the result composes correctly.

## What's translatable

Everything user-visible:

* Chat messages, command output, error messages — as of 1.7.1 this includes every admin command (`/trial dungeon`, `/trial container`, `/trial claims`, `/trial debug`, the reset-confirmation queue, snapshot listings, `/trial list`, loot audit) and the shared `pagination-*` Prev/Next line
* Time durations ("2d 3h 5m", "5m ago") via the `time-*` keys (actually applied since 1.7.1)
* Boss bar text on trial spawner waves
* Every name, lore line, and button label in the admin GUI
* `/trial help` and `/trial info` output
* Tab-completer suggestions are not translated (those are internal command tokens, not display text)

Logger output (server console) is intentionally English — those messages are read by server admins and bug reports, not players, and consistency makes triage easier.

## Reset to defaults

The plugin doesn't ship a `/trial reset-messages` command. To restore the bundled defaults: rename or delete `messages.yml` and run `/trial reload` — a fresh copy will be written from the JAR.

## Reporting translation issues

If a placeholder is missing, a key is missing from the bundled defaults, or a string can't be sensibly translated due to baked-in word order, [open an issue](https://github.com/ESMP-FUN/BetterTrialChambers/issues). Translation contributions are welcome.
