Skip to main content

Guía completa de localización de videojuegos con Godot

De TranslationServer a los respaldos de fuentes: localice su juego Godot con archivos CSV y PO, GDScript y traducción automatizada mediante IA.

1

Fundamentos de TranslationServer

El TranslationServer integrado en Godot es el núcleo del sistema. Carga recursos al iniciar y resuelve claves mediante tr(). Todas las llamadas de GDScript a tr() pasan por TranslationServer, sin bibliotecas adicionales.

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 admite formatos CSV, PO —Gettext— y .translation —binario—. Detecta automáticamente la configuración del sistema mediante OS.get_locale() y selecciona el recurso correspondiente. Puede cambiarla en cualquier momento con TranslationServer.set_locale().
2

Archivos de traducción CSV

CSV es el formato más sencillo para Godot. Un archivo contiene todos los idiomas en columnas. La primera es la clave y cada columna posterior corresponde a una configuración regional. Godot importa automáticamente los .csv y genera recursos .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
Envuelva entre comillas dobles los valores que contengan comas o saltos de línea. En los que incluyan comillas dobles, escápelas como "". Mantenga claves breves y descriptivas: MENU_START es mejor que menu_start_button_text_label.
3

Archivos de traducción PO / Gettext

Los archivos PO (Portable Object) son el estándar del sector para localizar software. Godot 4.x los admite de forma nativa con plurales, desambiguación contextual y comentarios para traductores. Cree un .po por idioma dentro de 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)
Los archivos PO admiten msgctxt para desambiguar —por ejemplo, 'OPEN' como verbo o adjetivo—, msgid_plural para plurales y comentarios para traductores —líneas #.— que explican dónde y cómo se utilizan las cadenas.
4

Uso de traducciones en GDScript

Utilice tr() en cualquier lugar de GDScript. Combínelo con el operador % para dar formato. Para una gestión regional sólida, cree un script Autoload que controle la detección, la persistencia y el cambio mediante señales.

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()
Cambiar la región con TranslationServer.set_locale() no actualiza automáticamente el texto ya renderizado en las escenas. Debe volver a aplicar tr() a todas las etiquetas, botones y nodos visibles. Utilice señales de su gestor para avisar a las escenas de que deben actualizarse.
5

Plurales y marcadores de posición

Godot gestiona plurales mediante las formas de archivos PO. Cada idioma define su fórmula en la cabecera. El operador % de GDScript gestiona marcadores posicionales (%s para cadenas y %d para enteros). Para marcadores con nombre, utilice 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))
Nunca codifique directamente lógica como 'if count == 1'. Las reglas varían enormemente: el inglés tiene 2 formas, el ruso 3, el árabe 6 y el japonés 1. Deje que el sistema PO elija automáticamente. CSV no admite plurales; utilice PO para cualquier contenido que los necesite.
6

Respaldos de fuentes para CJK, árabe y otras escrituras

Es probable que la fuente principal de su juego no incluya glifos japoneses, coreanos, chinos, árabes o tailandeses. Godot 4.x admite cadenas de respaldo: si falta un glifo, comprueba otras fuentes por orden. Sin ellas, el texto no latino aparece como cuadrados vacíos.

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
Utilice la familia Noto de Google, que abarca casi todas las escrituras Unicode. Añada Noto Sans JP, KR, SC y Arabic como respaldos. En juegos con pixel art, considere Noto Sans Mono o fuentes de mapa de bits con subconjuntos CJK. Tenga en cuenta el tamaño total: las fuentes CJK completas pueden ocupar entre 15 y 20 MB cada una.
7

Localización de escenas e interfaz

Hay tres métodos para localizar escenas de Godot: traducir en _ready() mediante tr(), utilizar Auto Translate en el editor o cargar escenas totalmente distintas para idiomas que necesitan otros diseños —como 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 solo funciona en la propiedad text del nodo. Si define text dinámicamente después de _ready(), lo sustituye. Para texto dinámico, utilice siempre tr() expresamente en el código. Además, Auto Translate aplica tr() al valor literal, por lo que text debe contener la clave, no la cadena legible de origen.
8

Respaldo regional inteligente con LocaleChain

TranslationServer de Godot pasa directamente a la región predeterminada del proyecto cuando falta una variante. Un jugador pt-BR que solo dispone de pt-PT ve inglés. LocaleChain lo corrige combinando traducciones de cadenas configurables dentro de TranslationServer al configurarlo.

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 es un complemento GDScript puro, sin extensiones nativas ni cambios del motor. Instálelo desde Godot AssetLib o copie addons/locale_chain/ en su proyecto. Funciona con CSV, PO y .translation.
9

Automatizar traducciones de videojuegos

Cuando termine de configurar la localización, traduzca sus archivos CSV o PO con IA. Automatice las cadenas del juego, el texto de la interfaz, las descripciones de objetos y los diálogos directamente desde el IDE o 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
Traduzca de forma incremental. Cuando añada claves nuevas al origen, traduzca solo las diferencias en vez de volver a generar todo. Así conserva los diálogos narrativos o el contenido culturalmente sensible revisados por personas.

Automatizar la calidad de la traducción

Detecte las claves ausentes y los marcadores rotos antes de publicar con i18n-validate. Pruebe la interfaz con pseudotraducciones mediante i18n-pseudo antes de que lleguen las reales.

Errores habituales

No se importaron los archivos de traducción

Godot debe importar los .csv y .po antes de utilizarlos. Si las traducciones no aparecen, compruebe que figuren en Project Settings > Localization > Translations. Para CSV, asegúrese de que Godot haya generado .translation en .godot/imported/.

Los valores CSV con comas o comillas rompen el análisis

Los valores con comas deben envolverse en comillas dobles. Las comillas dobles internas deben escaparse como "". Si falta una comilla, toda la fila se analiza mal y a menudo desplaza silenciosamente las columnas siguientes.

El texto CJK o árabe muestra cuadrados vacíos

Su fuente principal no contiene glifos para estas escrituras. Añada fuentes de respaldo en el recurso Theme o LabelSettings. Sin ellas, los glifos ausentes aparecen como rectángulos vacíos. Utilice variantes Noto Sans para una cobertura Unicode completa.

Número incorrecto de formas plurales en la cabecera PO

Si nplurals no coincide con el número real de entradas msgstr, Godot puede bloquearse o mostrar una forma equivocada. Compruebe siempre que Plural-Forms coincida con la especificación CLDR de cada idioma.

Auto Translate sustituido por el código

Definir la propiedad text de un nodo en GDScript después de _ready() sustituye el resultado automático. Utilice exclusivamente Auto Translate —defina text en el editor, nunca en código— o exclusivamente tr() en el código. Mezclarlos produce un comportamiento incoherente.

Estructura de proyecto recomendada

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

Pruebe i18n Agent ahora

Arrastre y suelte aquí su archivo de traducción

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

o haga clic para seleccionar

Idiomas de destino

No es necesario registrarsePresupuesto al instante

Respaldo de configuraciones regionales con locale-chain-godot

Cuando falta una clave de traducción en una configuración regional como pl_PL, Godot pasa directamente a la configuración regional predeterminada del proyecto en vez de comprobar primero la configuración regional principal pl.

Terminal
# Instalar desde Godot Asset Library
# Buscar: 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"],
})

Consulte nuestra guía de respaldo de configuraciones regionales para ver todos los frameworks admitidos y las 75 cadenas integradas. Learn more →

Preguntas frecuentes sobre localización en Godot