/localization
Use when implementing localization (i18n/l10n) — TranslationServer, CSV/PO translation files, locale switching, RTL support, and pluralization in Godot 4.3+
$ npx -y skills add jame581/GodotPrompter --skill localization --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/localization
Context preview
The summary Claude sees to decide when to auto-load this skill.
Use when implementing localization (i18n/l10n) — TranslationServer, CSV/PO translation files, locale switching, RTL support, and pluralization in Godot 4.3+
SKILL.md
localization.SKILL.mdname: localization
description: Use when implementing localization (i18n/l10n) — TranslationServer, CSV/PO translation files, locale switching, RTL support, and pluralization in Godot 4.3+
Localization in Godot 4.3+
All examples target Godot 4.3+ with no deprecated APIs; GDScript first, then C#.
> **Related skills:** **godot-ui** for Control nodes and theme management, **save-load** for persisting language settings, **responsive-ui** for layout adjustments per locale.
---
1. Core Concepts
How Godot Localization Works
1. **Wrap all user-facing strings** in `tr()` — Godot's translation function 2. **Create translation files** (CSV or PO) mapping keys to translated strings 3. **Import translation files** as `Translation` resources 4. **Switch locale at runtime** via `TranslationServer.set_locale()`
All `Control` nodes with `text`, `tooltip_text`, or `placeholder_text` properties auto-translate when the value matches a translation key.
Translation Key Strategies
| Strategy | Example Key | Pros | Cons | |----------|-------------|------|------| | Semantic keys | `MENU_START_GAME` | Clear intent, easy to find | Needs a default language fallback | | English-as-key | `Start Game` | Readable code, no mapping file for English | Breaks if English text changes |
> **Recommendation:** Use semantic keys (`MENU_START_GAME`) for production; English-as-key only for prototypes or solo projects.
---
2. Translation Files
CSV Format
The simplest format. First column is the key, subsequent columns are locale codes.
keys,en,cs,de,ja
MENU_START,Start Game,Začít hru,Spiel starten,ゲームスタート
MENU_OPTIONS,Options,Nastavení,Optionen,オプション
MENU_QUIT,Quit,Ukončit,Beenden,終了
PLAYER_HEALTH,Health: %d,Zdraví: %d,Gesundheit: %d,体力: %d
ITEM_COLLECTED,%s collected!,%s sebráno!,%s gesammelt!,%sを入手!
Save as `translations.csv` in your project. Godot auto-detects the format on import.
**Import settings** (Import dock):
- **Delimiter**: Comma (default) or Tab
- **Translations** section: enable/disable individual locales
PO Format (Gettext)
Industry-standard format, preferred by translation teams and tools like Poedit, Weblate, Crowdin.
**Create a POT template** (`messages.pot`):
msgid "MENU_START"
msgstr ""
msgid "MENU_OPTIONS"
msgstr ""
msgid "MENU_QUIT"
msgstr ""
msgid "PLAYER_HEALTH"
msgstr ""
**Create locale files** (e.g., `cs.po` for Czech):
msgid "MENU_START"
msgstr "Začít hru"
msgid "MENU_OPTIONS"
msgstr "Nastavení"
msgid "MENU_QUIT"
msgstr "Ukončit"
msgid "PLAYER_HEALTH"
msgstr "Zdraví: %d"
Registering Translations
**Project Settings → Localization → Translations → Add...** → select your `.csv` or `.po` files.
Or register at runtime:
var translation := load("res://translations/cs.po") as Translation
TranslationServer.add_translation(translation)var translation = GD.Load<Translation>("res://translations/cs.po");
TranslationServer.AddTranslation(translation);> ⚠️ **Changed in Godot 4.7:** `OptimizedTranslation.generate()` now returns `bool` (was `void`). GDScript- and C#-source-compatible, but binary-incompatible — recompile precompiled C# plugins calling it. See the [4.7 migration guide](https://docs.godotengine.org/en/latest/tutorials/migrating/upgrading_to_godot_4.7.html).
POT Generation Hooks (Godot 4.7+)
A custom `EditorTranslationParserPlugin` can override `_customize_strings()` — called once after all files are parsed during POT generation — to add or remove entries from the final extracted-string list:
@tool
extends EditorTranslationParserPlugin
func _customize_strings(strings: Array[PackedStringArray]) -> Array[PackedStringArray]:
strings.append(PackedStringArray(["Test 1", "context", "test 1 plurals", "test 1 comment"]))
# Drop internal strings that begin with "$".
return strings.filter(func(s): return not s[0].begins_with("$"))#if TOOLS
using System.Linq;
using Godot;
public partial class CommentAwareParser : EditorTranslationParserPlugin
{
public override Godot.Collections.Array<string[]> _CustomizeStrings(Godot.Collections.Array<string[]> strings)
{
strings.Add(new[] { "Test 1", "context", "test 1 plurals", "test 1 comment" });
// Drop internal strings that begin with "$".
return new Godot.Collections.Array<string[]>(strings.Where(s => !s[0].StartsWith("$")));
}
}
#endif> **Godot 4.7+:** The POT generator also extracts `Control.accessibility_name` and `accessibility_description`, making accessibility strings translatable without manual listing. ([GH-117134](https://github.com/godotengine/godot/pull/117134))
---
3. Using tr() in Code
GDScript
# Basic translation
var label_text: String = tr("MENU_START") # "Start Game" or translated equivalent
# With format arguments
var health_text: String = tr("PLAYER_HEALTH") % current_health
# "Health: 85" or "Zdraví: 85"
# With string arguments
var collected_text: String = tr("ITEM_COLLECTED") % item_name
# "Sword collected!" or "Meč sebráno!"
# Pluralization (Godot 4.x)
var count := 5
var msg: String = tr_n("ONE_ENEMY", "MANY_ENEMIES", count)
# Requires PO files with plural formsC#
string labelText = Tr("MENU_START");
string healthText = string.Format(Tr("PLAYER_HEALTH"), currentHealth);
// Pluralization
string msg = TrN("ONE_ENEMY", "MANY_ENEMIES", count);Automatic Control Translation
`Label`, `Button`, `RichTextLabel`, and other Control nodes auto-translate their `text` property when it matches a translation key. Set the text to the key:
Button.text = "MENU_START" → displays "Start Game" (en) or "Začít hru" (cs)
> **Tip:** To disable automatic translation on a specific Control, set `auto_translate_mode` to `DISABLED`.
> **Godot 4.7+:** `Control.translation_context: StringName` sets a per-control translation context, used both to translate displayed text and to generate translation tem
Read more
name: localization description: Use when implementing localization (i18n/l10n) — TranslationServer, CSV/PO translation files, locale switching, RTL support, and pluralization in Godot 4.3+
Localization in Godot 4.3+
All examples target Godot 4.3+ with no deprecated APIs; GDScript first, then C#.
> **Related skills:** **godot-ui** for Control nodes and theme management, **save-load** for persisting language settings, **responsive-ui** for layout adjustments per locale.
---
1. Core Concepts
How Godot Localization Works
1. **Wrap all user-facing strings** in `tr()` — Godot's translation function 2. **Create translation files** (CSV or PO) mapping keys to translated strings 3. **Import translation files** as `Translation` resources 4. **Switch locale at runtime** via `TranslationServer.set_locale()`
All `Control` nodes with `text`, `tooltip_text`, or `placeholder_text` properties auto-translate when the value matches a translation key.
Translation Key Strategies
| Strategy | Example Key | Pros | Cons | |----------|-------------|------|------| | Semantic keys | `MENU_START_GAME` | Clear intent, easy to find | Needs a default language fallback | | English-as-key | `Start Game` | Readable code, no mapping file for English | Breaks if English text changes |
> **Recommendation:** Use semantic keys (`MENU_START_GAME`) for production; English-as-key only for prototypes or solo projects.
---
2. Translation Files
CSV Format
The simplest format. First column is the key, subsequent columns are locale codes.
keys,en,cs,de,ja MENU_START,Start Game,Začít hru,Spiel starten,ゲームスタート MENU_OPTIONS,Options,Nastavení,Optionen,オプション MENU_QUIT,Quit,Ukončit,Beenden,終了 PLAYER_HEALTH,Health: %d,Zdraví: %d,Gesundheit: %d,体力: %d ITEM_COLLECTED,%s collected!,%s sebráno!,%s gesammelt!,%sを入手!
Save as `translations.csv` in your project. Godot auto-detects the format on import.
**Import settings** (Import dock):
- **Delimiter**: Comma (default) or Tab
- **Translations** section: enable/disable individual locales
PO Format (Gettext)
Industry-standard format, preferred by translation teams and tools like Poedit, Weblate, Crowdin.
**Create a POT template** (`messages.pot`):
msgid "MENU_START" msgstr "" msgid "MENU_OPTIONS" msgstr "" msgid "MENU_QUIT" msgstr "" msgid "PLAYER_HEALTH" msgstr ""
**Create locale files** (e.g., `cs.po` for Czech):
msgid "MENU_START" msgstr "Začít hru" msgid "MENU_OPTIONS" msgstr "Nastavení" msgid "MENU_QUIT" msgstr "Ukončit" msgid "PLAYER_HEALTH" msgstr "Zdraví: %d"
Registering Translations
**Project Settings → Localization → Translations → Add...** → select your `.csv` or `.po` files.
Or register at runtime:
var translation := load("res://translations/cs.po") as Translation
TranslationServer.add_translation(translation)var translation = GD.Load<Translation>("res://translations/cs.po");
TranslationServer.AddTranslation(translation);> ⚠️ **Changed in Godot 4.7:** `OptimizedTranslation.generate()` now returns `bool` (was `void`). GDScript- and C#-source-compatible, but binary-incompatible — recompile precompiled C# plugins calling it. See the [4.7 migration guide](https://docs.godotengine.org/en/latest/tutorials/migrating/upgrading_to_godot_4.7.html).
POT Generation Hooks (Godot 4.7+)
A custom `EditorTranslationParserPlugin` can override `_customize_strings()` — called once after all files are parsed during POT generation — to add or remove entries from the final extracted-string list:
@tool
extends EditorTranslationParserPlugin
func _customize_strings(strings: Array[PackedStringArray]) -> Array[PackedStringArray]:
strings.append(PackedStringArray(["Test 1", "context", "test 1 plurals", "test 1 comment"]))
# Drop internal strings that begin with "$".
return strings.filter(func(s): return not s[0].begins_with("$"))#if TOOLS
using System.Linq;
using Godot;
public partial class CommentAwareParser : EditorTranslationParserPlugin
{
public override Godot.Collections.Array<string[]> _CustomizeStrings(Godot.Collections.Array<string[]> strings)
{
strings.Add(new[] { "Test 1", "context", "test 1 plurals", "test 1 comment" });
// Drop internal strings that begin with "$".
return new Godot.Collections.Array<string[]>(strings.Where(s => !s[0].StartsWith("$")));
}
}
#endif> **Godot 4.7+:** The POT generator also extracts `Control.accessibility_name` and `accessibility_description`, making accessibility strings translatable without manual listing. ([GH-117134](https://github.com/godotengine/godot/pull/117134))
---
3. Using tr() in Code
GDScript
# Basic translation
var label_text: String = tr("MENU_START") # "Start Game" or translated equivalent
# With format arguments
var health_text: String = tr("PLAYER_HEALTH") % current_health
# "Health: 85" or "Zdraví: 85"
# With string arguments
var collected_text: String = tr("ITEM_COLLECTED") % item_name
# "Sword collected!" or "Meč sebráno!"
# Pluralization (Godot 4.x)
var count := 5
var msg: String = tr_n("ONE_ENEMY", "MANY_ENEMIES", count)
# Requires PO files with plural formsC#
string labelText = Tr("MENU_START");
string healthText = string.Format(Tr("PLAYER_HEALTH"), currentHealth);
// Pluralization
string msg = TrN("ONE_ENEMY", "MANY_ENEMIES", count);Automatic Control Translation
`Label`, `Button`, `RichTextLabel`, and other Control nodes auto-translate their `text` property when it matches a translation key. Set the text to the key:
Button.text = "MENU_START" → displays "Start Game" (en) or "Začít hru" (cs)
> **Tip:** To disable automatic translation on a specific Control, set `auto_translate_mode` to `DISABLED`.
> **Godot 4.7+:** `Control.translation_context: StringName` sets a per-control translation context, used both to translate displayed text and to generate translation tem
Agentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.
Other skills on godot-prompter.
- /authoring-godot-prompter-skills
Use when writing or editing a SKILL.md or an agent definition in this repo — required frontmatter, section ordering, and the GDScript-then-C# example convention.
Open skill - /releasing-godot-prompter
Use when cutting a GodotPrompter release or bumping its version — the version-bump sequence, tag-triggered workflow, and the marketplace manifests that must follow.
Open skill - /2d-essentials
Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D, custom drawing, and 2D meshes in Godot 4.3+
Open skill - /3d-essentials
Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion culling, and decals in Godot 4.3+
Open skill - /ability-system
Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay tags, and HUD binding
Open skill - /addon-development
Use when creating Godot editor plugins — EditorPlugin, @tool scripts, custom inspectors, and dock panels
Open skill

