> ## 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.

# Translation System

> How to translate the RPG Leveling plugin and how the per-player language system works.

# Translation System

The RPG Leveling plugin supports **full localization** with **per-player languages**. Each player picks their own language from the in-game **Settings** tab and the HUD, notifications, level-up titles, zone warnings, kill messages and `/lvl info` follow that choice. Server-side messages (logs, console output, broadcasts without a specific recipient) use the **server default language**.

***

## How it works

### The `languages/` folder

All translation files live in:

```
mods/Zuxaw_RPGLeveling/languages/
```

Each language is one file named:

```
MessagesLanguageMapping_<lang>.json
```

`<lang>` is a lowercase identifier (no spaces) - for example `english`, `french`, `spanish`, `de`, `pt_br`. The exact code is what players store on their character; pick something simple and stable.

Examples:

```
mods/Zuxaw_RPGLeveling/languages/
├── MessagesLanguageMapping_english.json   ← always created by the plugin
├── MessagesLanguageMapping_french.json
└── MessagesLanguageMapping_spanish.json
```

> **Migration from older versions** - If you upgrade from a version that used `mods/Zuxaw_RPGLeveling/MessagesLanguageMapping.json` (single-file translation), the file is moved automatically into `languages/` on first start. If your old file is not English, rename it to the correct suffix (example: `MessagesLanguageMapping_french.json`) and set `language.display_name` (example: `Français`), otherwise it will appear as English in the in-game picker.

### Auto-discovery

On startup the plugin scans `languages/` for any file matching `MessagesLanguageMapping_*.json` and loads it. There is no central registry to edit - drop a file in, restart, and the language appears in the in-game picker.

If `MessagesLanguageMapping_english.json` is missing, the plugin **creates it from the in-code defaults** so English is always available as a fallback.

### Self-localizing display names

Each bundle declares its own display name under the `language` section:

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

The in-game **Settings → Language** list reads `language.display_name` for each detected file. There is no central translation table to keep in sync - the file describes itself.

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

### Keeping translations up to date

Every time the server starts (and on `/lvl reload`), language files are updated to include new text entries added by plugin updates while keeping your existing translated text:

* **New entries** are added with English text as placeholders.
* **Old unused entries** are removed.
* **Your translated lines** stay untouched.
* **A short per-file report** is printed in console.

This keeps each language file clean and easy to maintain after updates.

### Player-aware message routing

Every player has a `Language` field on their `PlayerLevelData`. When the plugin needs to display text to a specific player, it resolves the bundle in this order:

1. The player's chosen language (`PlayerLevelData.Language`).
2. The server's `DefaultLanguage` (from `RPGLevelingConfig.json`).
3. `english` (always present).
4. In-code defaults (last-resort fallback so the game never shows a raw key).

This means a missing key in a translation file silently falls through to English instead of breaking the GUI.

### Setting language from another mod

Server mods can change a player’s RPG Leveling language in code using the same bundle codes as in **`languages/`**. See [API - Player language](api#player-language) for dependencies, methods (`setPlayerLanguage`, `setPlayerLanguageByUsername`, etc.), and examples.

### Server default language

The server-wide default lives in `mods/Zuxaw_RPGLeveling/RPGLevelingConfig.json`:

```json theme={null}
{
  "DefaultLanguage": "english"
}
```

It is used for:

* New players who have not opened the picker yet.
* Server console output and log lines.
* Broadcasts that do not target a specific player (e.g. global XP boost titles still use each recipient's own language; only truly recipient-less messages fall back to the default).

Set it to any language code you have in `languages/` (for example `"french"` for a fully French-speaking server).

***

## Picking a language in-game

1. Open the Stats GUI (`/lvl gui`, default key, or **Open RPG GUI** binding).
2. Click the **Settings** tab in the sidebar.
3. Scroll to **Language**.
4. Click **Switch** next to the language you want.

The choice is saved immediately on your character and replicated to the database. The GUI re-renders in the new language and the HUD / next notification follow.

***

## Adding a new translation

1. Make sure the server has been started at least once so `languages/MessagesLanguageMapping_english.json` exists.
2. Copy that file to `languages/MessagesLanguageMapping_<your_lang>.json` (e.g. `MessagesLanguageMapping_french.json`).
3. Open your copy and translate the **values** only - never change the keys.
4. Set `"language"."display_name"` to what should appear in the picker (e.g. `"Français"`).
5. Restart the server (or `/lvl reload`).
6. Open **Settings → Language** in-game; your file should appear in the list.

You do **not** need to touch the English file or any other config - adding a language is a pure file drop.

### What to translate, what to keep

* ✅ Translate the **string values**.
* ❌ **Do not** rename the keys (e.g. `level_up_title`).
* ❌ **Do not** change placeholders like `{0}`, `{1}` - they are replaced with player names, levels, XP values, etc. by the plugin. The order of placeholders must stay the same; you can move them around in the sentence as long as `{0}` still means "first argument".
* ❌ **Do not** translate plugin-internal identifiers (UUIDs, stat keys, brand name "RPG Leveling").

### Length and formatting

* The HUD and toast titles have limited width. If a translation overflows, prefer shorter wording over very long sentences.
* Numeric formatting (`+1`, `50%`, `100/200`, `Level 12`) stays universal and is composed in code, so you usually translate the surrounding label, not the number.

### Testing

After editing a file:

* Run `/lvl reload` to pick up changes without restarting.
* Switch to your language in **Settings → Language**.
* Check: HUD, level-up title, an XP gain toast, the kill message, `/lvl info`, the Stats GUI Settings tab.

***

## Smart merge report (console)

On startup or `/lvl reload`, each language file produces a short report:

```
=============================================================
MESSAGES FILE MERGE REPORT - MessagesLanguageMapping_french.json
=============================================================
✅ Added 2 new message(s) (defaulted to English)
❌ Removed 1 obsolete message(s)
💾 Preserved 374 user translation(s)
=============================================================
```

Use it after each plugin update to spot newly added keys that need translation.

***

## Troubleshooting

**My language file is not in the picker.**

* File name must match `MessagesLanguageMapping_<lowercase_code>.json` exactly.
* It must be inside `mods/Zuxaw_RPGLeveling/languages/` (not in the parent folder).
* Run `/lvl reload` or restart the server; the picker reads the registry on open.

**Some messages are still English.**

* Open your file and search for keys flagged in the merge report - they are probably new and still default to English.
* Missing keys fall back to English by design; this prevents broken GUIs after plugin updates.

**My old `MessagesLanguageMapping.json` disappeared.**

* It was moved to `languages/MessagesLanguageMapping_english.json` by the upgrade migration. Your translations are preserved there.

**Reset a translation file.**

* Delete `languages/MessagesLanguageMapping_<lang>.json` and restart. For English, the plugin recreates it from defaults; for any other language you keep the file you authored.

***

## Translation quality policy

This project does **not** rely on automatic AI translation quality for official language files.

* We prefer translations made and reviewed by real players/community members.
* If you are not sure about a language, leave it in English until a native speaker provides a proper version.

## Sharing translations

If you create a translation, please share it on our [Discord](https://discord.gg/nGDQbjMtxY) - it can be added to the next release as an officially bundled language file.

***

## See also

* [Messages Language Mapping](config-messages) - the file format in detail.
* [Configuration Overview](config-overview) - all config files and `/lvl reload`.
* [Commands](commands) - `/lvl reload` and friends.
