Skip to content
Development
Skill

/localization

Use when implementing localization (i18n/l10n) — TranslationServer, CSV/PO translation files, locale switching, RTL support, and pluralization in Godot 4.3+

From plugin
godot-prompter
90361 skills9 agents1 hook

Claude Code

$ npx -y skills add jame581/GodotPrompter --skill localization --agent claude-code

SKILL.md

localization.SKILL.md
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), Semicolon, or Tab
  • **Compress**: on by default — stores an `OptimizedTranslation`, skipped for files that use `?context`/`?plural` (§10)

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)
# Needs plural forms in the translation: PO, or CSV `?plural` rows on Godot 4.6+ (§10)

C#

string labelText = Tr("MENU_START");
// string.Format ignores GDScript-style %d — substitute it yourself.
string healthText = Tr("PLAYER_HEALTH").Replace("%d", currentHealth.ToString());

// 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_tra

Read more
@jame581
Ships withgodot-prompter

Agentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.

90361 skills9 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
903
Star history of jame581/GodotPrompter on GitHub, a chart by star-history.com

Other skills on godot-prompter.

2d-essentials

2d-essentials

Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D,…

3d-essentials

3d-essentials

Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion…

ability-system

ability-system

Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills11d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc13d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about localization.

Which coding agents can use localization?
localization installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.