Skip to content

Localization ​

The Localization namespace lets a mod ship its text in more than one language and read back whichever one the player is playing in.

Without it a mod has one choice, which is to write its strings straight into the source, and the result is an English mod inside a game the player set to their own language. That is tolerable for a small mod and not tolerable for content someone paid for.

No permission required.

Available since SDK v0.23.0

The Localization namespace requires @hotbunny/[email protected] or newer. Run npm install @hotbunny/hackhub-content-sdk@latest to update.

Import ​

typescript
import { Localization } from "@hotbunny/hackhub-content-sdk";

Scoping ​

Keys are scoped to the mod that registered them, so two mods can both use "TITLE" and neither can overwrite a base game string. This is also why there is no way to read another mod's strings: text is content, and content belongs to the pack that shipped it.

Only languages the game already offers can be registered. A mod cannot introduce a new one, because a language is not just a bundle of strings: it is an entry in the settings menu, a date format, a font, and a promise that the rest of the game is translated too. Registering a language the game does not offer is ignored with a warning rather than throwing, so a pack that ships a translation ahead of the game still loads.

Methods ​

Localization.register(language, strings) ​

Add the strings for one language, keyed however your pack likes.

Register before anything reads the text. A quest's Title is read when the quest is registered, so the natural place is the top level of the pack's entry file, above the content that uses it.

typescript
Localization.register("en", { "QUEST.TITLE": "First Bounty" });

Localization.registerAll(bundles) ​

Register several languages at once, keyed by language code.

typescript
Localization.registerAll({
    en: { "QUEST.TITLE": "First Bounty", "GREETING": "Hey {{name}}." },
    tr: { "QUEST.TITLE": "İlk Ödül", "GREETING": "Selam {{name}}." },
});

Localization.t(key, vars?) ​

The text for key in the player's language. in the string are replaced from vars.

Falls back to English when the player's language has no translation for it, and returns the key itself when nothing has it at all, which makes a missing string obvious on screen instead of silently blank.

Returns: string

typescript
Localization.t("QUEST.TITLE");                  // "İlk Ödül" when playing in Turkish
Localization.t("GREETING", { name: "Ada" });    // "Selam Ada."

Localization.language() ​

The language code the player is playing in, e.g. "tr" or "pt-BR".

Returns: string

Localization.languages() ​

Every language code the game offers.

Returns: string[]

Localization.onLanguageChange(callback) ​

Run callback whenever the player switches language. Returns a function that stops listening.

Text read once and kept (a quest title, an app's rendered HTML) does not update by itself. Anything a pack draws itself should redraw here.

Returns: () => void

typescript
const stop = Localization.onLanguageChange(() => redrawMyApp());

Full example ​

typescript
import { Localization, Quest, RegisterQuest } from "@hotbunny/hackhub-content-sdk";

// Top of the entry file, above the content that reads these keys.
Localization.registerAll({
    en: { "Q.TITLE": "First Bounty", "Q.OBJ": "Find the exposed endpoint" },
    tr: { "Q.TITLE": "İlk Ödül", "Q.OBJ": "Açıkta kalan endpoint'i bul" },
});

@RegisterQuest
class FirstBounty extends Quest {
    Name = "first-bounty";
    Title = Localization.t("Q.TITLE");
    Objectives = [
        { name: "find-endpoint", description: Localization.t("Q.OBJ") },
    ];
}

Because Title is read once at registration, a player who switches language mid-game keeps the old title until the next load. Use onLanguageChange for anything your pack redraws itself.

HotBunny Interactive Entertainment Inc.