locale
Key-based translation with English fallback and string.format interpolation. Each resource ships its own files.
Key-based translation with English fallback and string.format interpolation. Each resource ships its own files.
lib.locale(key, ...) resolves a translation key in the current language and interpolates arguments via
string.format. A missing key falls back to English, then to the raw key. Each resource ships its own
translation files.
local greeting = lib.locale('welcome', playerData.name) -- 'Welcome Jean'
local stock = lib.locale('items.count', 5) -- 'You have 5 items'
local missing = lib.locale('unknown.key') -- 'unknown.key'keystringrequiredTranslation key, e.g. menu.title.
...anyoptionalInterpolation args forwarded to string.format when provided.
Returns the resolved string, or the key itself if it's missing in every language.
Each consuming resource ships flat-key JSON files under locales/<lang>.json, declared in its files {}:
my_resource/
locales/
en.json
fr.json
fxmanifest.lua
{
"welcome": "Welcome %s",
"items.count": "You have %d items"
}The active language is the server convar see:locale (default en):
set see:locale "fr"
The convar is read once at module load — changing it at runtime won't re-resolve, and editing a
JSON file needs a resource restart (each language is cached after first load). A missing key returns the
raw key with no warning, so a typo is easy to miss. Locale files live in the consuming resource, not
in see_lib (it ships no default translations). Interpolation is string.format (%s, %d), not named
{name} placeholders — a format/args mismatch throws a Lua error, and an invalid JSON fails silently
(every key falls through).