
Ο πλήρης οδηγός τοπικοποίησης παιχνιδιών στο Godot
Από το TranslationServer έως τις εναλλακτικές γραμματοσειρές: τοπικοποιήστε το παιχνίδι σας στο Godot με CSV, αρχεία PO, GDScript και αυτοματοποιημένη μετάφραση με AI.
Βασικές αρχές του TranslationServer
Το ενσωματωμένο TranslationServer του Godot αποτελεί τον πυρήνα του συστήματος τοπικοποίησης. Φορτώνει τους πόρους μετάφρασης κατά την εκκίνηση και αντιστοιχίζει τα κλειδιά μέσω της συνάρτησης tr(). Κάθε κλήση της tr() από το GDScript περνά από το TranslationServer — δεν απαιτούνται πρόσθετες βιβλιοθήκες.
# 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)Αρχεία μετάφρασης CSV
Το CSV είναι η απλούστερη μορφή για μεταφράσεις στο Godot. Ένα αρχείο περιέχει όλες τις γλώσσες σε στήλες. Η πρώτη στήλη περιέχει το κλειδί και κάθε επόμενη στήλη αντιστοιχεί σε μια τοπική ρύθμιση. Το Godot εισάγει αυτόματα τα αρχεία .csv και δημιουργεί πόρους .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 filesΑρχεία μετάφρασης PO / Gettext
Τα αρχεία PO (Portable Object) αποτελούν το καθιερωμένο πρότυπο του κλάδου για την τοπικοποίηση λογισμικού. Το Godot 4.x υποστηρίζει εγγενώς τη μορφή PO, με τύπους πληθυντικού, διάκριση βάσει συμφραζομένων και σχόλια μεταφραστών. Δημιουργήστε ένα αρχείο .po ανά γλώσσα σε έναν κατάλογο 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)Χρήση μεταφράσεων στο GDScript
Χρησιμοποιήστε την tr() οπουδήποτε στο GDScript για να μεταφράσετε συμβολοσειρές. Συνδυάστε τη με τον τελεστή % του GDScript για τη μορφοποίηση συμβολοσειρών. Για αξιόπιστη διαχείριση των τοπικών ρυθμίσεων, δημιουργήστε ένα script Autoload που χειρίζεται τον εντοπισμό, τη διατήρηση και την εναλλαγή τους μέσω σημάτων.
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()Πληθυντικοί και σύμβολα κράτησης θέσης
Το Godot χειρίζεται τους πληθυντικούς μέσω των τύπων πληθυντικού των αρχείων PO. Κάθε γλώσσα ορίζει τον δικό της τύπο υπολογισμού στην κεφαλίδα PO. Ο τελεστής % του GDScript χειρίζεται σύμβολα κράτησης θέσης βάσει σειράς (%s για συμβολοσειρές και %d για ακέραιους). Για ονομαστικά σύμβολα κράτησης θέσης, χρησιμοποιήστε την 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))Εναλλακτικές γραμματοσειρές για CJK, αραβικά και άλλα συστήματα γραφής
Η κύρια γραμματοσειρά του παιχνιδιού σας πιθανότατα δεν περιλαμβάνει γλυφές για τα ιαπωνικά, τα κορεατικά, τα κινεζικά, τα αραβικά ή τα ταϊλανδικά συστήματα γραφής. Το Godot 4.x υποστηρίζει αλυσίδες εναλλακτικών γραμματοσειρών — όταν λείπει μια γλυφή από την κύρια γραμματοσειρά, το Godot ελέγχει διαδοχικά τις εναλλακτικές. Χωρίς αυτές, το μη λατινικό κείμενο εμφανίζεται ως κενά τετράγωνα.
# 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_RTLΤοπικοποίηση σκηνών και UI
Υπάρχουν τρεις προσεγγίσεις για την τοπικοποίηση σκηνών στο Godot: μετάφραση στη _ready() με χρήση της tr(), χρήση της ιδιότητας Auto Translate στο πρόγραμμα επεξεργασίας ή φόρτωση εντελώς διαφορετικών σκηνών για γλώσσες που χρειάζονται διαφορετικές διατάξεις, όπως οι γλώσσες 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())Έξυπνη εναλλακτική τοπική ρύθμιση με το LocaleChain
Το TranslationServer του Godot επιστρέφει απευθείας στην προεπιλεγμένη τοπική ρύθμιση του έργου όταν λείπει μια περιφερειακή παραλλαγή. Έτσι, ένας παίκτης με pt-BR βλέπει αγγλικά αντί για πορτογαλικά, αν υπάρχουν μόνο μεταφράσεις pt-PT. Το LocaleChain διορθώνει αυτή τη συμπεριφορά συγχωνεύοντας στο TranslationServer μεταφράσεις από παραμετροποιήσιμες αλυσίδες εναλλακτικών τοπικών ρυθμίσεων κατά τη ρύθμιση.
# 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()Αυτοματοποιήστε τις μεταφράσεις παιχνιδιών
Αφού ολοκληρώσετε τη ρύθμιση της τοπικοποίησης, μεταφράστε τα αρχεία CSV ή PO με AI. Αυτοματοποιήστε τη μετάφραση συμβολοσειρών παιχνιδιού, κειμένου UI, περιγραφών αντικειμένων και διαλόγων — απευθείας από το IDE ή το pipeline CI/CD σας.
# 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Αυτοματοποιήστε τον έλεγχο ποιότητας των μεταφράσεων
Συνήθεις παγίδες
Τα αρχεία μετάφρασης δεν έχουν εισαχθεί
Οι τιμές CSV με κόμματα ή εισαγωγικά προκαλούν αποτυχία της ανάλυσης
Το κείμενο CJK ή το αραβικό κείμενο εμφανίζεται ως κενά τετράγωνα
Εσφαλμένος αριθμός τύπων πληθυντικού στην κεφαλίδα PO
Το Auto Translate παρακάμπτεται από τον κώδικα
Προτεινόμενη δομή έργου
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Μεταφράστε επίσης:
Δοκιμάστε τώρα το i18n Agent
Αφήστε εδώ το αρχείο μετάφρασής σας
JSON, YAML, PO, XML, CSV, Markdown, Properties
ή κάντε κλικ για να επιλέξετε αρχείο
Γλώσσες-στόχοι
Εναλλακτικές τοπικές ρυθμίσεις με το locale-chain-godot
Όταν λείπει ένα κλειδί μετάφρασης από μια περιφερειακή τοπική ρύθμιση όπως η pl_PL, το Godot μεταβαίνει απευθείας στην προεπιλεγμένη τοπική ρύθμιση του έργου αντί να ελέγξει πρώτα τη γονική ρύθμιση pl.
# 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"],
})Δείτε τον οδηγό μας για τις εναλλακτικές τοπικές ρυθμίσεις, με τον πλήρη κατάλογο των υποστηριζόμενων framework και 75 ενσωματωμένων αλυσίδων. Learn more →