Multilanguage is the translation system almost every other Eternal Empires plugin is built on top of. Instead of hardcoding message strings, plugins register translation keys and get back Adventure Components in whatever language the receiving player has selected — English, German, whatever else the server supports.
Each player has a selected Language, identified by a BCP-47 code (en-US, de-DE, ...). LanguageProvider.getLanguageByPlayer(uuid) resolves that, and Language.getTranslation(key) returns a Translation for that key in the player's language, falling back to the key itself if no translation exists so a missing string never crashes a plugin, it just looks obviously wrong. A Translation supports placeholder replacement (.replace("{player}", name)) and converts to Adventure Components (asComponent(), asList(), asArray()) for sending as chat messages, so this is the thing basically every plugin's command output goes through.
Plugins register their own translation keys, descriptions, and placeholders through TranslationInfo — this is what lets Multilanguage know a key like economy.message.pay.sent belongs to the economy plugin, what placeholders it expects ({player}, {amount}), and what it's for, which in turn is what makes it possible to generate a translation reference or a translator-facing UI without reading every plugin's source.
LanguageProvider is the entry point for resolving languages — by player, by BCP-47 code, or the server's configured default. Everything you get back is a Language, and Language.getTranslation(key) is how you actually get message text out of it. If you're adding new user-facing messages to a plugin, register them as TranslationInfo so translators know they exist and what placeholders to fill in — see the multilanguage.json resource file convention used by other Eternal Empires plugins (e.g. economy's paper/src/main/resources/multilanguage.json) for the format Multilanguage picks up automatically.
api— the platform-independent public interfaces (Language,LanguageProvider,Translation,TranslationInfo,Placeholder).api/paperaddsPaperTranslation, a Paper-specific helper for translations. No implementation, published for other plugins to depend on.common— the MongoDB-backed implementation via Morphia, including translation storage and lookup.paper— the Paper platform module.velocity— the Velocity platform module, so translations are consistent across the proxy and backend servers.
Java 21, and either Paper 1.21+ or Velocity depending on which module you run, plus a MongoDB instance. Multilanguage depends on boilerplate being installed and loaded before it.
./gradlew buildTo get a plugin jar, build the platform module's shadow jar, e.g.:
./gradlew paper:shadowJarThe resulting jar is written to paper/build/libs/ (or velocity/build/libs/).
On first run, database.yml is generated, configuring the MongoDB connection used to store languages and translations:
host: localhost
port: 27017
database: multilanguage
username: admin
password: 'my-password' # leave blank if your MongoDB has no auth configuredIf your plugin sends any message to a player, depend on multilanguage-api (and multilanguage-api-paper if you're on Paper and want the PaperTranslation helper) instead of hardcoding strings:
repositories {
maven {
url 'https://packages.eternalempires.net'
}
}
dependencies {
compileOnly 'net.eternalempires:multilanguage-api:VERSION'
compileOnly 'net.eternalempires:multilanguage-api-paper:VERSION'
}Replace VERSION with the release you want to target — see the Releases page for available versions.
See LICENSE.
See CONTRIBUTING.md.