OPX//77
opx_infinityConcepts

Text and locales

Last updated on

Player-facing text comes from English and French catalogues looked up by key with OPX.Locale or the locale() shorthand; the server language is set once in config/shared.lua.

Every sentence a player reads comes from a catalogue, looked up by key. Logs, console answers and error codes stay in English. The server language is OPX.Config.SHARED.LOCALE in config/shared.lua ('en' by default; en and fr ship).

Where text lives

FileHolds
locales/en.lua, locales/fr.luaruntime-wide text, mostly the shared refusal codes (error.*)
modules/<id>/locales.luaone module's text, both languages in one file

Each file calls OPX.Locale.Register(code, strings) once per language. English and French must define the same keys with the same {placeholders}.

OPX.Locale.Register('en', {
	['thing.done'] = 'You picked up {count} items.',
})
OPX.Locale.Register('fr', {
	['thing.done'] = 'Vous avez ramassé {count} objets.',
})

Looking text up

CallAnswers
locale(key, params)The text, {name} placeholders filled. Global shorthand for OPX.Locale.Text.
OPX.Locale.Text(key, params)Same.
OPX.Locale.Exists(key)Whether the key is in the active or English catalogue.
OPX.Locale.Catalogue()Every key, English merged under the active language. The page gets its text this way.

A missing key falls back to English, then to the key itself, so an untranslated string shows its key on screen.

Codes are keys

  • Refusal codes such as error.tooFast are catalogue keys: the server sends the code, the client turns it into text. Do not rename a key — it may be a code on the wire.
  • OPX.RefusalKey turns any code with no text (e.g. a storage error) into error.unavailable before a player sees it. See Error codes.

Adding a language

Add locales/<code>.lua and an OPX.Locale.Register('<code>', …) block in every modules/<id>/locales.lua, list any new file in open77.lua, then set LOCALE to the new code. Keys you leave out fall back to English.

On this page