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

# Messages Language Mapping

> MessagesLanguageMapping_<lang>.json in languages/ - format, codes, and how other mods set player language via the API.

# Messages Language Mapping

**Folder:** `mods/Zuxaw_RPGLeveling/languages/`
**Files:** `MessagesLanguageMapping_<lang>.json` (e.g. `MessagesLanguageMapping_english.json`)

Each language is **one file** in the `languages/` folder. This page describes the file format. For the high-level system, the in-game picker, and how to ship a translation, see the [Translation System](translation) guide.

> **Migration from older versions** - A single `mods/Zuxaw_RPGLeveling/MessagesLanguageMapping.json` was used before. On first start after upgrading, that file is moved into the new `languages/` folder. If it is not English, rename it with the correct suffix (example: `MessagesLanguageMapping_french.json`) and set `language.display_name`, otherwise it will appear as English in the picker.

***

## Overview

Each file contains all translatable text strings for one language and includes messages for:

* **Stat names and descriptions** - Health, Stamina, Damage, Defense, etc.
* **HUD messages** - Level, XP progress, zone names
* **GUI labels and buttons** - Stat allocation, navigation, confirmations
* **Error messages** - Invalid commands, permission errors
* **Notification messages** - Level up, stat allocation, system messages
* **Command descriptions and responses** - Help text, feedback messages
* **Self-localizing display name** - `language.display_name` shown in the **Settings → Language** picker

***

## Translation Support

Each player picks their own language at runtime; the server-wide fallback is `LevelingConfig.DefaultLanguage` in `RPGLevelingConfig.json` (default `"english"`). New player-facing keys land in English first; missing keys in a translated file fall back to English then to in-code defaults so the GUI never shows a raw key.

### Adding a language

Drop **`MessagesLanguageMapping_<your_code>.json`** in `languages/` (e.g. `MessagesLanguageMapping_french.json`), set `language.display_name` inside it, and restart or `/lvl reload`. The picker will list it automatically.

### Common language codes

Any lowercase code works - pick something simple and stable:

* `english` (always present)
* `french`, `spanish`, `german`, `portuguese`, `russian`, `japanese`, `chinese`, ...
* Short codes like `de`, `es`, `pt_br`, `zh_cn` are also fine.

### Setting language from another server mod

Other plugins can assign the same language codes at runtime (for quests, portals, region scripts, etc.). The public API accepts an online player id, an online player reference, or a character name (online first, then offline profile when available); clearing uses an empty value so **`DefaultLanguage`** applies. Full method list and Java examples are on the [API](api) page under **Player language**.

***

## File Structure

Each language file is organized into logical sections, including a `language` block that describes the file itself:

```json theme={null}
{
  "_version": "1.0",
  "language": {
    "display_name": "English"
  },
  "stats": {
    "names": { "health": "Health", "stamina": "Stamina", ... },
    "descriptions": { "health": "Increases maximum health", ... }
  },
  "hud": {
    "level_xp_progress": "Level: {0} XP: {1} / {2}",
    "level_max": "Level: {0} XP: {1} (MAX)"
  },
  "gui": {
    "navigation": { "stats": "STATS MANAGEMENT", "settings": "SETTINGS" },
    "buttons": { "save": "Save", "cancel": "Cancel" },
    "labels": { "level": "Level", "available_points": "Available Stat Points: {0}" },
    "settings": { ... }
  },
  "notifications": { "level_up_title": "LEVEL UP!", ... },
  "errors": { "invalid_stat": "Invalid stat: {0}", ... },
  "commands": { "info": { "header": "=== RPG Leveling Information ===" } }
}
```

### `language.display_name`

This is the **only** place a language declares its human-readable name. The in-game picker reads it directly from each detected file, so adding a language is a pure file-drop with no central table to update.

```json theme={null}
"language": {
  "display_name": "Français"
}
```

If `display_name` is missing, the picker falls back to a capitalized version of the code (`french` → `French`).

***

## Common Message Keys

### Stat Names (`stats.names`)

```json theme={null}
{
  "stats": {
    "names": {
      "health": "Health",
      "stamina": "Stamina",
      "mana": "Mana",
      "damage": "Damage",
      "defense": "Defense",
      "mining": "Mining",
      "woodcutting": "Woodcutting",
      "harvest": "Harvest"
    }
  }
}
```

