Overview
KalmForge.Localization 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
PlayerPrefsafter the firstSetLanguage. - The full payload is cached on disk at
Application.persistentDataPath/kalmforge_localization.json.
Quick start
1using KalmForge;2using UnityEngine;3using UnityEngine.UI;45public class LocalizedHud : MonoBehaviour {6 [SerializeField] Text title;7 [SerializeField] Text body;89 async void Start() {10 await KalmForgeClient.Init();11 await Localization.Load();1213 Refresh();14 Localization.OnLanguageChanged += Refresh;15 }1617 void Refresh() {18 title.text = Localization.Get("hud.title");19 body.text = Localization.Format("hud.coins", playerCoins);20 }21}Languages & detection
After Load() resolves, AvailableLanguages contains every code your project ships. The active language is picked in this order:
- Whatever the player previously chose (persisted in
PlayerPrefsunderkalmforge.language). - The exact match for
Application.systemLanguage(e.g.pt-br). - The base language code (
ptwhen the system sayspt-br). - The project's default language.
1// Show a language picker2foreach (var code in Localization.AvailableLanguages) {3 Debug.Log(code); // "en", "fr", "pt-br", ...4}56// Switch - returns false if the code is unknown.7bool ok = Localization.SetLanguage("fr");"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.
1string label = Localization.Get("store.gem_pack.title");2string formatted = Localization.Format("store.gem_pack.price", 4.99f);3bool defined = Localization.Has("store.gem_pack.title");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
OnLanguageChanged fires whenever the dataset is loaded or SetLanguage succeeds. Re-bind your UI from this single handler:
1void OnEnable() { Localization.OnLanguageChanged += Rebind; }2void OnDisable() { Localization.OnLanguageChanged -= Rebind; }3void Rebind() { /* refresh every label */ }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 cache file name is exposed as Localization.CacheFileName - delete it to force a clean re-download.
API reference
| Name | Type | Description |
|---|---|---|
| AvailableLanguages | IReadOnlyList<string> | All language codes shipped by your project. |
| DefaultLanguage | string | Project default. Used as final fallback for Get(). |
| CurrentLanguage | string | Active language code. |
| IsLoaded | bool | True after a successful Load(). |
| OnLanguageChanged | event Action | Fired on Load() or SetLanguage(). |
| Load() | Task | Fetch translations (network → cache fallback). |
| SetLanguage(code) | bool | Switch active language. Returns false if code unknown. |
| Get(key) | string | Resolve key (current → default → first non-empty → key literal). |
| Format(key, args) | string | Get() then string.Format with InvariantCulture. |
| Has(key) | bool | True if a value exists in current OR default language. |
| CacheFileName | string (const) | "kalmforge_localization.json". |
REST endpoint
1GET /api/public/sdk/localization2Headers:3 X-API-Key: kf_xxx_yyy45Response: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}