Skip to main content

Le guide complet de la localisation de jeux avec Godot

De TranslationServer aux polices de repli : localisez votre jeu Godot avec des fichiers CSV, PO, GDScript et la traduction automatisée par IA.

1

Les bases de TranslationServer

Le TranslationServer intégré à Godot constitue le cœur du système de localisation. Il charge les ressources de traduction au démarrage et résout les clés via la fonction tr(). Chaque appel à tr() en GDScript passe par TranslationServer : aucune bibliothèque supplémentaire n'est nécessaire.

TranslationServer basics
# TranslationServer is Godot's built-in localization system.
# It loads translations at startup and resolves keys via tr().

# Set the game's locale
TranslationServer.set_locale("ja")

# Get the current locale
var current = TranslationServer.get_locale()  # "ja"

# Translate a key — works everywhere in GDScript
var text = tr("MENU_START")  # "ゲームスタート"

# Translate with context (Godot 4.x)
var text = tr("OPEN", "verb")    # "Open" (action)
var text = tr("OPEN", "adj")     # "Open" (state)
TranslationServer prend en charge les formats CSV, PO (Gettext) et .translation (binaire). Il détecte automatiquement la locale du système via OS.get_locale() et sélectionne la ressource de traduction correspondante. Vous pouvez remplacer la locale à tout moment avec TranslationServer.set_locale().
2

Fichiers de traduction CSV

Le CSV est le format le plus simple pour les traductions Godot. Un seul fichier contient toutes les langues, réparties en colonnes. La première colonne correspond à la clé, et chaque colonne suivante à une locale. Godot importe automatiquement les fichiers .csv et génère les ressources .translation.

translations.csv
# translations.csv
# First column = key, subsequent columns = locale codes
keys,en,ja,de,es
MENU_START,Start Game,ゲームスタート,Spiel starten,Iniciar juego
MENU_SETTINGS,Settings,設定,Einstellungen,Configuración
MENU_QUIT,Quit,終了,Beenden,Salir
ITEM_SWORD,Sword,剣,Schwert,Espada
ITEM_SHIELD,Shield,盾,Schild,Escudo
DIALOG_GREETING,"Hello, adventurer!",冒険者よ、こんにちは!,"Hallo, Abenteurer!","¡Hola, aventurero!"
Importing CSV translations
# In Godot Editor:
# 1. Place your .csv file in the project (e.g., res://translations.csv)
# 2. Godot auto-imports it — creates .translation resources
# 3. Go to Project > Project Settings > Localization > Translations
# 4. Add the generated .translation files
Encadrez les valeurs contenant des virgules ou des retours à la ligne par des guillemets doubles. Pour les valeurs contenant des guillemets doubles, échappez-les avec "". Gardez des clés courtes et descriptives : MENU_START est préférable à menu_start_button_text_label.
3

Fichiers de traduction PO / Gettext

Les fichiers PO (Portable Object) constituent la norme du secteur pour la localisation logicielle. Godot 4.x prend en charge nativement le format PO, avec pluriels, désambiguïsation contextuelle et commentaires pour les traducteurs. Créez un fichier .po par langue dans un répertoire locale/.

locale/ja.po
# translations.po — Gettext format for Godot
# Place in res://locale/ja.po

msgid ""
msgstr ""
"Language: ja\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=1; plural=0;\n"

# Simple translation
msgid "MENU_START"
msgstr "ゲームスタート"

# Translation with context (disambiguates identical source strings)
msgctxt "verb"
msgid "OPEN"
msgstr "開く"

msgctxt "adj"
msgid "OPEN"
msgstr "開いている"

# Plural form
msgid "You collected %d coin."
msgid_plural "You collected %d coins."
msgstr[0] "%d枚のコインを集めました。"
Loading PO files
# Project Settings > Localization > Translations
# Add each .po file:
#   res://locale/en.po
#   res://locale/ja.po
#   res://locale/de.po
#   res://locale/es.po

# Or load programmatically:
func _ready():
    var translation = load("res://locale/ja.po")
    TranslationServer.add_translation(translation)
