> For the complete documentation index, see [llms.txt](https://edseries-plugins.gitbook.io/p/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://edseries-plugins.gitbook.io/p/edlang/features/chat-translation.md).

# Chat translation

Optional: what players type in chat is translated into each reader's language. Off until you set it up.

* The sender and players who share the sender's language see the message at once.
* Players in other languages get it in their language as soon as it is translated (usually well under a second), with the original on hover.
* Each message is translated once into every language that needs it, and remembered: the same message is never sent to the provider twice.
* Players switch it off for themselves with `/lang chat` or in `/lang settings`.

## Setup

1. Pick a provider and get a key.
2. In config.yml:

```yaml
chat-translation:
  enabled: true
  provider: deepl
  providers:
    deepl:
      key: 'your-key'
```

3. `/edlang reload`, then test it with `/edlang chat test es,de Hello everyone`.

| Provider         | Key                                                                          | Notes                                                                                                                                |
| ---------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `deepl`          | <https://www.deepl.com/pro-api>                                              | The free plan (500,000 characters a month) is enough for most servers. Free keys end in `:fx`; the right URL is picked from the key. |
| `google`         | Google Cloud Translation v2 API key                                          |                                                                                                                                      |
| `libretranslate` | Your own server's URL (and key if it has one)                                | Free if you host it.                                                                                                                 |
| `openai`         | Any OpenAI-compatible chat API: OpenAI, Fireworks, OpenRouter, a local model | Set `url`, `key`, `model`. Writes like a player would, keeps slang and tone. Cost is estimated from `pricing`.                       |

`codes` (per provider) maps your lang codes to the codes the provider wants (`en: EN-US`, `pt: PT-BR` for DeepL). For `openai`, `language-names` gives the model each language's name and `prompt` is its instruction.

Keep keys secret: they are only read from config.yml and never written to logs.

## Modes

* `replace` (default): players in other languages get the message in their language instead, waiting at most `max-wait-ms` for the translation (after that they get it as typed).
* `follow-up`: everyone gets the message at once as typed; the translation follows as an extra line (`edlang.chat.follow-up`).

The translated message's look: `edlang.chat.translated` (`{message}`, `{original}`, `{language}`) and the hover `edlang.chat.hover`.

## Limits and costs

| Option                         |                                                                                      |
| ------------------------------ | ------------------------------------------------------------------------------------ |
| `min-length`, `max-length`     | Messages shorter or longer are shown as typed.                                       |
| `per-player-per-minute`        | Messages per player per minute that get translated (`edlang.chat.nolimit` skips it). |
| `daily-character-limit`        | Translation stops for the day once this many characters were sent.                   |
| `daily-budget-usd`             | `openai`: stops for the day at this estimated cost.                                  |
| `cache-size`                   | Translations remembered.                                                             |
| `max-concurrent`, `timeout-ms` | Requests at once, and how long one may take.                                         |
| `skip-words`                   | Messages made only of these (gg, lol, ok...) are never translated.                   |
| `keep-words`                   | Words kept exactly as typed (server name, ranks, currencies).                        |
| `keep-player-names`            | Online player names kept as typed.                                                   |
| `skip-prefixes`                | Messages starting with these are never translated.                                   |

`/edlang chat stats [days]` shows messages, characters, cache hits, failures, tokens and cost. Usage is saved per day in `data/translation-usage.yml`.

## Compatibility

Works with chat plugins that use Paper's chat renderer (the chat format stays theirs). Plugins that cancel the chat event and send their own messages are left alone. Developers can skip messages or languages with `ChatTranslateEvent` (see the [API](/p/edlang/reference/developer-api.md)).

Messages are sent to the translation provider you choose: say so in your server rules if your players expect it.

## Permissions

| Permission            | Default  |                                    |
| --------------------- | -------- | ---------------------------------- |
| `edlang.chat.receive` | everyone | Gets messages translated.          |
| `edlang.chat.toggle`  | everyone | `/lang chat`, the settings button. |
| `edlang.chat.nolimit` | op       | No per-player limit.               |
