
Panduan Lengkap Lokalisasi Game Godot
Dari TranslationServer hingga fallback font: lokalkan game Godot Anda dengan CSV, file PO, GDScript, dan terjemahan AI otomatis.
Dasar-Dasar TranslationServer
TranslationServer bawaan Godot adalah inti sistem lokalisasi. Komponen ini memuat sumber daya terjemahan saat startup dan memilih kunci melalui fungsi tr(). Setiap panggilan tr() GDScript melewati TranslationServer — tanpa pustaka tambahan.
# 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)File Terjemahan CSV
CSV adalah format paling sederhana untuk terjemahan Godot. Satu file menyimpan semua bahasa dalam kolom. Kolom pertama adalah kunci, dan setiap kolom berikutnya adalah suatu locale. Godot secara otomatis mengimpor file .csv dan menghasilkan sumber daya .translation.
# 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!"# 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 filesFile Terjemahan PO / Gettext
File PO (Portable Object) adalah standar industri untuk lokalisasi perangkat lunak. Godot 4.x mendukung PO secara native dengan bentuk jamak, pembedaan konteks, dan komentar penerjemah. Buat satu file .po per bahasa dalam direktori locale/.
# 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枚のコインを集めました。"# 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)Penggunaan Terjemahan GDScript
Gunakan tr() di mana saja dalam GDScript untuk menerjemahkan string. Gabungkan dengan operator % GDScript untuk memformat string. Untuk pengelolaan locale yang tangguh, buat skrip Autoload yang menangani deteksi, persistensi, dan penggantian locale dengan sinyal.
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 — 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()Bentuk Jamak dan Placeholder
Godot menangani bentuk jamak melalui bentuk jamak file PO. Setiap bahasa mendefinisikan formula bentuk jamaknya sendiri di header PO. Operator % GDScript menangani placeholder posisi (%s untuk string, %d untuk bilangan bulat). Untuk placeholder bernama, gunakan String.replace().
# 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 монет."# 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))Fallback Font untuk CJK, Arab, dan Lainnya
Font utama game Anda kemungkinan tidak menyertakan glif untuk aksara Jepang, Korea, Tionghoa, Arab, atau Thai. Godot 4.x mendukung rantai fallback font — ketika glif tidak tersedia dalam font utama, Godot memeriksa font fallback secara berurutan. Tanpanya, teks non-Latin dirender sebagai kotak kosong.
# 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)# 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_RTLLokalisasi Scene dan UI
Ada tiga pendekatan untuk melokalkan scene Godot: terjemahkan dalam _ready() menggunakan tr(), gunakan properti Auto Translate dalam editor, atau muat scene yang sama sekali berbeda untuk bahasa yang memerlukan tata letak berbeda (seperti bahasa RTL).
# 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())Fallback Locale Cerdas dengan LocaleChain
TranslationServer Godot langsung melakukan fallback ke locale default proyek ketika varian regional tidak tersedia. Pemain pt-BR yang hanya memiliki terjemahan pt-PT melihat bahasa Inggris alih-alih Portugis. LocaleChain memperbaikinya dengan menggabungkan terjemahan dari rantai fallback yang dapat dikonfigurasi ke TranslationServer pada waktu konfigurasi.
# 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()Otomatiskan Terjemahan Game
Setelah penyiapan lokalisasi selesai, terjemahkan file CSV atau PO Anda menggunakan AI. Otomatiskan terjemahan string game, teks UI, deskripsi item, dan dialog — langsung dari IDE atau pipeline CI/CD Anda.
# 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 headersOtomatiskan Kualitas Terjemahan
Kesalahan Umum
File Terjemahan Tidak Diimpor
Nilai CSV dengan Koma atau Tanda Kutip Merusak Penguraian
Teks CJK atau Arab Menampilkan Kotak Kosong
Jumlah Bentuk Jamak dalam Header PO Salah
Auto Translate Diganti oleh Kode
Struktur Proyek yang Disarankan
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.cfgTerjemahkan juga:
Coba i18n Agent Sekarang
Lepaskan file terjemahan Anda di sini
JSON, YAML, PO, XML, CSV, Markdown, Properties
atau klik untuk menjelajahi
Bahasa target
Fallback Locale dengan locale-chain-godot
Ketika kunci terjemahan tidak tersedia dalam locale regional seperti pl_PL, Godot langsung beralih ke locale default proyek alih-alih memeriksa locale induk pl terlebih dahulu.
# Install from Godot Asset Library
# Search: locale-chain-godotvar lc = LocaleChain.new()
lc.configure({
"pl": ["pl_PL", "en"],
"pt_BR": ["pt", "en"],
"zh_Hant_HK": ["zh_Hant", "zh", "en"],
})Lihat Panduan Fallback Bahasa kami untuk daftar lengkap framework yang didukung dan 75 rantai bawaan. Learn more →