Internationalization
Generally it's a good idea to support translations in your plugin, especially if you want to appeal to the largest user base. Adventure makes this simple by adding a server-side translation layer to almost all text that ends up being displayed to clients.
Adventure's Javadocs for all-things translations can be found here.
GlobalTranslator
All translation is done through GlobalTranslator
.
You can render translations yourself and add new sources for translations.
You can add sources to the GlobalTranslator
by creating instances of TranslationRegistry
or implementing the Translator
interface yourself.
Where translations work
Vanilla Minecraft handles translations on the client by using the language files bundled with the client or provided via resource packs. If you don't want to send custom language files
in a resource pack, server-side translations are the only alternative. They work anywhere the component API exists, except for ItemStack
display text like the display name or lore. So chat, entity display names, scoreboards, tab lists, etc., all support translations.
The player's language as declared in the settings packet sent by the client arrives after the player has joined the server, so there are no guarantees that
translations will work for a client that is joining during the PlayerJoinEvent
or any earlier event.
You can listen for the first PlayerClientOptionsChangeEvent
after joining to know with 100% certainty what language the client that joined is using.
Examples
ResourceBundle
some.translation.key=Translated Message: {0}
TranslationRegistry registry = TranslationRegistry.create(Key.key("namespace:value"));
ResourceBundle bundle = ResourceBundle.getBundle("your.plugin.Bundle", Locale.US, UTF8ResourceBundleControl.get());
registry.registerAll(Locale.US, bundle, true);
GlobalTranslator.translator().addSource(registry);
This creates a new TranslationRegistry
under a specified namespace. Then, a ResourceBundle
is created from a bundle located on the classpath with the specified Locale
.
Finally, that ResourceBundle
is added to the registry. That registry is then added as a source to the GlobalTranslator
.
This makes all the translations available server-side.
Now you can use translation keys in translatable components.
final Component message = Component.translatable("some.translation.key", Component.text("The Argument"))
This will show to clients using the US English language: Translated Message: The Argument
.