Skip to content

Unify translation system: replace text.bmd(and other bmds) and Translations/*.json with .resx + generated C++ accessors #347

@Mosch0512

Description

@Mosch0512

Summary

The client currently uses two parallel translation systems:

  1. Legacy .bmd files (text.bmd, item.bmd, etc.) — binary, index-based lookup (e.g. GlobalText[100]).
  2. src/bin/Translations/<lang>/*.json — key-based runtime lookup (e.g. EDITOR_TEXT(\"btn_save\")).

Replace both with a single .resx-based localization system that compiles to generated C++ accessor classes at build time.

Target design

Source format

  • One .resx file per resource group per locale, e.g.:
    src/Localization/
      Editor.en.resx
      Editor.de.resx
      Items.en.resx
      Items.de.resx
      GlobalText.en.resx
      GlobalText.de.resx
    
  • .resx is plain XML — editable in Visual Studio, Rider, or any text editor on Linux/Mac.

Build-time code generator

  • A resx-to-C++ generator produces typed accessor headers, integrated into the CMake build.
  • Generated output (committed or in build dir, TBD) provides one class per resource group per locale, plus an index header.

Call-site usage

Compile-time-checked typed accessors:

ImGui::Text(\"%s\", L.editor.btnSave());
ImGui::Text(\"%s\", L.items.itemName(itemId));
ImGui::Text(\"%s\", L.global.greeting(playerName));   // placeholder substitution
  • Typos fail at compile time.
  • IDE autocomplete works.
  • Placeholder / format-string support for parameterized strings.

Runtime layer

  • Locale switching at runtime.
  • Configurable fallback locale (e.g. fall back to en when a key is missing in the active locale).
  • Defined behaviour for missing keys (log + return key name, or fail loudly in debug).

Migration plan

  1. Land the resx system + generator + runtime layer alongside the existing systems.
  2. Migrate strings from text.bmd, item.bmd, and any other .bmd localization files.
  3. Migrate strings from src/bin/Translations/<lang>/*.json.
  4. Remove the legacy code paths: GlobalText array indexing, text.bmd loader, EDITOR_TEXT macro, JSON translation loader.
  5. Delete the legacy data files.

A temporary integer-ID compatibility shim (L(100) → resolves to the migrated key) may help during migration but is not a long-term API — every call site should end up using the typed accessors.

Documentation

Add docs/translation-system.md covering:

  • How to add a new string (which .resx, naming convention).
  • How to add a new locale.
  • How the build-time generator runs.
  • How locale switching and fallback work at runtime.

Link it from README.md and from the AI/contributor entry point (#32).

Acceptance criteria

  • resx-to-C++ generator integrated into CMake; runs as part of a normal build.
  • Runtime locale switching with fallback works end-to-end.
  • At least two locales work (e.g. en + de).
  • All previously translatable text reachable via the new system.
  • Legacy .bmd translation files and Translations/*.json removed.
  • Legacy GlobalText / EDITOR_TEXT code paths removed.
  • docs/translation-system.md added.
  • also add these Option window: hardcoded English labels bypass translation system (post 3d-camera-rework) #334

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions