Localization
This guide shows you how to configure Passage to display disconnect messages in multiple languages, providing a better experience for international players.
Overview
Section titled “Overview”Passage supports localization (l10n) for disconnect messages. When a player is disconnected, Passage will show the message in the player’s configured language.
Supported scenarios:
- Connection timeouts
- No available backend servers
- Resource pack failures
- Custom disconnect reasons
Configuration
Section titled “Configuration”Configure localization in config.toml:
[localization]default_locale = "en_US"
[localization.messages.en]disconnect_timeout = "{\"text\":\"Connection timeout\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"No server available\",\"color\":\"yellow\"}"
[localization.messages.es]disconnect_timeout = "{\"text\":\"Tiempo de espera agotado\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Servidor no disponible\",\"color\":\"yellow\"}"Locale Codes
Section titled “Locale Codes”Passage uses standard Minecraft locale codes:
Supported Locales
Section titled “Supported Locales”| Code | Language | Region |
|---|---|---|
en_US | English | United States |
en_GB | English | United Kingdom |
de_DE | German | Germany |
es_ES | Spanish | Spain |
es_MX | Spanish | Mexico |
fr_FR | French | France |
fr_CA | French | Canada |
it_IT | Italian | Italy |
pt_BR | Portuguese | Brazil |
pt_PT | Portuguese | Portugal |
ru_RU | Russian | Russia |
ja_JP | Japanese | Japan |
ko_KR | Korean | South Korea |
zh_CN | Chinese | China (Simplified) |
zh_TW | Chinese | Taiwan (Traditional) |
nl_NL | Dutch | Netherlands |
pl_PL | Polish | Poland |
tr_TR | Turkish | Turkey |
sv_SE | Swedish | Sweden |
da_DK | Danish | Denmark |
fi_FI | Finnish | Finland |
no_NO | Norwegian | Norway |
cs_CZ | Czech | Czech Republic |
el_GR | Greek | Greece |
hu_HU | Hungarian | Hungary |
ro_RO | Romanian | Romania |
uk_UA | Ukrainian | Ukraine |
th_TH | Thai | Thailand |
vi_VN | Vietnamese | Vietnam |
id_ID | Indonesian | Indonesia |
ms_MY | Malay | Malaysia |
ar_SA | Arabic | Saudi Arabia |
he_IL | Hebrew | Israel |
Default Locale
Section titled “Default Locale”The default_locale is used when:
- The client doesn’t send a locale preference
- The client’s locale is not configured in Passage
- Fallback is needed for any reason
[localization]default_locale = "en_US" # Used as fallbackBest practice: Always configure messages for your default_locale.
Message Keys
Section titled “Message Keys”Standard Messages
Section titled “Standard Messages”Passage provides these built-in message keys:
disconnect_timeout
Section titled “disconnect_timeout”Shown when a connection times out during handshake.
When it occurs:
- Client doesn’t respond within the configured
timeoutperiod - Network issues cause connection to stall
Example:
[localization.messages.en]disconnect_timeout = "{\"text\":\"Connection timeout\",\"color\":\"red\"}"disconnect_no_target
Section titled “disconnect_no_target”Shown when no backend server is available.
When it occurs:
- Target discovery returns zero servers
- All servers are full (player_fill strategy)
- Strategy adapter returns no target
Example:
[localization.messages.en]disconnect_no_target = "{\"text\":\"No server available. Please try again later.\",\"color\":\"yellow\"}"disconnect_failed_resourcepack
Section titled “disconnect_failed_resourcepack”Shown when a required resource pack fails to load.
When it occurs:
- Client rejects the resource pack
- Resource pack download fails
- Resource pack is corrupted
Example:
[localization.messages.en]disconnect_failed_resourcepack = "{\"text\":\"Failed to load required resource pack\",\"color\":\"red\"}"Message Format
Section titled “Message Format”Messages use Minecraft’s JSON text component format.
Basic Text
Section titled “Basic Text”disconnect_timeout = "{\"text\":\"Connection timeout\"}"Colored Text
Section titled “Colored Text”disconnect_timeout = "{\"text\":\"Connection timeout\",\"color\":\"red\"}"Available colors:
black,dark_blue,dark_green,dark_aquadark_red,dark_purple,gold,graydark_gray,blue,green,aquared,light_purple,yellow,white
Formatted Text
Section titled “Formatted Text”disconnect_timeout = "{\"text\":\"Connection timeout\",\"bold\":true,\"color\":\"red\"}"Available formatting:
"bold": true"italic": true"underlined": true"strikethrough": true"obfuscated": true
Complex Messages
Section titled “Complex Messages”disconnect_no_target = "{\"text\":\"\",\"extra\":[{\"text\":\"No server available\\n\",\"color\":\"yellow\",\"bold\":true},{\"text\":\"Please try again later\",\"color\":\"gray\"}]}"With Placeholders
Section titled “With Placeholders”Messages support parameter substitution:
disconnect_custom = "{\"text\":\"Hello {player}!\"}"Available placeholders:
{player}- Player username{server}- Server hostname{reason}- Disconnect reason (if provided)
Note: Standard messages (disconnect_timeout, disconnect_no_target, etc.) don’t use placeholders by default.
Example Configurations
Section titled “Example Configurations”English Only
Section titled “English Only”[localization]default_locale = "en_US"
[localization.messages.en]disconnect_timeout = "{\"text\":\"Connection timeout\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"No server available\",\"color\":\"yellow\"}"disconnect_failed_resourcepack = "{\"text\":\"Failed to load resource pack\",\"color\":\"red\"}"Multi-Language (English + Spanish)
Section titled “Multi-Language (English + Spanish)”[localization]default_locale = "en_US"
[localization.messages.en]disconnect_timeout = "{\"text\":\"Connection timeout\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"No server available\",\"color\":\"yellow\"}"disconnect_failed_resourcepack = "{\"text\":\"Failed to load resource pack\",\"color\":\"red\"}"
[localization.messages.es]disconnect_timeout = "{\"text\":\"Tiempo de espera agotado\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Servidor no disponible\",\"color\":\"yellow\"}"disconnect_failed_resourcepack = "{\"text\":\"Error al cargar el paquete de recursos\",\"color\":\"red\"}"European Languages
Section titled “European Languages”[localization]default_locale = "en_GB"
[localization.messages.en]disconnect_timeout = "{\"text\":\"Connection timeout\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"No server available\",\"color\":\"yellow\"}"
[localization.messages.de]disconnect_timeout = "{\"text\":\"Verbindungszeitüberschreitung\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Kein Server verfügbar\",\"color\":\"yellow\"}"
[localization.messages.fr]disconnect_timeout = "{\"text\":\"Délai de connexion dépassé\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Aucun serveur disponible\",\"color\":\"yellow\"}"
[localization.messages.it]disconnect_timeout = "{\"text\":\"Timeout di connessione\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Nessun server disponibile\",\"color\":\"yellow\"}"
[localization.messages.es]disconnect_timeout = "{\"text\":\"Tiempo de espera agotado\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Servidor no disponible\",\"color\":\"yellow\"}"
[localization.messages.pt]disconnect_timeout = "{\"text\":\"Tempo de conexão esgotado\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Nenhum servidor disponível\",\"color\":\"yellow\"}"Asian Languages
Section titled “Asian Languages”[localization]default_locale = "en_US"
[localization.messages.en]disconnect_timeout = "{\"text\":\"Connection timeout\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"No server available\",\"color\":\"yellow\"}"
[localization.messages.ja]disconnect_timeout = "{\"text\":\"接続タイムアウト\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"利用可能なサーバーがありません\",\"color\":\"yellow\"}"
[localization.messages.ko]disconnect_timeout = "{\"text\":\"연결 시간 초과\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"사용 가능한 서버가 없습니다\",\"color\":\"yellow\"}"
[localization.messages.zh_CN]disconnect_timeout = "{\"text\":\"连接超时\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"没有可用的服务器\",\"color\":\"yellow\"}"
[localization.messages.zh_TW]disconnect_timeout = "{\"text\":\"連線逾時\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"沒有可用的伺服器\",\"color\":\"yellow\"}"Complete World-Wide Setup
Section titled “Complete World-Wide Setup”[localization]default_locale = "en_US"
# English[localization.messages.en]disconnect_timeout = "{\"text\":\"Connection timeout\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"No server available\",\"color\":\"yellow\"}"
# German[localization.messages.de]disconnect_timeout = "{\"text\":\"Verbindungszeitüberschreitung\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Kein Server verfügbar\",\"color\":\"yellow\"}"
# Spanish[localization.messages.es]disconnect_timeout = "{\"text\":\"Tiempo de espera agotado\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Servidor no disponible\",\"color\":\"yellow\"}"
# French[localization.messages.fr]disconnect_timeout = "{\"text\":\"Délai de connexion dépassé\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Aucun serveur disponible\",\"color\":\"yellow\"}"
# Italian[localization.messages.it]disconnect_timeout = "{\"text\":\"Timeout di connessione\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Nessun server disponibile\",\"color\":\"yellow\"}"
# Portuguese (Brazil)[localization.messages.pt_BR]disconnect_timeout = "{\"text\":\"Tempo de conexão esgotado\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Nenhum servidor disponível\",\"color\":\"yellow\"}"
# Russian[localization.messages.ru]disconnect_timeout = "{\"text\":\"Тайм-аут подключения\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Нет доступного сервера\",\"color\":\"yellow\"}"
# Japanese[localization.messages.ja]disconnect_timeout = "{\"text\":\"接続タイムアウト\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"利用可能なサーバーがありません\",\"color\":\"yellow\"}"
# Korean[localization.messages.ko]disconnect_timeout = "{\"text\":\"연결 시간 초과\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"사용 가능한 서버가 없습니다\",\"color\":\"yellow\"}"
# Chinese (Simplified)[localization.messages.zh_CN]disconnect_timeout = "{\"text\":\"连接超时\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"没有可用的服务器\",\"color\":\"yellow\"}"
# Dutch[localization.messages.nl]disconnect_timeout = "{\"text\":\"Verbindingstime-out\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Geen server beschikbaar\",\"color\":\"yellow\"}"
# Polish[localization.messages.pl]disconnect_timeout = "{\"text\":\"Przekroczono limit czasu połączenia\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Brak dostępnego serwera\",\"color\":\"yellow\"}"
# Turkish[localization.messages.tr]disconnect_timeout = "{\"text\":\"Bağlantı zaman aşımı\",\"color\":\"red\"}"disconnect_no_target = "{\"text\":\"Kullanılabilir sunucu yok\",\"color\":\"yellow\"}"Environment Variables
Section titled “Environment Variables”Override localization settings with environment variables:
# Set default localeexport PASSAGE_LOCALIZATION_DEFAULT_LOCALE=de_DE
# Override specific messages (not commonly used)export PASSAGE_LOCALIZATION_MESSAGES_EN_DISCONNECT_TIMEOUT='{"text":"Connection timeout","color":"red"}'Note: Environment variable syntax for nested localization messages is cumbersome. Prefer using config.toml.
How Locale Selection Works
Section titled “How Locale Selection Works”When a player connects, Passage:
- Checks client locale - Reads the locale sent by the client during handshake
- Looks up messages - Searches for messages in
localization.messages.<locale> - Falls back - If not found, uses
default_localemessages - Displays message - Sends the localized message to the client
Example flow:
- Client with locale
es_MXconnects - Connection times out
- Passage looks for
localization.messages.es_MX.disconnect_timeout - If not found, checks
localization.messages.es.disconnect_timeout(language fallback) - If not found, uses
localization.messages.en_US.disconnect_timeout(default locale)
Testing Localization
Section titled “Testing Localization”Change Client Locale
Section titled “Change Client Locale”In Minecraft:
- Options → Language
- Select a language
- Reconnect to test
Test Disconnect Messages
Section titled “Test Disconnect Messages”Test Timeout
Section titled “Test Timeout”# Set very short timeouttimeout = 1Connect and wait 1 second without completing login.
Test No Target
Section titled “Test No Target”[target_discovery]adapter = "fixed"# Don't configure any targets
[[target_discovery.fixed.targets]]# Empty listBest Practices
Section titled “Best Practices”Coverage
Section titled “Coverage”- Always configure your
default_locale - Add locales for your primary player base
- Consider adding major languages (English, Spanish, German, French)
Message Quality
Section titled “Message Quality”- Keep messages clear and concise
- Use friendly, helpful tone
- Include actionable information when possible
- Test with native speakers
Formatting
Section titled “Formatting”- Use colors to indicate severity:
- Red for errors
- Yellow for warnings
- Gray/white for informational
- Keep formatting consistent across languages
- Avoid overly fancy formatting (readability first)
Maintenance
Section titled “Maintenance”- Keep messages up to date
- Review translations periodically
- Accept community contributions
- Store translations in version control
Translation Services
Section titled “Translation Services”For professional translations, consider:
- Crowdin - Community translation platform
- POEditor - Translation management
- DeepL - AI translation (review required)
- Google Translate - Quick drafts (review required)
- Native speakers - Best quality
Common Translations
Section titled “Common Translations””Connection timeout”
Section titled “”Connection timeout””| Language | Translation |
|---|---|
| German | Verbindungszeitüberschreitung |
| Spanish | Tiempo de espera agotado |
| French | Délai de connexion dépassé |
| Italian | Timeout di connessione |
| Portuguese | Tempo de conexão esgotado |
| Russian | Тайм-аут подключения |
| Japanese | 接続タイムアウト |
| Korean | 연결 시간 초과 |
| Chinese | 连接超时 |
| Dutch | Verbindingstime-out |
| Polish | Przekroczono limit czasu |
| Turkish | Bağlantı zaman aşımı |
”No server available”
Section titled “”No server available””| Language | Translation |
|---|---|
| German | Kein Server verfügbar |
| Spanish | Servidor no disponible |
| French | Aucun serveur disponible |
| Italian | Nessun server disponibile |
| Portuguese | Nenhum servidor disponível |
| Russian | Нет доступного сервера |
| Japanese | 利用可能なサーバーがありません |
| Korean | 사용 가능한 서버가 없습니다 |
| Chinese | 没有可用的服务器 |
| Dutch | Geen server beschikbaar |
| Polish | Brak dostępnego serwera |
| Turkish | Kullanılabilir sunucu yok |
Troubleshooting
Section titled “Troubleshooting”Messages Not Appearing in Different Languages
Section titled “Messages Not Appearing in Different Languages”-
Check locale code spelling:
[localization.messages.es_ES] # Correct[localization.messages.es-ES] # Wrong - use underscore -
Verify JSON format:
Terminal window # Test JSON validityecho '{"text":"Hello"}' | jq -
Check client language settings in Minecraft
-
Enable debug logging:
Terminal window RUST_LOG=debug passage
Special Characters Not Displaying
Section titled “Special Characters Not Displaying”Ensure proper escaping in TOML:
# Escape quotesdisconnect_timeout = "{\"text\":\"Connection timeout\"}"
# Escape backslashesdisconnect_timeout = "{\"text\":\"Error: \\\\\"}"
# Use multiline strings for complex JSONdisconnect_timeout = '''{"text":"Connection timeout","color":"red"}'''