Skip to content

Add XML Translation Api - #91

Open
HayashiUme wants to merge 3 commits into
All-Of-Us-Mods:devfrom
HayashiUme:dev
Open

Add XML Translation Api#91
HayashiUme wants to merge 3 commits into
All-Of-Us-Mods:devfrom
HayashiUme:dev

Conversation

@HayashiUme

Copy link
Copy Markdown
Contributor

Add Translation API

This PR adds a complete multi-language translation system to MiraAPI, allowing mods to register translation files and
use .Translate() extension method anywhere.

QQ20260619-212716 QQ20260619-212740

Translation Flow

  1. Structured keys in XML: <string name="teleporter.name">传送者</string>
  2. Abstract class properties: public string RoleName => "teleporter.name";
  3. Reverse lookup: when a raw English string (like a ConfigEntry key "Example Bool") doesn't match any
    structured key, the system searches English dictionary values and maps back to the structured key for translation

Translation Files

  • Resources/Translations/English.xml and SChinese.xml for both MiraAPI and MiraAPI.Example
  • 13 other language stubs ready for community contributions
  • Files distributed to Application.persistentDataPath/mira_languages/{ModGuid}/ on startup, overwritten each update

Registration API

TranslationManager.Register("mira.example");

Tip

TranslationManager.Register() must be called in the plugin constructor rather than Load(), because attribute option constructors fire during the PluginLoad event before the mod's own Load() completes, causing .Translate() to miss the mod's own translations.

@HayashiUme
HayashiUme force-pushed the dev branch 2 times, most recently from bca3aaf to 9bc6e82 Compare June 19, 2026 15:36
@HayashiUme

Copy link
Copy Markdown
Contributor Author

To improve code cleanliness, I force push to the Pr
It now will to merge to the dev branch

@HayashiUme

Copy link
Copy Markdown
Contributor Author

No conflicts with base branch
Changes can be cleanly merged.

@AlchlcDvl

Copy link
Copy Markdown
Collaborator

Would be interesting if it used dynamic id building instead. Like for example:

public class SomeRole : CrewmateRole, ICustomRole
{
    public string IdPart => "someRole";
}

and then the translation api will dynamically build translation ids as someRole.name and someRole.description by default. It should remove a lot of boiletplate. Of course, can be made opt-out by adding a specific prefix to the ids (for example, adding a # will make it do that the system will pick up the rest of the string as the id itself, not adding parts to construct an id).

@HayashiUme

Copy link
Copy Markdown
Contributor Author

Would be interesting if it used dynamic id building instead. Like for example:

public class SomeRole : CrewmateRole, ICustomRole
{
    public string IdPart => "someRole";
}

and then the translation api will dynamically build translation ids as someRole.name and someRole.description by default. It should remove a lot of boiletplate. Of course, can be made opt-out by adding a specific prefix to the ids (for example, adding a # will make it do that the system will pick up the rest of the string as the id itself, not adding parts to construct an id).

It would be better to change it to GetMethodName()

@HayashiUme

Copy link
Copy Markdown
Contributor Author

Would be interesting if it used dynamic id building instead. Like for example:

public class SomeRole : CrewmateRole, ICustomRole
{
    public string IdPart => "someRole";
}

and then the translation api will dynamically build translation ids as someRole.name and someRole.description by default. It should remove a lot of boiletplate. Of course, can be made opt-out by adding a specific prefix to the ids (for example, adding a # will make it do that the system will pick up the rest of the string as the id itself, not adding parts to construct an id).

I will make changes later

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.

2 participants