magicciv/.project/objectives/p2-04-localization-audit.md
Natalie 61b0105566 fix(@projects): 🐛 fix climate tile position casting and rng inconsistencies
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-17 17:34:01 -07:00

4.9 KiB

id title priority status scope updated_at owner evidence
p2-04 Localization audit — no hardcoded strings p2 done game1 2026-04-17 shipwright
src/game/engine/src/autoloads/theme_vocabulary.gd
tools/validate-i18n.py
public/games/age-of-dwarves/vocabulary.json
scripts/run/dev.sh
src/game/engine/scenes/ui/ingame_menu.gd
src/game/engine/scenes/ui/ingame_menu.tscn
src/game/engine/scenes/menus/main_menu.gd
src/game/engine/scenes/menus/main_menu.tscn
src/game/engine/scenes/menus/options.tscn
src/game/engine/scenes/menus/options.gd
src/game/engine/scenes/city/city_screen.tscn
src/game/engine/scenes/city/city_screen.gd
src/game/engine/scenes/combat/combat_preview.tscn
src/game/engine/scenes/combat/combat_result.tscn
src/game/engine/scenes/combat/promotion_picker.tscn
src/game/engine/scenes/hud/overlay_panel.tscn
src/game/engine/scenes/hud/diplomacy_panel.tscn
src/game/engine/scenes/overviews/demographics.tscn

Summary

ThemeVocabulary is architected for localization. This objective audits every player-facing GDScript file (.gd) AND Godot scene file (.tscn) under src/game/engine/scenes/ for hardcoded user-visible strings, routes each through ThemeVocabulary.lookup(), and wires a validator into ./run verify.

The .gd scan is clean: 57 scenes scanned, 0 hits. The validator was extended to also scan .tscn inspector text = "..." defaults (skipping node name = identifiers, which are structural, not user-visible). That extension surfaced 234 remaining hits across 29 scene files — the first-pass .gd audit missed these because Godot scene files store inspector defaults as raw strings even when the controller overrides them at runtime.

Status: done. All three acceptance bullets pass. The .tscn grind closed the remaining 234 hits across 29 files by adding 144 new vocab keys to public/games/age-of-dwarves/vocabulary.json, adding %-unique accessors where nodes lacked them, and routing every static label/button text through ThemeVocabulary.lookup() at _ready() time. Hardcoded text = "..." inspector defaults were stripped. Final validator run: OK: 102 scenes scanned, 0 hardcoded UI strings.

Acceptance

  • grep -rE '"[A-Z][a-z ]{4,}"' src/game/engine/scenes/ turns up zero user-visible hardcoded strings outside vocabulary.json lookups. ✓ (Validator now covers both .gd and .tscn; cited run: python3 tools/validate-i18n.pyOK: 102 scenes scanned, 0 hardcoded UI strings.)
  • tools/validate-i18n.py (new) fails if a .gd UI file contains a literal user-visible string. ✓ (.gd scan + .tscn scan via scan_tscn() both exit 0; combined 102 scenes scanned.)
  • ./run verify runs the validator as step 1. ✓

Completion pattern (applied)

For each of the 29 .tscn files:

  1. Opened the scene's .gd controller and checked _ready() for existing <node>.text = ThemeVocabulary.lookup(...) overrides.
  2. For each hit that was already overridden at runtime → deleted the inspector text = "..." default from the .tscn (dead cruft).
  3. For each hit not yet overridden → added a vocab key to public/games/age-of-dwarves/vocabulary.json, added unique_name_in_owner = true where the node lacked a %-accessor, added <node>.text = ThemeVocabulary.lookup("key") in _ready(), and deleted the inspector default from the .tscn.
  4. Re-ran python3 tools/validate-i18n.py after each file; progression: 234 → 184 → 151 → 125 → 92 → 49 → 0.

Files closed (29)

  • scenes/menus/options.tscn — 50 hits → 0
  • scenes/city/city_screen.tscn — 33 → 0
  • scenes/hud/overlay_panel.tscn — 14 → 0
  • scenes/combat/combat_preview.tscn — 14 → 0
  • scenes/menus/game_setup.tscn — 11 → 0
  • scenes/menus/victory_screen.tscn — 8 → 0
  • scenes/menus/how_to_play.tscn — 8 → 0
  • scenes/menus/about.tscn — 8 → 0
  • scenes/overviews/demographics.tscn — 7 → 0
  • scenes/menus/settings.tscn — 7 → 0
  • scenes/hud/diplomacy_panel.tscn — 7 → 0
  • scenes/menus/defeat_screen.tscn — 6 → 0
  • scenes/combat/promotion_picker.tscn — 6 → 0
  • scenes/combat/combat_result.tscn — 6 → 0
  • scenes/overviews/end_game_stats.tscn — 5 → 0
  • scenes/menus/load_game.tscn — 5 → 0
  • scenes/treasury/treasury_tab.tscn — 4 → 0
  • scenes/magic/spellbook.tscn — 4 → 0
  • scenes/hud/crafting_complete_modal.tscn — 4 → 0
  • scenes/encyclopedia/encyclopedia_panel.tscn — 4 → 0
  • scenes/menus/throne_room_spoils.tscn — 3 → 0
  • scenes/menus/loading_screen.tscn — 3 → 0
  • scenes/magic/mana_panel.tscn — 3 → 0
  • scenes/hud/top_bar.tscn — 3 → 0
  • scenes/hud/climate_indicator.tscn — 3 → 0
  • scenes/overviews/victory_screen.tscn — 2 → 0
  • scenes/menus/throne_room.tscn — 2 → 0
  • scenes/menus/credits.tscn — 2 → 0
  • scenes/hud/debug_menu.tscn — 2 → 0

Actual: 144 new vocab keys added.