Localization
TL;DR; Contracts’ localization system works just like most other plugins that supports it and only comes with the English language file. You can translate it into other languages by copying the English
oxide/lang/en/Contracts.jsonorcarbon/lang/en/Contracts.jsonfile into a new language folder and translating the values. You can also edit the English text itself. See below for the full details.
Every message Contracts shows players goes through your framework’s localization system: chat messages, menu labels, buttons, statuses, condition text and popup text. On first load, the plugin registers its default English messages and the framework writes them to a language file. You can translate that file into other languages, or edit the English text itself.
Language files
Section titled “Language files”Alongside config, data and logs, your framework keeps a lang folder with one subfolder per language and
one JSON file per plugin. The default messages for Contracts live at:
oxide/lang/en/Contracts.jsoncarbon/lang/en/Contracts.jsonThe file is a flat JSON object. Keys identify messages and never change. Values are the text players see:
{ "contracts.commands.score_current": "Your Contract Score: <color=#ffc14d>{0}</color>.", "contracts.messages.contract_completed": "Contract Completed: <color=#ffc14d>{0}</color>", "contracts.ui.menu.accept_contract": "ACCEPT CONTRACT"}Adding a language
Section titled “Adding a language”-
Find the two-letter code of your language, e.g.
ru(Russian),de(German),fr(French),es(Spanish). -
Create the language folder next to
enif it doesn’t exist yet, and copy the English file into it:oxide/lang/en/Contracts.json→oxide/lang/ru/Contracts.jsoncarbon/lang/en/Contracts.json→carbon/lang/ru/Contracts.json -
Translate the values in the copied file. Leave the keys untouched.
-
Reload the plugin so the framework picks up your changes:
o.reload Contractsc.reload Contracts
Players whose Rust client runs in that language now see the translated messages automatically. Nothing else to configure.
Translation rules
Section titled “Translation rules”A few things must survive the translation, or messages will render wrong:
- Never translate the keys. The plugin looks messages up by key, so a translated key is a missing message and players would see the raw key instead.
- Keep the
{0},{1}, … placeholders. They are replaced at runtime with values like contract names or amounts. You can move a placeholder anywhere in the sentence to fit your language’s grammar, but if you delete one (or add one that doesn’t exist), the message breaks and falls back to English. - Keep the
<color=#ffc14d>...</color>tags. These are Unity rich text tags that highlight the important part of a message. Move them so they wrap the same words in your translation. You can also restyle them deliberately, as long as every opening tag keeps its closing tag. - Keep the JSON valid. Escape double quotes inside messages (
\") and keep the commas between entries. If the file fails to parse, the whole language falls back to English.
How a player’s language is chosen
Section titled “How a player’s language is chosen”You don’t assign languages to players. The framework resolves each message per player:
- The player’s language. Both Oxide and Carbon detect it automatically from the player’s Rust client language
and keep it in sync when the player changes it. On Oxide, players can also override it manually with the
/langchat command (e.g./lang ru). - The server’s language if the player’s language has no file. This is also what the server console uses. It
defaults to English. Change it with the
lang <code>console command on Oxide, or theLanguagesetting incarbon/config.jsonon Carbon. - English as the final fallback, per message: any key missing from a translated file shows its English text.
Because untranslated messages simply fall back to English, a partial translation is perfectly fine to ship on your server and finish over time.
After a plugin update
Section titled “After a plugin update”Plugin updates sometimes add new messages or remove old ones. The English file is kept in sync automatically on load: new keys are added, removed keys are cleaned up, and values you’ve customized are preserved. Translated files are synced too, but the new keys arrive with their English text (on Oxide they’re written into your file the first time the language is used, on Carbon they just fall back at runtime).
After updating the plugin, skim your translated file for English strings, or diff it against en/Contracts.json,
and translate whatever is new.
Customizing the English text
Section titled “Customizing the English text”Localization isn’t only for other languages. You can edit the values in en/Contracts.json to reword any message
on your server, then reload the plugin. Your customized values survive plugin updates. Only added and removed keys
change.
What localization does not cover
Section titled “What localization does not cover”Language files cover the plugin’s own messages, not your content or the game’s names:
- Contract, category and preset content (names, descriptions) lives in your data files and holds a single text per field, in whatever language you author it. Multi-language contract content is planned. See the roadmap.
- Item names shown in objectives and rewards come from the game’s item definitions.
- Entity and monument display names are curated by the plugin and currently English-only.
