Skip to content

feat(l10n): add planetary, fleet, recruitment, trading interface translation(zh-cn) - #1439

Open
CaesinEachonson wants to merge 37 commits into
Adeptus-Dominus:mainfrom
CaesinEachonson:feat/zh-cn-localization
Open

feat(l10n): add planetary, fleet, recruitment, trading interface translation(zh-cn)#1439
CaesinEachonson wants to merge 37 commits into
Adeptus-Dominus:mainfrom
CaesinEachonson:feat/zh-cn-localization

Conversation

@CaesinEachonson

@CaesinEachonson CaesinEachonson commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Completed translation of:
A1. Planetary
A2. Fleet
A3. Recruitment
A4. Trading


Summary by cubic

Adds zh-CN localization across planetary, fleet, recruitment, trading, diplomacy, advisors, and secret lair screens, replacing hardcoded English and Latin-only fonts. Text now resolves via localize(..., [args]) and draws with cjk_font(), so Chinese renders correctly and language switching is stable.

  • en.json/zh.json expanded and kept in sync (~1,210 keys); remaining literals replaced (ship repair popup, “SELECT DESTINATION”, debug options, garrison/disposition labels, promotion/recruit alerts, “DECLARE WAR”, secret lair titles, unit location statuses).
  • Planet info uses English-source arrays (fortification levels, presence factions/blurbs, planet sizes) and LocalizationManager.translate_array; localized arrays rebuild on language change to avoid per-frame translation and switch-time crashes.
  • All affected draws wrap fonts with cjk_font(); DataSlate/ShutterButton localize cover text and cache per language.
  • Trade UI decouples labels from logic: UI shows a localized label, logic reads stable data_label.
  • Table adds localize_headings/localize_values; enabled in unit quick-find for headings, with location values localized in code.
  • Adds localized_name_role() for advisor/unit headers; additional l10n fixes and a crash fix from a wrong function call.
  • Syncs with upstream LocalizationManager: adds a resolved-fonts cache and consolidates the CJK font-load guard; removes a duplicated safeguard.

Required actions

  • Wrap any new UI text with localize(..., [args]) and draw with cjk_font(font).
  • In trade options, set both data_label (stable key) and label (localized); read data_label in logic.
  • When adding planet info terms, extend the *_en arrays and rely on the locale refresh to rebuild localized arrays.
  • Enable Table.localize_headings/localize_values when headings or cell values are localization keys.

Written for commit 9d3c1c1. Summary will update on new commits.

Review in cubic

…json, added Chinese translation for said strings.
…nt, hit-test). IDE version will be updated during next commit.
- Wrap remaining bare strings in scr_PlanetData, scr_garrison, obj_star_select,
  obj_popup, scr_unit_quick_find_pane
- Add localize_values flag to scr_Table for row-value translation
- en.json/zh.json in sync at 690 keys
- Localize scr_fleet_advisor, scr_company_struct, scr_ui_manage and
  obj_controller battle UI (menu bar, ship repair popup)
- Convert template-literal strings to localize(..., [args]) form
- en.json/zh.json in sync at 849 keys
Devastator/歼灭者, Battle Barge/战斗驳船, Necrons/死灵族,
Recruiting World/征兵世界, Planetary Features/行星特征,
Renegade/变节, Reclusium/隐修室. Keep UI type labels 陆基型/赎罪远征.
- Localize recruit advisor, aspirant trials, training rates, promotion popup
- Convert trial long_description templates to localize(..., [args])
- scr_role_setup verified already covered (chapter-creation strings)
- en.json/zh.json in sync at 920 keys
…lair