Les fichiers PO prennent en charge msgctxt pour la désambiguïsation contextuelle (par exemple, « OPEN » en tant que verbe ou adjectif), msgid_plural pour les formes de pluriel, ainsi que les commentaires pour les traducteurs (lignes #.) afin de leur indiquer où et comment les chaînes sont utilisées.
4

Utilisation des traductions en GDScript

Utilisez tr() n'importe où dans votre GDScript pour traduire des chaînes. Combinez-le avec l'opérateur % de GDScript pour le formatage de chaînes. Pour une gestion robuste des locales, créez un script Autoload qui gère la détection, la persistance et le changement de locale via des signaux.

Using tr() in scenes
extends Control

func _ready():
    # Simple key lookup
    $TitleLabel.text = tr("MENU_START")

    # With string formatting (positional)
    $GreetingLabel.text = tr("DIALOG_GREETING_NAME") % [player_name]

    # With multiple placeholders
    $StatusLabel.text = tr("PLAYER_STATUS") % [player_name, level, health]

    # Context-aware translation (Godot 4.x)
    $ActionButton.text = tr("OPEN", "verb")

    # Update UI when locale changes
    TranslationServer.set_locale("de")
    _update_ui()

func _update_ui():
    # Re-apply all translated strings
    $TitleLabel.text = tr("MENU_START")
    $GreetingLabel.text = tr("DIALOG_GREETING_NAME") % [player_name]
locale_manager.gd (Autoload)
# locale_manager.gd — Register as Autoload in Project Settings
extends Node

signal locale_changed(new_locale: String)

const SUPPORTED_LOCALES = ["en", "ja", "de", "es", "fr", "ko", "zh"]

func _ready():
    var system_locale = OS.get_locale_language()
    if system_locale in SUPPORTED_LOCALES:
        set_locale(system_locale)
    else:
        set_locale("en")

func set_locale(locale: String):
    TranslationServer.set_locale(locale)
    locale_changed.emit(locale)

func get_locale() -> String:
    return TranslationServer.get_locale()
Changer de locale avec TranslationServer.set_locale() ne met pas automatiquement à jour le texte déjà affiché dans vos scènes. Vous devez réappliquer manuellement tr() à tous les labels, boutons et nœuds de texte visibles après un changement de locale. Utilisez des signaux depuis votre gestionnaire de locale pour avertir les scènes d'UI qu'elles doivent se rafraîchir.
5

Pluriels et espaces réservés

Godot gère les pluriels via les formes de pluriel des fichiers PO. Chaque langue définit sa propre formule de pluriel dans l'en-tête PO. L'opérateur % de GDScript gère les espaces réservés positionnels (%s pour les chaînes, %d pour les entiers). Pour les espaces réservés nommés, utilisez String.replace().

Plural forms by language
# Godot uses Gettext PO plural rules.
# Each language defines its own plural formula.

# English (2 forms: one, other)
msgid "You collected %d coin."
msgid_plural "You collected %d coins."
msgstr[0] "You collected %d coin."
msgstr[1] "You collected %d coins."

# Japanese (1 form: other — no singular/plural distinction)
msgid "You collected %d coin."
msgid_plural "You collected %d coins."
msgstr[0] "%d枚のコインを集めました。"

# Russian (3 forms: one, few, many)
msgid "You collected %d coin."
msgid_plural "You collected %d coins."
msgstr[0] "Вы собрали %d монету."
msgstr[1] "Вы собрали %d монеты."
msgstr[2] "Вы собрали %d монет."
Placeholder formatting
# GDScript string formatting with tr()

# Positional placeholders with %
var msg = tr("SCORE_MSG") % [score]        # "Score: %d" → "Score: 1500"
var msg = tr("STATS") % [name, level, hp]  # "%s — Lv %d — HP: %d"

# Named placeholders (manual replacement)
var template = tr("WELCOME_BACK")
var msg = template.replace("{player}", name).replace("{days}", str(days))
Ne codez jamais en dur une logique de pluriel telle que 'if count == 1'. Les règles de pluriel varient énormément d'une langue à l'autre : l'anglais a 2 formes, le russe en a 3, l'arabe en a 6, et le japonais n'en a qu'une. Laissez le système de pluriel PO gérer automatiquement la sélection. Les fichiers CSV ne prennent pas en charge les pluriels : utilisez des fichiers PO pour tout contenu nécessitant des formes de pluriel.
6

Polices de repli pour le CJK, l'arabe et plus encore

La police principale de votre jeu ne contient probablement pas les glyphes nécessaires pour les écritures japonaise, coréenne, chinoise, arabe ou thaïe. Godot 4.x prend en charge les chaînes de polices de repli : lorsqu'un glyphe est absent de la police principale, Godot vérifie les polices de repli dans l'ordre. Sans cela, le texte non latin s'affiche sous forme de carrés vides.

Font fallback setup
# Godot 4.x supports font fallback chains.
# When a glyph is missing from the primary font, fallbacks are checked in order.

# In the Editor:
# 1. Create a LabelSettings or Theme resource
# 2. Set the primary font (e.g., Noto Sans for Latin)
# 3. Add fallback fonts: Noto Sans JP, KR, SC, Arabic

# Programmatically:
func setup_fonts():
    var font = FontFile.new()
    font.load_dynamic_font("res://fonts/NotoSans-Regular.ttf")

    var fallback_jp = FontFile.new()
    fallback_jp.load_dynamic_font("res://fonts/NotoSansJP-Regular.ttf")
    font.add_fallback(fallback_jp)

    $Label.add_theme_font_override("font", font)
RTL support
# Right-to-left (RTL) support for Arabic, Hebrew, etc.

# In the Editor:
# Select your Control node > Layout > Text Direction = RTL

# Programmatically:
func setup_rtl():
    var locale = TranslationServer.get_locale()
    var rtl_locales = ["ar", "he", "fa", "ur"]

    if locale.substr(0, 2) in rtl_locales:
        $Label.text_direction = Control.TEXT_DIRECTION_RTL
        $Container.layout_direction = Control.LAYOUT_DIRECTION_RTL
Utilisez la famille de polices Noto de Google : elle couvre presque toutes les écritures Unicode. Ajoutez Noto Sans JP, Noto Sans KR, Noto Sans SC et Noto Sans Arabic en tant que polices de repli. Pour les jeux en pixel art, envisagez Noto Sans Mono ou des polices bitmap incluant des sous-ensembles CJK. Gardez à l'esprit la taille totale des polices : les polices CJK complètes peuvent peser de 15 à 20 Mo chacune.
7

Localisation des scènes et de l'UI

Il existe trois approches pour localiser les scènes Godot : traduire dans _ready() avec tr(), utiliser la propriété Auto Translate de l'éditeur, ou charger des scènes entièrement différentes pour les langues nécessitant une mise en page distincte (comme les langues RTL).

Scene localization approaches
# Approach 1: Translate in _ready() using tr()
extends Control

func _ready():
    $StartButton.text = tr("MENU_START")
    $SettingsButton.text = tr("MENU_SETTINGS")
    $QuitButton.text = tr("MENU_QUIT")

# Approach 2: Use auto-translate in the editor
# Set the Text property to the translation key (e.g., "MENU_START")
# and enable "Auto Translate" on the node.

# Approach 3: Locale-specific scenes for complex layouts
func load_localized_scene():
    var locale = TranslationServer.get_locale().substr(0, 2)
    var path = "res://ui/main_menu_%s.tscn" % locale
    if ResourceLoader.exists(path):
        add_child(load(path).instantiate())
    else:
        add_child(load("res://ui/main_menu_en.tscn").instantiate())
Auto Translate ne fonctionne que sur la propriété text du nœud. Si vous définissez le texte dynamiquement dans le code après _ready(), auto-translate est ignoré. Pour du texte mis à jour dynamiquement, utilisez toujours tr() explicitement dans votre code. Notez également qu'auto-translate applique tr() à la valeur littérale du texte : la propriété text doit donc contenir la clé de traduction, et non la chaîne source lisible.
8

Repli intelligent de locale avec LocaleChain

Le TranslationServer de Godot se rabat directement sur la locale par défaut du projet lorsqu'une variante régionale est manquante. Un joueur pt-BR ne disposant que de traductions pt-PT voit s'afficher l'anglais au lieu du portugais. LocaleChain corrige ce problème en fusionnant les traductions issues de chaînes de repli configurables directement dans TranslationServer au moment de la configuration.

LocaleChain plugin
# LocaleChain for Godot — smart locale fallback
# Install from Godot AssetLib or copy addons/locale_chain/ into your project

# Problem: Godot's TranslationServer falls back directly to the default locale.
# A pt-BR player with only pt-PT translations sees English, not Portuguese.

# Solution: One-line setup
func _ready():
    LocaleChain.configure()  # Uses built-in fallback chains

# Now pt-BR falls back to pt-PT → pt → default
# es-MX falls back to es-419 → es → default
# zh-Hant-HK falls back to zh-Hant-TW → zh-Hant → default

# Custom configuration:
func _ready():
    # Override specific chains
    LocaleChain.configure({"pt-BR": ["pt"]})

    # Full custom — only your chains
    LocaleChain.configure(
        {"pt-BR": ["pt-PT", "pt"], "es-MX": ["es-419", "es"]},
        false  # don't merge defaults
    )

    # Reset to original state
    LocaleChain.reset()
LocaleChain est une extension purement GDScript : aucune extension native ni modification du moteur n'est nécessaire. Installez-la depuis l'AssetLib de Godot ou copiez le dossier addons/locale_chain/ dans votre projet. Elle fonctionne avec les fichiers CSV, PO et .translation.
9

Automatiser la traduction de vos jeux

Une fois votre configuration de localisation terminée, traduisez vos fichiers CSV ou PO grâce à l'IA. Automatisez la traduction des chaînes du jeu, des textes d'UI, des descriptions d'objets et des dialogues, directement depuis votre IDE ou votre pipeline CI/CD.

Terminal
# Translate your Godot locale files with AI
# CSV files:
# In your IDE, ask your AI assistant:
> Translate translations.csv to Japanese, Korean, and German

# PO files:
> Translate locale/en.po to ja, ko, de

# Or use the CLI in CI/CD:
npx i18n-agent translate locale/en.po --lang ja,ko,de

# The tool preserves:
# - CSV column structure and delimiters
# - PO msgctxt, msgid_plural, and plural forms
# - Placeholder syntax (%s, %d, {name})
# - Comments and metadata headers
Traduisez de façon incrémentale. Lorsque vous ajoutez de nouvelles clés à votre fichier source, ne traduisez que le diff plutôt que de tout régénérer. Cela préserve les traductions relues par des humains pour les dialogues narratifs ou le contenu culturellement sensible.

Automatiser la qualité des traductions

Détectez les clés manquantes et les espaces réservés cassés avant leur mise en production grâce à i18n-validate. Testez votre interface avec des pseudo-traductions grâce à i18n-pseudo avant l'arrivée des traductions réelles.

Pièges courants

Fichiers de traduction non importés

Godot doit importer les fichiers .csv et .po avant qu'ils ne soient utilisables. Si les traductions n'apparaissent pas, vérifiez que vos fichiers sont bien répertoriés dans Project Settings > Localization > Translations. Pour le CSV, assurez-vous que Godot a bien généré les fichiers .translation dans le répertoire .godot/imported/.

Les valeurs CSV contenant des virgules ou des guillemets cassent l'analyse

Les valeurs contenant des virgules doivent être encadrées de guillemets doubles. Les valeurs contenant des guillemets doubles doivent les échapper sous la forme "". L'absence d'un guillemet entraîne une analyse incorrecte de toute la ligne, décalant souvent silencieusement toutes les colonnes suivantes.

Le texte CJK ou arabe s'affiche sous forme de carrés vides

Votre police principale ne contient pas les glyphes de ces écritures. Ajoutez des polices de secours dans votre ressource Theme ou LabelSettings. Sans polices de secours, les glyphes manquants s'affichent sous forme de rectangles vides. Utilisez les variantes Noto Sans pour une couverture Unicode complète.

Nombre de formes plurielles incorrect dans l'en-tête PO

Si la valeur nplurals de votre en-tête PO ne correspond pas au nombre réel d'entrées msgstr, Godot peut planter ou afficher la mauvaise forme plurielle. Vérifiez toujours que l'en-tête Plural-Forms correspond à la spécification CLDR pour chaque langue cible.

Traduction automatique écrasée par le code

Définir la propriété text d'un nœud en GDScript après _ready() écrase le résultat de la traduction automatique. Utilisez soit exclusivement la traduction automatique (définissez le texte dans l'éditeur, jamais dans le code), soit exclusivement tr() dans le code. Mélanger les deux entraîne un comportement incohérent.

