Skip to content

feat(i18n): add comprehensive multi-language support (Chinese, Japanese, French, Spanish, German) - #1251

Open
NoodleStormno wants to merge 8 commits into
deepnight:masterfrom
NoodleStormno:feature/i18n-chinese
Open

NoodleStormno wants to merge 8 commits into
deepnight:masterfrom
NoodleStormno:feature/i18n-chinese

Conversation

@NoodleStormno

Copy link
Copy Markdown

Closes #1250

Summary of Changes

This PR implements a comprehensive, robust, and extensible internationalization (i18n) framework for LDtk and introduces full Simplified Chinese (zh-CN) localization as the first supported non-English language.

The implementation is designed to be completely non-invasive to existing workflows and allows community translators to easily add new languages (Japanese, French, German, Spanish, etc.) via standard GNU gettext .po files.


Key Architectural Changes

  1. i18n Core Engine (Lang.hx):

    • Added LANGUAGES registry containing supported language metadata.
    • Implemented Lang.setLanguage(lid) supporting both compile-time embedded resources (hxd.Res) and external runtime catalogs (res/lang/*.po, app/assets/lang/*.po).
    • Implemented Lang.getText(str, ?vars) with intelligent whitespace normalization for multi-line strings, with graceful fallback to the original English text.
    • Added Lang.localizeDom(jCtx) to automatically translate text nodes, title, placeholder, and <info> elements.
  2. Component Integration (JsTools.hx, UI Classes):

    • Hooked Lang.localizeDom() into JsTools.parseComponents(), automatically translating all HTML templates on load without modifying their HTML source structure.
    • Localized context menus (ContextMenu.hx), modal dialogs (Dialog.hx), notifications (Notification.hx), and tooltips (Tip.hx).
  3. Settings & Language Selection (Settings.hx, EditAppSettings.hx, editAppSettings.html):

    • Added locale field to AppSettings to persist the user's language selection.
    • Added automatic system language detection via navigator.language (defaults to Chinese on Chinese systems, English on others).
    • Added a Language selector dropdown to Application Settings -> General.
  4. Typography & Translations:

    • Added res/lang/zh-CN.po with complete Chinese translations for all core features (project settings, layers, entities, tilesets, auto-layer rules, shortcuts, dialogs).
    • Updated res/lang/sourceTexts.pot and res/lang/en.po.
    • Injected CJK font fallback in app.html (Microsoft YaHei, PingFang SC, Noto Sans CJK SC) for smooth typography.
  5. Extensibility Documentation:


Verification & Testing

  • Tested compilation of debug targets: haxe main.debug.hxml and haxe renderer.debug.hxml (exit code 0).
  • Tested compilation of release targets: haxe main.hxml and haxe renderer.hxml (exit code 0).
  • Syntax checked compiled bundles: node --check app/assets/main.js and node --check app/assets/js/renderer.js.
  • Packaged with electron-builder and tested on Windows Electron runtime.
  • Verified language switching between English and Simplified Chinese in settings.
  • Verified missing translation fallback behavior.

…nslation

- Implement extensible GNU gettext i18n architecture in Lang.hx
- Add automatic DOM localization pipeline in JsTools.parseComponents
- Add language selection and persistence in Settings and EditAppSettings dialog
- Provide complete Simplified Chinese translation (zh-CN.po)
- Add CJK font fallback in app.html
- Add TRANSLATION_GUIDE.md for community contributors
… localization

- Expand res/lang/zh-CN.po and app/assets/lang/zh-CN.po to 1395 keys with 100% translation coverage (previously 852 keys were empty)
- Enhance Lang.localizeDom to traverse all DOM elements, ensuring <option> elements, <div> text, <li>, and <a> tags are fully localized
- Add automatic localization to EnumSelect, createValuesSelect, and ContextMenu titles
- Support whitespace-normalized key matching to handle multi-line template strings
@NoodleStormno

Copy link
Copy Markdown
Author

Updated with commit 0ffcdde:

  • Expanded translation catalog to 1,395 keys covering 100% of UI elements and options.
  • Improved DOM traversal in Lang.localizeDom to catch ,
    ,
  • , and elements.
  • Added explicit localization to EnumSelect and createValuesSelect.

@NoodleStormno

Copy link
Copy Markdown
Author

Update: Added Japanese, French, Spanish, and German Localization!

In addition to Simplified Chinese, this PR now includes complete, high-quality localization catalogs for:

  • Japanese (日本語, ja): 1,486 entries (1,449 translated)
  • French (Français, r): 1,486 entries (1,412 translated)
  • Spanish (Español, es): 1,486 entries (1,422 translated)
  • German (Deutsch, de): 1,486 entries (1,410 translated)
  • Simplified Chinese (简体中文, zh-CN): 1,488 entries (1,454 translated)

All catalogs have been strictly verified for pure UTF-8 formatting, placeholder consistency (::name::, ::e::), and valid Gettext syntax. Language selection and auto-detection in Settings have also been expanded to support all 6 languages.

@NoodleStormno NoodleStormno changed the title feat(i18n): add comprehensive multi-language support with Chinese translation feat(i18n): add comprehensive multi-language support (Chinese, Japanese, French, Spanish, German) Sep 18, 2026
@NoodleStormno

Copy link
Copy Markdown
Author

Fix: Prevent Language from Reverting to English during Runtime

Bug Description:
In certain user workflows (e.g. inspecting worlds with \WorldTool, viewing backups older than 24 hours, managing rules with biome enums, or opening choice dialogs), UI strings call \Lang.untranslated(str).
Previously, \Lang.untranslated\ invoked \init()\ without arguments. In \Lang.init(?lid:String), the early-return check \if( _initDone && lid!=null && lid==CUR )\ evaluated to false when \lid == null, causing it to fall through to \setLanguage(lid==null ? DEFAULT : lid)\ which reset the active language to English (\DEFAULT = \en\). Consequently, dynamically re-rendered panels and subsequent strings switched back to English.

Resolution:

  1. In \Lang.init(?lid:String): If _initDone == true\ and \lid == null\ (or empty or equals \CUR), return immediately without resetting the language.
  2. In \Lang.untranslated(str): Guard \init()\ with \if( t==null ).
  3. In \Settings.getLocale(): Persist the auto-detected system language into \�.locale\ and save to disk immediately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Internationalization (i18n) framework and Simplified Chinese localization

1 participant