- Localize trade screen (items, xeno refusal dialog, deal chances)
- Keep raw trade item data via data_label field so logic stays intact
- Localize diplomacy screen, Reclusium/festival advisors, secret lair rooms
- en.json/zh.json in sync at 1210 keys
Devastator/毁灭者, Necrons/太空死灵, Skitarii/护教军.
Keep deliberate UI exceptions 陆基型/赎罪远征/Load=读取.
Resolve lang conflicts: our zh.json is a superset of the upstream
localization (no unique upstream keys; only 3 zh values differed and
ours wins per localization-conflict rule). Keep merged auto-resolution
of 17 shared gml files (other PRs' changes preserved).
Trade, Reclusium/festival, diplomacy, secret lair, unit manage screens
used Latin-only fonts; wrap every draw_set_font with cjk_font() so
localized Chinese text renders (fallback runtime CJK fonts).
@github-actions github-actions Bot added Area: JSON Changes to external JSON files or their under-the-hood functionality Size: Epic labels Aug 16, 2026
@CaesinEachonson CaesinEachonson changed the title Feat/zh cn localization Feat/zh-cn-localization Aug 16, 2026
@CaesinEachonson CaesinEachonson changed the title Feat/zh-cn-localization feat/zh-cn-localization Aug 16, 2026
@github-actions github-actions Bot added the Type: Feature Adds something new label Aug 16, 2026
@CaesinEachonson CaesinEachonson changed the title feat/zh-cn-localization patch(l10n)/zh-cn-localization Aug 16, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 issues found across 21 files

Confidence score: 4/5

  • In scripts/scr_promote/scr_promote.gml, dynamic requirement keys like equipment names fall back to raw English in Chinese, so promotion requirements can appear mixed-language and harder to interpret—add the missing zh.json entries for all referenced requirement keys.
  • In scripts/scr_fleet_advisor/scr_fleet_advisor.gml, both weapon labels (cn.temp[110..116]) and the Gloriana class can render in English in the Chinese fleet detail view, which creates inconsistent UI text and weakens clarity—add the supported weapon and class keys to the Chinese locale.
  • In scripts/scr_ui_manage/scr_ui_manage.gml, the Apothecarion company name is routed through localization but the key is missing from catalogs, so this branch stays English for Chinese users—add the key and Chinese translation in the language files.
  • In scripts/scr_company_struct/scr_company_struct.gml, nested lookup of dynamic squad location phrases leaves English fragments inside otherwise translated labels, causing partial localization in core squad info—return stable keys/values from squad_loci() (or localize the dynamic phrase before composing the label).
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="scripts/scr_ui_manage/scr_ui_manage.gml">

<violation number="1" location="scripts/scr_ui_manage/scr_ui_manage.gml:485">
P2: The Apothecarion company name is passed through localization, but its key is absent from both language catalogs, so this branch remains English in Chinese. Add the key and its Chinese translation to the catalogs.</violation>
</file>

<file name="scripts/scr_promote/scr_promote.gml">

<violation number="1" location="scripts/scr_promote/scr_promote.gml:251">
P2: In Chinese, requirements such as `Bolter`, `Jump Pack`, and `Company Standard` remain English because these dynamic keys have no `zh.json` entries and `translate` falls back to the key. Add translations for all equipment and special requirement values before localizing them.</violation>
</file>

<file name="scripts/scr_fleet_advisor/scr_fleet_advisor.gml">

<violation number="1" location="scripts/scr_fleet_advisor/scr_fleet_advisor.gml:185">
P2: When a Gloriana ship appears in the fleet, this call falls back to the English class name because the Chinese locale has no `Gloriana` entry. Add the missing class translation.</violation>

<violation number="2" location="scripts/scr_fleet_advisor/scr_fleet_advisor.gml:295">
P2: In the Chinese fleet detail view, weapon names still render in English because none of the weapon keys used by `cn.temp[110..116]` exists in the Chinese locale. Add translations for the supported weapon names.</violation>
</file>

<file name="scripts/scr_company_struct/scr_company_struct.gml">

<violation number="1" location="scripts/scr_company_struct/scr_company_struct.gml:559">
P2: When the squad location contains a dynamic phrase, this nested lookup leaves that phrase in English even though the surrounding label is translated. Return stable location keys and values from `squad_loci()` or localize each location template before composing the display text.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread scripts/scr_trade/scr_trade.gml Outdated
Comment thread scripts/scr_Table/scr_Table.gml Outdated
Comment thread scripts/scr_ui_manage/scr_ui_manage.gml Outdated
break;
case 12:
_company_name = "Apothecarion";
_company_name = localize("Apothecarion");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The Apothecarion company name is passed through localization, but its key is absent from both language catalogs, so this branch remains English in Chinese. Add the key and its Chinese translation to the catalogs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/scr_ui_manage/scr_ui_manage.gml, line 485:

<comment>The Apothecarion company name is passed through localization, but its key is absent from both language catalogs, so this branch remains English in Chinese. Add the key and its Chinese translation to the catalogs.</comment>

<file context>
@@ -466,37 +466,37 @@ function reset_manage_unit_constants(unit) {
                 break;
             case 12:
-                _company_name = "Apothecarion";
+                _company_name = localize("Apothecarion");
                 break;
             case 13:
</file context>

draw_set_color(CM_GREEN_COLOR);
}
draw_text(1280, 390, $"{req_wep1_num} {req_wep1} (Have {have_wep1_num})");
draw_text(1280, 390, localize("{0} {1} (Have {2})", [req_wep1_num, localize(req_wep1), have_wep1_num]));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: In Chinese, requirements such as Bolter, Jump Pack, and Company Standard remain English because these dynamic keys have no zh.json entries and translate falls back to the key. Add translations for all equipment and special requirement values before localizing them.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/scr_promote/scr_promote.gml, line 251:

<comment>In Chinese, requirements such as `Bolter`, `Jump Pack`, and `Company Standard` remain English because these dynamic keys have no `zh.json` entries and `translate` falls back to the key. Add translations for all equipment and special requirement values before localizing them.</comment>

<file context>
@@ -248,7 +248,7 @@ function draw_popup_promotion() {
                 draw_set_color(CM_GREEN_COLOR);
             }
-            draw_text(1280, 390, $"{req_wep1_num} {req_wep1} (Have {have_wep1_num})");
+            draw_text(1280, 390, localize("{0} {1} (Have {2})", [req_wep1_num, localize(req_wep1), have_wep1_num]));
         }
         if (req_wep2 != "") {
</file context>

@CaesinEachonson CaesinEachonson Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The keys for equipment are intended to be translated in the next stage. And it is intended to let the untranslated strings to rollback to their English values, so should there are more strings added in the future, and said strings are not yet translated by me or others, they won't crash the game because of missing value in zh.json

Comment thread scripts/scr_unit_quick_find_pane/scr_unit_quick_find_pane.gml Outdated
Comment thread scripts/scr_fleet_advisor/scr_fleet_advisor.gml Outdated
Comment thread scripts/scr_PlanetData/scr_PlanetData.gml Outdated
Comment thread scripts/scr_PlanetData/scr_PlanetData.gml Outdated
Comment thread scripts/scr_garrison/scr_garrison.gml Outdated
@CaesinEachonson CaesinEachonson changed the title patch(l10n)/zh-cn-localization patch(l10n): add planetary, fleet, recruitment, trading interface translation(zh-cn) Aug 16, 2026
@CaesinEachonson CaesinEachonson changed the title patch(l10n): add planetary, fleet, recruitment, trading interface translation(zh-cn) feat(l10n): add planetary, fleet, recruitment, trading interface translation(zh-cn) Aug 16, 2026
@CaesinEachonson

Copy link
Copy Markdown
Contributor Author

22 issues found across 21 files

Confidence score: 3/5

  • In scripts/scr_trade/scr_trade.gml, scr_add_item can receive a string quantity from -_opt.data_label, which coerces to 0 and silently returns "no_item"; this can block item removal during trade flows and create hard-to-debug gameplay inconsistencies—pass a numeric field and validate/coerce quantity before calling scr_add_item.
  • objects/obj_controller/Draw_64.gml performs placeholder localization work every frame (array allocations plus repeated replacements), so UI draw cost can spike and cause avoidable frame drops on lower-end systems—cache resolved strings per state/language and only recompute when inputs change.
  • Localization behavior is inconsistent across scripts/scr_promote/scr_promote.gml, scripts/scr_fleet_advisor/scr_fleet_advisor.gml, and scripts/scr_recruit_data/scr_recruit_data.gml: missing zh keys and English-only post-processing leave mixed-language/incorrect-perspective text, which is user-facing in Chinese—add the missing translation keys and switch to role-aware localization keys instead of post-hoc replacements.
  • In scripts/scr_unit_quick_find_pane/scr_unit_quick_find_pane.gml, headers can stay in the old language after apply_language() and CJK text may render with missing glyphs due to font inheritance; players may see stale or unreadable table labels—rebuild/refresh the pane on language change and force cjk_font(...) for those header draws.

Prompt for AI agents (unresolved issues)


Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="scripts/scr_Table/scr_Table.gml">

<violation number="1" location="scripts/scr_Table/scr_Table.gml:129">
P2: When `localize_values` is true, `localize(_value)` is called on every struct-row cell. `localize()` forwards to `translate`, which returns `""` for any non-string key (see `translate`: `!is_string(_key)` → `is_string(_key) ? _key : ""`). So a numeric or non-string cell (e.g. a stat, count, cooldown, or enum value rendered into a localized table) silently draws as an empty value instead of its raw text. Both current `localize_values: true` callers happen to use only strings, so this is latent: any future localized table with a numeric column loses that data with no error. Guard the localization to strings so non-string cells pass through untouched.</violation>
</file>

<file name="scripts/scr_ui_manage/scr_ui_manage.gml">

<violation number="1" location="scripts/scr_ui_manage/scr_ui_manage.gml:312">
P2: The experience tooltip key differs from the catalog by using a curly apostrophe, so Chinese users see this tooltip in English. Use the catalog’s ASCII apostrophe in the localization key.</violation>

<violation number="2" location="scripts/scr_ui_manage/scr_ui_manage.gml:485">
P2: The Apothecarion company name is passed through localization, but its key is absent from both language catalogs, so this branch remains English in Chinese. Add the key and its Chinese translation to the catalogs.</violation>
</file>

<file name="scripts/scr_PlanetData/scr_PlanetData.gml">

<violation number="1" location="scripts/scr_PlanetData/scr_PlanetData.gml:403">
P3: This splits one sentence into separate translation keys, preventing natural word-order changes in future languages. Localize the complete sentence and pass the selected location as a `{0}` argument.</violation>

<violation number="2" location="scripts/scr_PlanetData/scr_PlanetData.gml:1274">
P3: In the planet draw block, the `forti_string`, `faction_names`, `blurbs`, and `size` arrays are rebuilt with `localize()` calls on every draw frame, so each element runs a translation lookup per frame per planet even though the result only changes when the language is switched. Cache the localized arrays (rebuild once on language change, matching `refresh_locale_globals()`) rather than translating them per draw.</violation>
</file>

<file name="scripts/scr_promote/scr_promote.gml">

<violation number="1" location="scripts/scr_promote/scr_promote.gml:251">
P2: In Chinese, requirements such as `Bolter`, `Jump Pack`, and `Company Standard` remain English because these dynamic keys have no `zh.json` entries and `translate` falls back to the key. Add translations for all equipment and special requirement values before localizing them.</violation>
</file>

<file name="scripts/scr_fleet_advisor/scr_fleet_advisor.gml">

<violation number="1" location="scripts/scr_fleet_advisor/scr_fleet_advisor.gml:74">
P2: When the adept report is shown in Chinese, the localized fragments retain “our” wording because the following replacements only match English text. Build the adept report with role-aware localization keys, or choose the pronouns before translating.</violation>

<violation number="2" location="scripts/scr_fleet_advisor/scr_fleet_advisor.gml:185">
P2: When a Gloriana ship appears in the fleet, this call falls back to the English class name because the Chinese locale has no `Gloriana` entry. Add the missing class translation.</violation>

<violation number="3" location="scripts/scr_fleet_advisor/scr_fleet_advisor.gml:295">
P2: In the Chinese fleet detail view, weapon names still render in English because none of the weapon keys used by `cn.temp[110..116]` exists in the Chinese locale. Add translations for the supported weapon names.</violation>

<violation number="4" location="scripts/scr_fleet_advisor/scr_fleet_advisor.gml:295">
P2: Custom agent: **Code Quality Review**

Four near-identical `draw_text` blocks are repeated with only the temp indices and Y-offset changing. This is boilerplate that increases maintenance debt; updates to rendering logic must be made in four places. Replace the four blocks with a single loop, since the values are already assigned in a loop above.</violation>
</file>

<file name="scripts/scr_recruit_data/scr_recruit_data.gml">

<violation number="1" location="scripts/scr_recruit_data/scr_recruit_data.gml:885">
P2: When `menu_adept == 1` in Chinese, the report still addresses the player with first-person wording such as `我方` and `我们`. Replace the English-only post-processing with perspective-aware localization keys.</violation>
</file>

<file name="scripts/scr_ui_diplomacy/scr_ui_diplomacy.gml">

<violation number="1" location="scripts/scr_ui_diplomacy/scr_ui_diplomacy.gml:388">
P2: When the language changes after diplomacy setup, the faction shutter labels remain in the old language because this localized value is cached during setup. Resolve `cover_text` when drawing or refresh the diplomacy shutters from the language-change handler.</violation>
</file>

<file name="scripts/scr_company_struct/scr_company_struct.gml">

<violation number="1" location="scripts/scr_company_struct/scr_company_struct.gml:554">
P2: When a squad leader is shown in Chinese, `localize(_squad_leader.name_role())` cannot match a dictionary key because `name_role()` includes the runtime name (and optional epithet). Localize the stable role separately while keeping the generated name as a value.</violation>

<violation number="2" location="scripts/scr_company_struct/scr_company_struct.gml:559">
P2: When the squad location contains a dynamic phrase, this nested lookup leaves that phrase in English even though the surrounding label is translated. Return stable location keys and values from `squad_loci()` or localize each location template before composing the display text.</violation>
</file>

<file name="scripts/scr_ui_advisors/scr_ui_advisors.gml">

<violation number="1" location="scripts/scr_ui_advisors/scr_ui_advisors.gml:67">
P2: When a department head is present, `_head.name_role()` returns a composed name and role, not a translation key. `localize` therefore leaves the role English in the Chinese Reclusium heading; localize `squad_role()` separately and append the name.</violation>

<violation number="2" location="scripts/scr_ui_advisors/scr_ui_advisors.gml:130">
P2: The Penitorium rows still show English roles in Chinese because `unit.name_role()` is a generated name-plus-role string that `localize` cannot match. Localize `unit.squad_role()` separately and append `unit.name_role(true, false)`.</violation>
</file>

<file name="scripts/scr_unit_quick_find_pane/scr_unit_quick_find_pane.gml">

<violation number="1" location="scripts/scr_unit_quick_find_pane/scr_unit_quick_find_pane.gml:38">
P2: After an in-game language change, these table headings remain in the language active during construction because the panel and its tables are not rebuilt. Refresh the table headings when `apply_language()` runs, or store English keys and localize them during drawing.</violation>

<violation number="2" location="scripts/scr_unit_quick_find_pane/scr_unit_quick_find_pane.gml:237">
P2: Custom agent: **Code Quality Review**

The forge/apothecary point header block is duplicated in `draw_fleet_area` and the garrisons branch. Extract a single helper such as `draw_specialist_point_headers(x, y)` and call it from both locations so labels, font, and alignment are maintained in one place.</violation>

<violation number="3" location="scripts/scr_unit_quick_find_pane/scr_unit_quick_find_pane.gml:372">
P2: When Chinese is selected, the garrison headers can render as missing glyphs because this branch inherits a non-CJK font. Set `draw_set_font(cjk_font(fnt_40k_14))` before these four headers.</violation>
</file>

<file name="scripts/scr_garrison/scr_garrison.gml">

<violation number="1" location="scripts/scr_garrison/scr_garrison.gml:350">
P3: The `string()` wrappers around the format arguments are redundant: `translate()` already converts every `{0}`/`{1}` argument via `string(_args[i])`, so wrapping adds noise without changing output. The same PR's diplomacy changes pass raw values (numbers and strings) directly, making the two files inconsistent. Drop the `string()` wrappers and pass values directly for a consistent, less-cluttered pattern.</violation>
</file>

<file name="objects/obj_controller/Draw_64.gml">

<violation number="1" location="objects/obj_controller/Draw_64.gml:127">
P2: Custom agent: **Code Quality Review**

The `localize()` calls with placeholder arguments allocate arrays and run `string_replace_all` loops inside the Draw_64 event every frame. The shadow-text pairs also resolve the same key twice instead of caching it (e.g., `localize("Loyal")` on lines 127 and 128). Cache `localize()` results in local variables before the paired `draw_text` calls to remove duplicate work from the hot draw path.</violation>
</file>

<file name="scripts/scr_trade/scr_trade.gml">

<violation number="1" location="scripts/scr_trade/scr_trade.gml:123">
P1: Custom agent: **Code Quality Review**

`scr_add_item` receives a string quantity because `-_opt.data_label` implicitly converts to `0` in GML, causing a silent `"no_item"` return and no items removed. The quantity should be `-_opt.number`, matching the corresponding store block that uses `_opt.number` for the item count.</violation>
</file>

Reply with feedback, questions, or to request a fix.Re-trigger cubic

scr_fleet_advisor.gml:185 Is intended to left untranslated for now. It is to be translated at the next stage.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 19 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread scripts/LocalizationManager/LocalizationManager.gml Outdated
Comment thread scripts/scr_ui_advisors/scr_ui_advisors.gml Outdated
Comment thread scripts/scr_ui_advisors/scr_ui_advisors.gml Outdated
Comment thread scripts/scr_company_struct/scr_company_struct.gml Outdated
Comment thread scripts/scr_ui_advisors/scr_ui_advisors.gml Outdated
Comment thread scripts/scr_Table/scr_Table.gml Outdated
Comment thread datafiles/lang/zh.json Outdated
Comment thread scripts/scr_DataSlate/scr_DataSlate.gml Outdated
Comment thread scripts/globals/globals.gml

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 10 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread scripts/LocalizationManager/LocalizationManager.gml Outdated
Comment thread scripts/scr_DataSlate/scr_DataSlate.gml Outdated
Comment thread scripts/scr_marine_struct/scr_marine_struct.gml
Comment thread scripts/LocalizationManager/LocalizationManager.gml Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread scripts/LocalizationManager/LocalizationManager.gml Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Requires human review: Auto-approval blocked by 5 unresolved issues from previous reviews.

Re-trigger cubic

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

Labels

Area: JSON Changes to external JSON files or their under-the-hood functionality Size: Warning Type: Feature Adds something new

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant