AtlasLang
Multilingual engine used by every Nautic Studios plugin. Stores each player’s language in a database, loads per-language YAML files and exposes the AtlasAPI v2 so any plugin can translate messages without owning the data.
Reads are cached in memory, writes are async — every API method is safe to call from the main thread.
GitHub: nauticstudios/AtlasLang · API source: api/
Configuration
Section titled “Configuration”default: english
register: languages: - en_US:english:messages.yml - es_ES:spanish:messages.yml - pt_BR:portuguese:messages.ymlFolder layout:
languages/ ├── english/ │ ├── messages.yml │ ├── scoreboard.yml │ └── atlasaddon.yml └── spanish/ └── ...Placeholders
Section titled “Placeholders”%alang_(file)_(path)%%alang_(messages)_(join_message)%%alang_(lobby:scoreboard)_(title)%Resolves using the player’s language. Missing keys return a safe error string.
Commands
Section titled “Commands”Base: /atlaslang
| Command | Permission |
|---|---|
/atlaslang help | — |
/atlaslang list | atlaslang.list |
/atlaslang aliases | atlaslang.aliases |
/atlaslang set <player> <language> | atlaslang.set |
/atlaslang reset <player> | atlaslang.reset |
/atlaslang info <player> | atlaslang.info |
/atlaslang reload | atlaslang.reload |
/atlaslang github sync | atlaslang.github |
/atlaslang github status | atlaslang.github |
atlaslang.admin grants every permission above.
Developer API
Section titled “Developer API”Maven module: com.github.nautic:api. Three types — AtlasAPI, AtlasProvider, PlayerLanguageChangeEvent.
Installation
Section titled “Installation”<repositories> <repository> <id>jitpack.io</id> <url>https://jitpack.io</url> </repository></repositories>
<dependency> <groupId>com.github.nauticstudios.AtlasLang</groupId> <artifactId>api</artifactId> <version>VERSION</version> <scope>provided</scope></dependency>repositories { maven("https://jitpack.io") }
dependencies { compileOnly("com.github.nauticstudios.AtlasLang:api:VERSION")}depend: [AtlasLang] # or: softdepend: [AtlasLang]Quick start
Section titled “Quick start”import com.github.nautic.api.AtlasAPI;
String msg = AtlasAPI.translate(player, "join.welcome");
String greet = AtlasAPI.translateOrDefault( player.getUniqueId(), "myaddon", "join.welcome", "Welcome!");
AtlasAPI.setLanguage(player, "spanish");String lang = AtlasAPI.getLanguage(player);Conventions
Section titled “Conventions”- Every method has a
Playerand aUUIDoverload. langInputaccepts either a locale code (en_US) or folder (english).namespaceis a folder insidelanguages/<lang>/. Defaults toatlasaddon.getPlayerLanguage(...)reads from memory — no DB call.
Constants
Section titled “Constants”| Constant | Value |
|---|---|
AtlasAPI.API_VERSION | 2 |
AtlasAPI.DEFAULT_NAMESPACE | "atlasaddon" |
Version gating
Section titled “Version gating”package com.example.myplugin;
import org.bukkit.plugin.java.JavaPlugin;import com.github.nautic.api.AtlasAPI;
public final class MyPlugin extends JavaPlugin {
@Override public void onEnable() { if (!AtlasAPI.isAvailable()) { getServer().getPluginManager().disablePlugin(this); return; }
try { AtlasAPI.requireVersion(2); } catch (IllegalStateException error) { getLogger().severe(error.getMessage()); getServer().getPluginManager().disablePlugin(this); } }}Translate
Section titled “Translate”AtlasAPI.translate(player, "join.welcome");AtlasAPI.translate(player, "mycrates", "open.message");AtlasAPI.translate(uuid, "join.welcome");AtlasAPI.translate(uuid, "mycrates", "open.message");
AtlasAPI.translateInLang("english", "join.welcome");AtlasAPI.translateInLang("es_ES", "mycrates", "open.message");
AtlasAPI.translateOrDefault(uuid, "mycrates", "open.message", "&aFallback");Set language
Section titled “Set language”boolean ok = AtlasAPI.setLanguage(player, "spanish");
AtlasAPI.setLanguageAsync(uuid, "spanish").thenAccept(success -> { // ...});Both forms fire PlayerLanguageChangeEvent and persist asynchronously. The sync form returns true if the language was resolved and the event was not cancelled; the async form completes once the DB row is committed.
String folder = AtlasAPI.getLanguage(player);String locale = AtlasAPI.api().getLocaleOf(folder); // nullable
Set<String> folders = AtlasAPI.getRegistered();Set<String> locales = AtlasAPI.getLocales();String fallback = AtlasAPI.getDefault();
AtlasAPI.api().compatibleLanguages(List.of("en_US", "fr_FR", "es_ES"));Method reference
Section titled “Method reference”| Method | Returns |
|---|---|
message(Player / UUID, [namespace,] path) | String |
messageInLang(langInput, [namespace,] path) | String |
messageOrDefault(UUID, namespace, path, fallback) | String |
has(langInput, [namespace,] path) | boolean |
setPlayerLanguage(Player / UUID, langInput) | boolean |
setPlayerLanguageAsync(UUID, langInput) | CompletableFuture<Boolean> |
getPlayerLanguage(Player / UUID) | String |
isLanguageRegistered(langInput) / supports(langInput) | boolean |
getRegisteredLanguages() / getRegisteredLocales() | Set<String> |
getDefaultLanguage() | String |
getLocaleOf(folder) | String? |
compatibleLanguages(Collection<String>) | Set<String> |
getApiVersion() | int |
Static shortcuts
Section titled “Static shortcuts”| Static call | Delegates to |
|---|---|
AtlasAPI.api() | AtlasProvider.get() |
AtlasAPI.isAvailable() | AtlasProvider.isRegistered() |
AtlasAPI.requireVersion(int) | Throws if API_VERSION is lower. |
translate(...) | message(...) |
translateInLang(...) | messageInLang(...) |
translateOrDefault(...) | messageOrDefault(...) |
exists(...) | has(...) |
setLanguage(...) | setPlayerLanguage(...) |
setLanguageAsync(...) | setPlayerLanguageAsync(...) |
getLanguage(...) | getPlayerLanguage(...) |
getRegistered() / getLocales() / getDefault() | corresponding instance method |
Events
Section titled “Events”PlayerLanguageChangeEvent
Section titled “PlayerLanguageChangeEvent”Cancellable. New language can be rewritten with setNewLanguage(...).
| Method | Returns |
|---|---|
getUniqueId() | UUID |
getPreviousLanguage() | String? |
getNewLanguage() | String |
setNewLanguage(String) | void |
isCancelled() / setCancelled(boolean) | — |
package com.example.plugin.listener;
import org.bukkit.event.EventHandler;import org.bukkit.event.EventPriority;import org.bukkit.event.Listener;
import com.github.nautic.api.event.PlayerLanguageChangeEvent;
import java.util.Set;
public final class LanguageGuard implements Listener {
private static final Set<String> BLOCKED = Set.of("klingon");
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onChange(final PlayerLanguageChangeEvent event) { if (BLOCKED.contains(event.getNewLanguage())) { event.setCancelled(true); return; }
if ("portuguese".equals(event.getNewLanguage())) { event.setNewLanguage("portuguese_br"); } }}Full plugin example
Section titled “Full plugin example”package com.example.welcome;
import org.bukkit.command.Command;import org.bukkit.command.CommandSender;import org.bukkit.entity.Player;import org.bukkit.event.EventHandler;import org.bukkit.event.Listener;import org.bukkit.event.player.PlayerJoinEvent;import org.bukkit.plugin.java.JavaPlugin;
import com.github.nautic.api.AtlasAPI;
public final class WelcomePlugin extends JavaPlugin implements Listener {
private static final String NAMESPACE = "welcome";
@Override public void onEnable() { if (!AtlasAPI.isAvailable()) { getServer().getPluginManager().disablePlugin(this); return; } AtlasAPI.requireVersion(2); getServer().getPluginManager().registerEvents(this, this); }
@EventHandler public void onJoin(final PlayerJoinEvent event) { final Player player = event.getPlayer(); player.sendMessage(AtlasAPI.translateOrDefault( player.getUniqueId(), NAMESPACE, "join.message", "&aWelcome, " + player.getName() + "!" )); }
@Override public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) { if (!(sender instanceof Player player)) return false; player.sendMessage(AtlasAPI.translate(player, NAMESPACE, "command.welcome")); return true; }}join: message: "&aWelcome back, %player_name%!"command: welcome: "&bHello from AtlasLang!"GitHub sync
Section titled “GitHub sync”github: repository: name: "owner/repository" branch: "main"
authentication: type: "none" token: ""
paths: remote-root: "languages" local-root: "languages"
sync: create-missing: true overwrite-existing: true delete-missing: false reload-after-sync: trueTrigger manually with /atlaslang github sync.