For the complete documentation index, see llms.txt. This page is also available as Markdown.

Translate the Strings

Every word a player reads comes from one file. Nothing is written in the code, so a translation is a copy of that file and one line of config.

Where They Are

rm_mapeditor/locales/en.json

A flat JSON object, one key per string:

{
  "ui.tool.select": "Select",
  "ui.fill.go": "Fill it",
  "limit_reached": "Placement limit reached (%s)."
}

Keys with a ui. prefix are read by the interface; the rest are the messages that appear as a toast. Both halves of the resource read the same file, so a key that works in one works in the other.

Adding a Language

1

Copy the File

locales/en.json  ->  locales/de.json

Keep every key. A missing key shows up as the key itself, on purpose: an untranslated string has to be visible rather than blank, or it ships.

2

Translate the Values

Leave the keys alone and translate the right-hand side.

3

Point the Config at It

cfg.locale = 'de'

Restart the resource. A locale that is not there falls back to en and says so in the console.

Placeholders

%s is filled in by the resource, in the order it appears:

"import_done": "Imported %s of %s rows.",
"ui.session.reach_fixed": "%s m, set by whatever opened this session"

Keep every %s and keep them in that order. A string that loses one loses the number it was carrying.

Two Conventions Worth Keeping

Runtime features. Lights, hidden map pieces, collision and embedded light colour are named as a group in several places, because they behave as a group: they need a script running, so they only work while a layout is active. If you translate that phrase one way in the tag and another way in the settings, it stops reading as one idea.

What a key says about a press. A hint under a switch says what pressing it does next rather than what the switch is: "On, click to show every prop". It reads oddly out of context and correctly in it.