Structure de projet recommandée

Project Structure
my_godot_game/
├── addons/
│   └── locale_chain/              # LocaleChain plugin (optional)
│       ├── fallback_map.gd
│       ├── locale_chain.gd
│       └── plugin.cfg
├── fonts/
│   ├── NotoSans-Regular.ttf       # Primary font (Latin)
│   ├── NotoSansJP-Regular.ttf     # Japanese fallback
│   ├── NotoSansKR-Regular.ttf     # Korean fallback
│   └── NotoSansArabic-Regular.ttf # Arabic fallback
├── locale/
│   ├── en.po                      # English (source)
│   ├── ja.po                      # Japanese
│   ├── de.po                      # German
│   ├── es.po                      # Spanish
│   └── ar.po                      # Arabic
├── translations.csv               # Alternative: CSV format
├── scenes/
│   └── ui/
│       ├── main_menu.tscn
│       └── settings_menu.tscn
├── scripts/
│   ├── locale_manager.gd          # Autoload for locale management
│   └── ui/
│       └── main_menu.gd
├── project.godot
└── export_presets.cfg

Essayez i18n Agent maintenant

Déposez votre fichier de traduction ici

JSON, YAML, PO, XML, CSV, Markdown, Properties

ou cliquez pour parcourir

Langues cibles

Aucune inscription requiseEstimation instantanée

Repli de locale avec locale-chain-godot

Lorsqu'une clé de traduction est manquante dans une locale régionale comme pl_PL, Godot passe directement à la locale par défaut du projet au lieu de vérifier d'abord la locale parente pl.

Terminal
# Install from Godot Asset Library
# Search: locale-chain-godot
Configuration
var lc = LocaleChain.new()
lc.configure({
    "pl": ["pl_PL", "en"],
    "pt_BR": ["pt", "en"],
    "zh_Hant_HK": ["zh_Hant", "zh", "en"],
})

Consultez notre guide de repli de locale pour découvrir la liste complète des frameworks pris en charge et les 75 chaînes intégrées. Learn more →

FAQ sur la localisation Godot