### Stat Descriptions (`stats.descriptions`)

```json theme={null}
{
  "stats": {
    "descriptions": {
      "health": "Increases maximum health",
      "stamina": "Increases maximum stamina",
      "damage": "Increases damage to NPCs",
      "defense": "Reduces damage taken (%, max 80%)",
      "mining": "Increases damage to stone/ore blocks",
      "woodcutting": "Increases damage to wood blocks",
      "harvest": "Chance to double or triple crop yield on harvest"
    }
  }
}
```

### HUD Messages (`hud`)

```json theme={null}
{
  "hud": {
    "level_xp_progress": "Level: {0} XP: {1} / {2}",
    "level_max": "Level: {0} XP: {1} (MAX)"
  }
}
```

### Stats GUI - Settings tab (`gui` tree)

These keys live under the merged **`gui`** object in `MessagesLanguageMapping_<lang>.json` (same nesting as other GUI strings the plugin writes). Defaults are defined in **`MessageService.createDefaultMessages()`**. Custom `.ui` layouts should leave translatable **`Text`** empty and set strings from Java (see **`StatsGUIPage.appendSettingsTabUi`**).

| Key                                      | Purpose                                                                         |
| ---------------------------------------- | ------------------------------------------------------------------------------- |
| `gui.navigation.settings`                | Sidebar tab label (e.g. **SETTINGS**)                                           |
| `gui.settings.title`                     | Settings page heading                                                           |
| `gui.settings.level_hud_section`         | Section title for level HUD options                                             |
| `gui.settings.level_hud_description`     | Short explanation for players                                                   |
| `gui.settings.server_hud_disabled`       | Shown when **`EnableHUD`** is off server-wide                                   |
| `gui.settings.show_level_hud`            | Button to show the level progress HUD                                           |
| `gui.settings.hide_level_hud`            | Button to hide the level progress HUD                                           |
| `gui.settings.notif_section_title`       | Settings heading for toast/title preferences (only if **`EnableNotification`**) |
| `gui.settings.notif_section_intro`       | Short intro for that block                                                      |
| `gui.settings.notif_xp_title`            | XP / progression subgroup title                                                 |
| `gui.settings.notif_xp_description`      | What XP/progression toasts include                                              |
| `gui.settings.notif_passive_title`       | Passive subgroup title (only if **`EnablePassiveNotifications`**)               |
| `gui.settings.notif_passive_description` | What passive popups include                                                     |
| `gui.settings.show_notifications`        | Generic “Show” for notification rows                                            |
| `gui.settings.hide_notifications`        | Generic “Hide” for notification rows                                            |

**Player data keys** (in `PlayerLevelData`, persisted): `HideXpProgressNotifications`, `HidePassiveNotifications`, `Language`.

### Stats GUI - Language section keys

The Settings → Language section uses keys nested under **`gui.settings.language`** (defaults in `MessageService.createDefaultMessages()`):

| Key                                    | Purpose                                                                                                                                        |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `gui.settings.language.title`          | Section title (default **Language**)                                                                                                           |
| `gui.settings.language.description`    | Short explanation under the title                                                                                                              |
| `gui.settings.language.current`        | Label that shows the active language (e.g. `Current language: {0}`)                                                                            |
| `gui.settings.language.server_default` | Label for the server-default fallback option (e.g. `Use server default ({0})`)                                                                 |
| `gui.settings.language.active_suffix`  | Suffix appended next to the active row (e.g. ` (active)`)                                                                                      |
| `gui.settings.language.switch`         | Label on the row button used to pick another language (default **Switch**)                                                                     |
| `notifications.language_changed`       | Toast shown after switching language (e.g. `Language set to {0}.`)                                                                             |
| `language.display_name`                | **Top-level** key in each file - name of *this* language as it appears in the picker (e.g. `Français`, `Deutsch`). Each file declares its own. |

### Notifications (`notifications`)

