RedM Emotes Languages
RedM Emotes has two independent language settings, and mixing them up is the most common localisation complaint.
| Set by | Source | |
|---|---|---|
| Interface text — menu labels, tab names, notifications | RM.Lang in config.lua | locales/*.lua |
| Emote names — the label on every card | Which SQL seed you imported | The custom_name column |
| Prop & shared emote names — the nine extras | Editing 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 Portugueselocales/english.lua,french.lua,german.lua,greek.lua,spanish.lua,portuguese.luasql/english.sql,french.sql,german.sql,greek.sql,spanish.sql,portuguese.sql
RM.Lang = 'English' -- case-sensitive; must match a table name defined in locales/*.luaAn 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:
- The
/eand/adjustanimchat autocomplete suggestions, including the/eargument helpe.g. wavehello / stop / random. - The gizmo key-binding label
RM Emotes: toggle adjust gizmo, registered throughRegisterKeyMapping— 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. - The preview-model failure notice, and the literal
RM Emotestitle it is sent with. - 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:
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.
- Back up favourites:sql
DROP TABLE IF EXISTS `rm_emote_favs_backup`; CREATE TABLE `rm_emote_favs_backup` AS SELECT * FROM `rm_emote_favs`; - Drop the child table, then the parent:sql
DROP TABLE `rm_emote_favs`; DROP TABLE `rm_emotes`; - Run the new language seed.
- Re-run
walkstyles.sql,scenarios.sqlandamount.sqlif you were using them — they exist in one version only, so those names come back English whichever seed you chose. - 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`; - 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:
-- locales/dutch.lua
RM.Text.Dutch = {
-- same keys as english.lua, translated values
}Then:
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:
UPDATE `rm_emotes` SET custom_name = 'Zwaaien' WHERE id = 42;Then rebuild the cache. Two things to be aware of:
- The
/eslug is derived fromcustom_nameunless an explicitcommandis set. Renaming an emote changes the command players type for it. If people have learned a slug, setcommandexplicitly before you rename. - Slugs strip every non-alphanumeric character, so accented letters vanish rather than transliterating:
Zwaaiengiveszwaaien, butGrüßengivesgren. Setcommandexplicitly 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:
mysql --default-character-set=utf8mb4 DBNAME -u DBUSER -p < sql/greek.sql