Skip to content

Localization

This guide shows you how to configure Passage to display disconnect messages in multiple languages, providing a better experience for international players.

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

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\"}"

Passage uses standard Minecraft locale codes:

CodeLanguageRegion
en_USEnglishUnited States
en_GBEnglishUnited Kingdom
de_DEGermanGermany
es_ESSpanishSpain
es_MXSpanishMexico
fr_FRFrenchFrance
fr_CAFrenchCanada
it_ITItalianItaly
pt_BRPortugueseBrazil
pt_PTPortuguesePortugal
ru_RURussianRussia
ja_JPJapaneseJapan
ko_KRKoreanSouth Korea
zh_CNChineseChina (Simplified)
zh_TWChineseTaiwan (Traditional)
nl_NLDutchNetherlands
pl_PLPolishPoland
tr_TRTurkishTurkey
sv_SESwedishSweden
da_DKDanishDenmark
fi_FIFinnishFinland
no_NONorwegianNorway
cs_CZCzechCzech Republic
el_GRGreekGreece
hu_HUHungarianHungary
ro_RORomanianRomania
uk_UAUkrainianUkraine
th_THThaiThailand
vi_VNVietnameseVietnam
id_IDIndonesianIndonesia
ms_MYMalayMalaysia
ar_SAArabicSaudi Arabia
he_ILHebrewIsrael

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 fallback

Best practice: Always configure messages for your default_locale.


Passage provides these built-in message keys:

Shown when a connection times out during handshake.

When it occurs:

  • Client doesn’t respond within the configured timeout period
  • Network issues cause connection to stall

Example:

[localization.messages.en]
disconnect_timeout = "{\"text\":\"Connection timeout\",\"color\":\"red\"}"

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\"}"

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\"}"

Messages use Minecraft’s JSON text component format.

disconnect_timeout = "{\"text\":\"Connection timeout\"}"
disconnect_timeout = "{\"text\":\"Connection timeout\",\"color\":\"red\"}"

Available colors:

  • black, dark_blue, dark_green, dark_aqua
  • dark_red, dark_purple, gold, gray
  • dark_gray, blue, green, aqua
  • red, light_purple, yellow, white
disconnect_timeout = "{\"text\":\"Connection timeout\",\"bold\":true,\"color\":\"red\"}"

Available formatting:

  • "bold": true
  • "italic": true
  • "underlined": true
  • "strikethrough": true
  • "obfuscated": true
disconnect_no_target = "{\"text\":\"\",\"extra\":[{\"text\":\"No server available\\n\",\"color\":\"yellow\",\"bold\":true},{\"text\":\"Please try again later\",\"color\":\"gray\"}]}"

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.


[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]
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\"}"

[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\"}"

[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\"}"

[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\"}"

Override localization settings with environment variables:

Terminal window
# Set default locale
export 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.


When a player connects, Passage:

  1. Checks client locale - Reads the locale sent by the client during handshake
  2. Looks up messages - Searches for messages in localization.messages.<locale>
  3. Falls back - If not found, uses default_locale messages
  4. Displays message - Sends the localized message to the client

Example flow:

  • Client with locale es_MX connects
  • 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)

In Minecraft:

  1. Options → Language
  2. Select a language
  3. Reconnect to test
# Set very short timeout
timeout = 1

Connect and wait 1 second without completing login.

[target_discovery]
adapter = "fixed"
# Don't configure any targets
[[target_discovery.fixed.targets]]
# Empty list

  • Always configure your default_locale
  • Add locales for your primary player base
  • Consider adding major languages (English, Spanish, German, French)
  • Keep messages clear and concise
  • Use friendly, helpful tone
  • Include actionable information when possible
  • Test with native speakers
  • 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)
  • Keep messages up to date
  • Review translations periodically
  • Accept community contributions
  • Store translations in version control

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

LanguageTranslation
GermanVerbindungszeitüberschreitung
SpanishTiempo de espera agotado
FrenchDélai de connexion dépassé
ItalianTimeout di connessione
PortugueseTempo de conexão esgotado
RussianТайм-аут подключения
Japanese接続タイムアウト
Korean연결 시간 초과
Chinese连接超时
DutchVerbindingstime-out
PolishPrzekroczono limit czasu
TurkishBağlantı zaman aşımı
LanguageTranslation
GermanKein Server verfügbar
SpanishServidor no disponible
FrenchAucun serveur disponible
ItalianNessun server disponibile
PortugueseNenhum servidor disponível
RussianНет доступного сервера
Japanese利用可能なサーバーがありません
Korean사용 가능한 서버가 없습니다
Chinese没有可用的服务器
DutchGeen server beschikbaar
PolishBrak dostępnego serwera
TurkishKullanılabilir sunucu yok

Messages Not Appearing in Different Languages

Section titled “Messages Not Appearing in Different Languages”
  1. Check locale code spelling:

    [localization.messages.es_ES] # Correct
    [localization.messages.es-ES] # Wrong - use underscore
  2. Verify JSON format:

    Terminal window
    # Test JSON validity
    echo '{"text":"Hello"}' | jq
  3. Check client language settings in Minecraft

  4. Enable debug logging:

    Terminal window
    RUST_LOG=debug passage

Ensure proper escaping in TOML:

# Escape quotes
disconnect_timeout = "{\"text\":\"Connection timeout\"}"
# Escape backslashes
disconnect_timeout = "{\"text\":\"Error: \\\\\"}"
# Use multiline strings for complex JSON
disconnect_timeout = '''{"text":"Connection timeout","color":"red"}'''