Skip to content

RedM Emotes Languages

RedM Emotes has two independent language settings, and mixing them up is the most common localisation complaint.

Set bySource
Interface text — menu labels, tab names, notificationsRM.Lang in config.lualocales/*.lua
Emote names — the label on every cardWhich SQL seed you importedThe custom_name column
Prop & shared emote names — the nine extrasEditing each entry's name field (neither RM.Lang nor the SQL seed reaches them)shared/extras.lua

Set both to the same language, or you get French emote names inside an English menu. They can legitimately disagree, and nothing warns you.

The six shipped languages

Both halves ship in the same six:

English   French   German   Greek   Spanish   Portuguese
  • locales/english.lua, french.lua, german.lua, greek.lua, spanish.lua, portuguese.lua
  • sql/english.sql, french.sql, german.sql, greek.sql, spanish.sql, portuguese.sql
lua
RM.Lang = 'English'   -- case-sensitive; must match a table name defined in locales/*.lua

An unknown value silently falls back to English at every read site rather than erroring — so a typo shows up as an English menu, not an error.

The match is against the table name (RM.Text.French), not the file name, and it is case-sensitive'french' does not match RM.Text.French. That mismatch is the usual cause of a menu that stays English after a translation.

The optional packs are not translated. walkstyles.sql, scenarios.sql and amount.sql exist in one version only and their names are always English — "Normal Walk", "Sit on Ground", "2h Tool Working (M)". Only the 208-row base seed changes with the language you pick, so translate the pack rows in place with the UPDATE method below if you need them in your own language.

The strings that stay English

Regardless of RM.Lang:

  1. The /e and /adjustanim chat autocomplete suggestions, including the /e argument help e.g. wavehello / stop / random.
  2. The gizmo key-binding label RM Emotes: toggle adjust gizmo, registered through RegisterKeyMapping — this is the entry players see in RedM's own key settings, so it is the one a non-English server notices first. It is not a broken translation.
  3. The preview-model failure notice, and the literal RM Emotes title it is sent with.
  4. The Category and Type dropdown values in the admin editor — those are the raw database values, deliberately untranslated.

Server-side log and audit strings — including the Discord webhook embeds — and the [rm_emotes] console lines are hard-coded English too.

Switching the interface language

One line, then restart the resource:

lua
RM.Lang = 'Spanish'

That is the whole operation. No database change, no player impact, nothing to migrate.

Switching the emote names

This one is not so easy. There is no in-place route.

A second seed cannot replace the first

The seeds cannot overwrite each other. Importing a second one collides on the primary key, the whole 208-row insert rolls back, and the previously installed language is left completely intact.

It is harmless — no file in sql/ contains a DROP, and every seed carries a comment saying it deliberately does not drop rm_emote_favs. It simply achieves nothing.

The only route is a full reset, and the good news is that favourites survive it — because the seeds use fixed ids, a favourite pointing at a seeded emote still points at the right emote afterwards.

  1. Back up favourites:
    sql
    DROP TABLE IF EXISTS `rm_emote_favs_backup`;
    CREATE TABLE `rm_emote_favs_backup` AS SELECT * FROM `rm_emote_favs`;
  2. Drop the child table, then the parent:
    sql
    DROP TABLE `rm_emote_favs`;
    DROP TABLE `rm_emotes`;
  3. Run the new language seed.
  4. Re-run walkstyles.sql, scenarios.sql and amount.sql if you were using them — they exist in one version only, so those names come back English whichever seed you chose.
  5. Restore favourites, filtered so any pointing at an emote that no longer exists are dropped rather than failing the foreign key:
    sql
    INSERT IGNORE INTO `rm_emote_favs` (steam_id, emote_id, key_bind)
    SELECT b.steam_id, b.emote_id, b.key_bind
    FROM `rm_emote_favs_backup` b
    JOIN `rm_emotes` e ON e.id = b.emote_id;
    
    DROP TABLE `rm_emote_favs_backup`;
  6. Restart the resource, or call exports.rm_emotes:Rebuild().

The nine props and shared emotes are not database rows, so the seed you just imported did not touch them — they still read English. Rename the name field of each entry in shared/extras.lua and restart the resource. That also rewrites their /e slugs, which are derived from name the same way: rename Dance Together to Danser ensemble and /e dancetogether becomes /e danserensemble. Extras have no command column to pin a slug with, so any exports.rm_emotes:PlayByCommand('dancetogether') call in another resource has to be updated too.

Full detail in Database & SQL.

Adding your own interface language

Copy locales/english.lua, rename the file, and define your own table:

lua
-- locales/dutch.lua
RM.Text.Dutch = {
    -- same keys as english.lua, translated values
}

Then:

lua
RM.Lang = 'Dutch'

The manifest loads locales/*.lua as a glob, so a new file is picked up with no manifest edit. locales/ is in escrow_ignore, so this works on both editions.

Keep every key

RM.Lang falls back to English per read site, not per file — but a missing key in your own table is a nil lookup, not a graceful fallback. Copy the whole English file and translate in place rather than starting from an empty table.

Translating emote names in place

You do not have to switch seeds wholesale. Emote names are just a column, so you can translate individual rows:

sql
UPDATE `rm_emotes` SET custom_name = 'Zwaaien' WHERE id = 42;

Then rebuild the cache. Two things to be aware of:

  • The /e slug is derived from custom_name unless an explicit command is set. Renaming an emote changes the command players type for it. If people have learned a slug, set command explicitly before you rename.
  • Slugs strip every non-alphanumeric character, so accented letters vanish rather than transliterating: Zwaaien gives zwaaien, but Grüßen gives gren. Set command explicitly for anything with accents.

Encoding

Locale files. Save locales/*.lua as UTF-8 without a byte-order mark — all six shipped files are, and each starts straight with the --[[ header. In VS Code the status bar must read UTF-8, not UTF-8 with BOM and not Windows 1252; in Notepad++ use Encoding > UTF-8, the entry without "BOM", never "ANSI". Never edit a locale file in a word processor. The wrong encoding shows up as é for é and â€" for , and the em dash in shared_request, more_results and preview_hint — the only non-ASCII characters in locales/english.lua — is usually the first thing to break. Replace it with a plain hyphen if your toolchain is unreliable.

The database. Both tables are utf8mb4 with utf8mb4_general_ci collation, so accented characters, Greek and emoji all store correctly.

If names come back as mojibake after a manual import, the file was almost certainly read as latin-1. Re-import with the connection charset set explicitly:

bash
mysql --default-character-set=utf8mb4 DBNAME -u DBUSER -p < sql/greek.sql

Documentation for RedMorrow. Scripts are licensed per server — redistribution is not permitted.