```json theme={null}
{
  "notifications": {
    "level_up_title": "LEVEL UP!",
    "stat_points_earned": "{0} stat point(s) earned{1}",
    "entity_killed": "You killed: {0}",
    "creature_tamed": "You tamed: {0}",
    "harvest_double_yield": "Double harvest!",
    "harvest_triple_yield": "Triple harvest!",
    "max_level_reached": "You have reached the maximum level!"
  }
}
```

### Errors (`errors`)

```json theme={null}
{
  "errors": {
    "invalid_stat": "Invalid stat: {0}",
    "not_enough_points": "Not enough stat points!"
  }
}
```

### Command Messages (`commands`)

```json theme={null}
{
  "commands": {
    "info": { "header": "=== RPG Leveling Information ===" },
    "setlevel": { "success": "Set {0}'s level to {1}" }
  }
}
```

***

## Example Translation (French)

A partial `MessagesLanguageMapping_french.json`:

```json theme={null}
{
  "_version": "1.0",
  "language": {
    "display_name": "Français"
  },
  "stats": {
    "names": {
      "health": "Santé",
      "stamina": "Endurance",
      "damage": "Dégâts",
      "defense": "Défense"
    }
  },
  "hud": {
    "level_xp_progress": "Niveau : {0} XP : {1} / {2}",
    "level_max": "Niveau : {0} XP : {1} (MAX)"
  },
  "notifications": {
    "level_up_title": "NIVEAU SUPÉRIEUR !",
    "stat_points_earned": "{0} point(s) de stats gagné(s){1}"
  }
}
```

> Drop this file in `languages/`, restart or `/lvl reload`, and "Français" appears in the Settings → Language picker.

***

## Placeholders

Messages use **`MessageFormat`-style** placeholders - `{0}`, `{1}`, `{2}` etc., where `{0}` is the first argument passed by the plugin, `{1}` the second, and so on. The order of arguments is fixed by the plugin code; you can move placeholders around in your sentence as long as `{0}` still represents the first argument.

| Placeholder | Typical role (depends on key)                         |
| ----------- | ----------------------------------------------------- |
| `{0}`       | First dynamic value (player name, level, points, ...) |
| `{1}`       | Second dynamic value (XP, target stat, ...)           |
| `{2}`       | Third dynamic value (XP needed, max level, ...)       |

Example:

```json theme={null}
"hud": {
  "level_xp_progress": "Level: {0} XP: {1} / {2}"
}
```

The plugin calls this with `(level, currentXP, neededXP)`, so:

* `{0}` → level
* `{1}` → currentXP
* `{2}` → neededXP

> Numeric formatting (`+1`, `50%`, `1250 / 2000`) stays universal and is built in code - you translate the surrounding label, not the number itself.

***

## Creating a Translation

To create a full translation:

1. Start the server once so `languages/MessagesLanguageMapping_english.json` exists.
2. Copy that file to `languages/MessagesLanguageMapping_<your_code>.json`.
3. Set `language.display_name` to your language's native name.
4. Translate every string **value** (never the keys).
5. Keep `{0}`, `{1}`, ... placeholders intact.
6. Restart or `/lvl reload`, switch to your language in **Settings → Language**, and verify the HUD, GUI, commands, and notifications.

See the [Translation System](translation) guide for the full workflow.

***

## Formatting Tips

* **Keep placeholders intact** - `{0}`, `{1}`, ... must stay; only their position in the sentence may change.
* **Maintain similar length** - long translations may overflow the HUD or toast titles.
* **Consistent terminology** - use the same word for "level", "stat", etc. throughout.
* **Test thoroughly** - HUD, GUI, `/lvl info`, level-up titles, kill messages, zone warnings.

***

## File location and reload

* **Folder:** `mods/Zuxaw_RPGLeveling/languages/`
* **File pattern:** `MessagesLanguageMapping_<lang>.json`
* **Default fallback:** Set in `RPGLevelingConfig.json` → `DefaultLanguage` (default `"english"`).
* **Apply changes without restarting:** **[/lvl reload](commands#lvl-reload)** (`rpgleveling.command.reload`). See [Configuration Overview](config-overview#reloading-config).

***

## See Also

* [Translation System](translation) - How players pick a language and how the per-player system works
* [Configuration Overview](config-overview) - All config files
* [Features](features) - List of all stats and features to translate
