Use Internationalization (I18n)¶
Internationalization (often abbreviated as "i18n" because there are 18 letters between "i" and "n") is the process of designing software so it can be adapted to various languages without engineering changes. Allay provides a powerful i18n system that allows plugins to support multiple languages easily.
How I18n Works in Allay¶
Allay's i18n system uses translation keys to represent translatable text. A translation key follows the format:
For example:
- minecraft:commands.generic.syntax - A vanilla Minecraft translation key
- allay:command.gc.completed - An Allay server translation key
- myplugin:greeting.welcome - A custom plugin translation key
When you use a translation key, the i18n system looks up the corresponding text in the language file based on the current language setting.
Using the I18n API¶
Basic Translation¶
To translate a text that contains a translation key, use the I18n.get().tr() method:
Translate with Specific Language¶
You can also specify a language code to translate to:
Available Language Codes¶
Allay supports the following language codes:
| Code | Language |
|---|---|
| en_US | English (United States) |
| en_GB | English (United Kingdom) |
| zh_CN | Chinese (Simplified) |
| zh_TW | Chinese (Traditional) |
| ja_JP | Japanese |
| ko_KR | Korean |
| de_DE | German |
| fr_FR | French (France) |
| fr_CA | French (Canada) |
| es_ES | Spanish (Spain) |
| es_MX | Spanish (Mexico) |
| it_IT | Italian |
| pt_BR | Portuguese (Brazil) |
| pt_PT | Portuguese (Portugal) |
| ru_RU | Russian |
| pl_PL | Polish |
| nl_NL | Dutch |
| tr_TR | Turkish |
| ... and more |
Add Language Files to Your Plugin¶
To add i18n support to your plugin, you need to create language files in the correct location.
File Structure¶
Place your language files in the assets/lang/ directory inside your plugin JAR:
your-plugin.jar
├── plugin.json
├── assets/
│ └── lang/
│ ├── en_US.json
│ ├── zh_CN.json
│ ├── ja_JP.json
│ └── ... (other languages)
└── your/plugin/classes/
Language File Format¶
Each language file is a JSON file with translation keys and their corresponding translations:
{
"myplugin:greeting.welcome": "Welcome to our server!",
"myplugin:greeting.hello": "Hello, %1!",
"myplugin:command.mycommand.description": "This is my custom command",
"myplugin:command.mycommand.success": "Command executed successfully for %1",
"myplugin:error.notfound": "Could not find %1 in %2"
}
{
"myplugin:greeting.welcome": "欢迎来到我们的服务器!",
"myplugin:greeting.hello": "你好,%1!",
"myplugin:command.mycommand.description": "这是我的自定义命令",
"myplugin:command.mycommand.success": "成功为 %1 执行命令",
"myplugin:error.notfound": "无法在 %2 中找到 %1"
}
Parameter Placeholders¶
You can use placeholders in your translations:
| Placeholder | Description |
|---|---|
%1, %2, %3, ... |
Ordered parameters (recommended) |
%s |
Unordered string parameter |
%d |
Unordered integer parameter |
Example:
// Result: "Steve traded 5 items with Alex for 10 emeralds"
I18n.get().tr("myplugin:message.trade", "Steve", 5, "Alex", 10);
Using I18n in Commands¶
You can use translation keys in command descriptions and output messages:
Send Translatable Messages to Players¶
When sending messages to players, you can use sendTranslatable() to send translatable messages:
Fallback Language¶
If a translation key is not found in the specified language, the system will fall back to en_US (English).
This means you should always provide at least an en_US.json file with all your translation keys.
Best Practices¶
-
Use a consistent namespace: Always prefix your translation keys with your plugin name (e.g.,
myplugin:category.key) -
Organize keys hierarchically: Use dots to organize keys into logical groups (e.g.,
myplugin:command.mycommand.description) -
Always provide English translations: Include
en_US.jsonas the fallback language -
Use ordered parameters: Prefer
%1,%2over%s,%dfor better readability and flexibility across languages (word order may differ) -
Keep translations concise: Especially for in-game messages that appear in limited space
Example: Complete Plugin with I18n¶
Here's a complete example of a plugin with i18n support:
plugin.json:
assets/lang/en_US.json:
{
"myplugin:greeting.welcome": "Welcome to the server, %1!",
"myplugin:greeting.goodbye": "Goodbye, %1! See you next time!",
"myplugin:command.greet.description": "Greet a player"
}
assets/lang/zh_CN.json:
{
"myplugin:greeting.welcome": "欢迎来到服务器,%1!",
"myplugin:greeting.goodbye": "再见,%1!下次再见!",
"myplugin:command.greet.description": "向玩家问好"
}
MyPlugin.java: