-
Notifications
You must be signed in to change notification settings - Fork 0
Localization
PCEdit ships in 15 languages. English (US) is written by hand; the other 14 are generated from per-locale JSON.
| File / type | Role |
|---|---|
PCEdit.App.Core/Resources/Strings.resx |
Source of truth — keys, their order, and the canonical en-US text |
PCEdit.App.Core/Resources/Strings.<culture>.resx (×14) |
Generated satellites — never hand-edit |
tools/i18n/<culture>.json (×14) |
The translations themselves; one flat { "Key": "text" } map |
tools/i18n/gen_satellites.py |
JSON → satellite .resx
|
tools/i18n/gen_metainfo.py |
Catalog → the Linux AppStream metainfo (store listing) |
Localization/LocKeys.cs |
Constants for every key referenced from C# |
Localization/ILocalizer.cs, Localizer.cs
|
this[key], Format(key, args), SetCulture, CultureChanged
|
Localization/LocaleOption.cs |
One selectable language (culture name, native name, English name) |
Cultures: en-GB, fr, de, es-ES, zh-Hans, ru, pl, pt-PT, ko, ja, pt-BR, it,
zh-Hant, tr — plus neutral en-US.
-
Add / change the key in
Strings.resx. -
Add / change the same key in every
tools/i18n/<culture>.json— all 14. -
Regenerate the satellites:
python tools/i18n/gen_satellites.py
-
If the key feeds the Linux store listing (
Shell_Title,About_Tagline,OpenFile_Intro,Disclaimer_Body), regenerate the AppStream metadata too:python tools/i18n/gen_metainfo.py
-
Run the tests:
dotnet test PCEdit.App.Core.Tests/PCEdit.App.Core.Tests.csproj -
Commit the generated files. CI regenerates them and fails the build on any drift.
LocalizationCatalogTests enforce that every satellite has exactly the neutral key set, that no
value is empty, that {0} / {1} placeholders match the neutral string, and that every LocKeys
constant exists.
From C# — inject ILocalizer and use a LocKeys constant:
_localizer[LocKeys.Save_Ok];
_localizer.Format(LocKeys.Teleport_Done, playerName, planetId, position);From XAML — the markup extensions:
<Button Content="{m:Loc Common_Save}" />
<!-- one argument, bound from the data context -->
<TextBlock Text="{m:LocFormat Key=Inv_Fallback, Path=InventoryId}" />
<!-- two arguments: {0} from Path, {1} from Path2 (v1.5.0) -->
<Button AutomationProperties.Name="{m:LocFormat Key=Inventories_MoveA11y, Path=DisplayName, Path2=WorldObjectId}" />
<!-- FallbackKey supplies the text when the first argument is null or empty -->LocFormat only takes named properties (Key, Path, Path2, FallbackKey); a positional
form does not exist.
Important
The markup extensions bind ILocalizer.Current through a converter, not the string indexer.
Avalonia's reflection binding does not re-read an [key] path on an Item[] notification, so a
binding written the obvious way would go stale the moment the user switches language.
The same rule applies in ViewModels: a status message is stored as a key plus its arguments and
re-formatted on CultureChanged, never as a finished string.
On first run the OS language is used if it is one of the 15; otherwise en-US. The user's choice from
the nav-pane picker is stored via ILanguageStore (see
Languages & Settings) and applied at startup by LanguageStartup.
SetCulture raises CultureChanged, and the whole UI re-reads — no restart.
- Add the culture to
CULTURESintools/i18n/gen_satellites.py. - Add
tools/i18n/<culture>.jsonwith every key translated. - Add a
LocaleOptionfor the picker (culture name, native name, English name). - Add the culture to
<SatelliteResourceLanguages>inPCEdit.Desktop.csproj— a satellite not listed there is not published, and the language silently falls back to English. - Regenerate, test, commit the generated files.
Consider whether the language needs fonts the app does not carry — CJK relies on the OS fallback, which is why the Linux notes ask for a Noto CJK package.
Everything except English started as a machine-translation pass. Resources/TRANSLATIONS.md tracks
the review status per locale and lists the batches of keys added since. A native-speaker review is
very welcome: correct tools/i18n/<culture>.json, regenerate, and mark the locale reviewed.
Its wording has one source — DISCLAIMER.md at the repo root — mirrored by the Disclaimer_Body
key in the catalog and by the AppStream <description>. Change one, change all three.
PCEdit · unofficial fan tool for The Planet Crafter · GPL-3.0-or-later · back up your saves (disclaimer)
Using PCEdit
- Installation
- Save File Locations
- Quick Start
- Worlds & Planets
- Overview & Terraforming
- Inventories
- Logistics Editor
- Terra Tokens
- Teleport
- Languages & Settings
- FAQ & Troubleshooting
Development
- Architecture
- Save File Format
- Save File Library
- App Core
- Desktop UI
- Localization
- Item Catalog
- Testing
Shipping