Unity SDK

Localization

Pull every translation key for your project, auto-detect the player's language, and resolve strings with graceful fallback. Ships with a disk cache so the first frame after a cold launch is fully translated even offline.

Overview

KalmForgeLocalization is a static class. Call Load() once after KalmForgeClient.Init() and from then on every Get(key) resolves against the active language with fallback to your project's default language, then to the key itself.

  • ~40 ISO codes supported out of the box (full list in the dashboard).
  • System language is auto-detected on first launch - saved to PlayerPrefs after the first SetLanguage.
  • The full payload is cached on disk at Application.persistentDataPath/kalmforge_localization.json.
  • Hash-based conditional fetch skips the download when the server content hasn't changed.

Quick start

LocalizedHud.csC#
1using KalmForge;
2using UnityEngine;
3using UnityEngine.UI;
4
5public class LocalizedHud : MonoBehaviour {
6 [SerializeField] Text title;
7 [SerializeField] Text body;
8
9 async void Start() {
10 await KalmForgeClient.Init();
11 await KalmForgeLocalization.Load();
12
13 Refresh();
14 KalmForgeLocalization.OnLanguageChanged += Refresh;
15 }
16
17 void Refresh() {
18 title.text = KalmForgeLocalization.Get("hud.title");
19 body.text = KalmForgeLocalization.Format("hud.coins", playerCoins);
20 }
21}

Languages & detection

After Load() resolves, KalmForgeLocalization.AvailableLanguages contains every code your project ships. The active language is picked in this order:

  1. Whatever the player previously chose (persisted in PlayerPrefs under kalmforge.language).
  2. The exact match for Application.systemLanguage (e.g. pt-br).
  3. The base language code (pt when the system says pt-br).
  4. The project's default language.
exampleC#
1// Show a language picker
2foreach (var code in KalmForgeLocalization.AvailableLanguages) {
3 Debug.Log(code); // "en", "fr", "pt-br", ...
4}
5
6// Switch - returns false if the code is unknown.
7bool ok = KalmForgeLocalization.SetLanguage("fr");
Note
Codes are normalised: leading/trailing whitespace stripped, lower-cased. "PT-BR" and "pt-br" are the same key.

Resolving keys

Get(key) walks current language → default language → first non-empty value → the key string itself. It never returns null - a missing key shows up as the literal key, which is your bug-finding fallback.

exampleC#
1string label = KalmForgeLocalization.Get("store.gem_pack.title");
2string formatted = KalmForgeLocalization.Format("store.gem_pack.price", 4.99f);
3bool defined = KalmForgeLocalization.Has("store.gem_pack.title");
Heads up
Format uses CultureInfo.InvariantCulture. If your translators include locale-specific number formatting in the template (e.g. {0:N2}), validate the output for every language.

Reacting to language changes

KalmForgeLocalization.OnLanguageChanged fires whenever the dataset is loaded or SetLanguage succeeds. Re-bind your UI from this single handler:

exampleC#
1void OnEnable() { KalmForgeLocalization.OnLanguageChanged += Rebind; }
2void OnDisable() { KalmForgeLocalization.OnLanguageChanged -= Rebind; }
3void Rebind() { /* refresh every label */ }

TMPLocalizer component

The SDK ships an optional drop-in component for TextMeshPro that binds a TMP_Text to a localisation key and keeps it in sync as the active language changes. Add it to any GameObject that already has a TMP_Text (or TextMeshProUGUI) component, then set the localisationKey field in the inspector.

Note
TMPLocalizer is gated by the KALM_TMP scripting define symbol so the SDK does not hard-depend on TextMeshPro. Add KALM_TMP under Project Settings → Player → Scripting Define Symbols once TMP is installed in your project.
TMPLocalizer.cs (inspector usage)C#
1// 1. Add the TMPLocalizer component to your TMP text object.
2// 2. Set "Localisation Key" in the inspector, e.g. "hud.title".
3// 3. The text refreshes automatically whenever KalmForgeLocalization.OnLanguageChanged fires.
4
5// From code you can force a refresh or preview another language:
6var localizer = GetComponent<KalmForge.TMPLocalizer>();
7localizer.localisationKey = "store.gem_pack.title";
8localizer.RefreshText();
9
10// Useful for in-editor language pickers / settings menus:
11localizer.PreviewTextForLanguage("fr");
TMPLocalizer - MonoBehaviour
NameTypeDescription
localisationKeystringTranslation key resolved via KalmForgeLocalization.Get on every refresh.
RefreshText()voidRe-resolves the key against the current language and writes it to the TMP_Text.
PreviewTextForLanguage(code)voidTemporarily switches language to fetch the translation, then restores the previous language. Handy for language-picker previews.

Cache & offline

Load() tries the network first; on failure it falls back to kalmforge_localization.json in persistentDataPath. A successful network response overwrites the cache.

The SDK also stores a content hash at kalmforge_localization.hash. On subsequent loads it sends this hash to the server via the X-Cache-Hash header. If the server confirms the content hasn't changed (HTTP 304 or matching X-Content-Hash header), the cached file is reused without re-downloading the full payload.

exampleC#
1// Force a clean re-download by deleting the cache and hash
2string cachePath = Path.Combine(Application.persistentDataPath, KalmForgeLocalization.CacheFileName);
3string hashPath = Path.Combine(Application.persistentDataPath, KalmForgeLocalization.HashFileName);
4if (File.Exists(cachePath)) File.Delete(cachePath);
5if (File.Exists(hashPath)) File.Delete(hashPath);
6await KalmForgeLocalization.Load();

API reference

KalmForgeLocalization - static API
NameTypeDescription
AvailableLanguagesIReadOnlyList<string>All language codes shipped by your project.
DefaultLanguagestringProject default. Used as final fallback for Get().
CurrentLanguagestringActive language code.
IsLoadedboolTrue after a successful Load().
OnLanguageChangedevent ActionFired on Load() or SetLanguage().
Load()TaskFetch translations with hash-based conditional download; falls back to disk cache.
SetLanguage(code)boolSwitch active language. Returns false if code unknown.
Get(key, onChanged)stringResolve key (current → default → first non-empty → key literal). Optional onChanged callback fires once after next language change.
Format(key, args)stringGet() then string.Format with InvariantCulture.
Has(key)boolTrue if a value exists in current OR default language.
CacheFileNamestring (const)"kalmforge_localization.json".
HashFileNamestring (const)"kalmforge_localization.hash".

REST endpoint

examplebash
1GET /api/public/sdk/localization
2Headers:
3 X-API-Key: kf_xxx_yyy
4
5Response:
6{
7 "default_language": "en",
8 "languages": ["en", "fr", "pt-br", ...],
9 "keys": [
10 { "key": "hud.title", "values": { "en": "Score", "fr": "Score" } },
11 ...
12 ]
13}
Back to DocsKalmForge SDK · v1.0.1