Installing RedM Emotes
Requirements
| Requirement | Detail |
|---|---|
| RedM artifacts | Any build supporting fx_version 'cerulean' and lua54 'yes'. Saved-emote key binds additionally need a build exposing the IsRawKeyDown native — on an older build the raw listener thread exits on its first line, silently, and letter binds plus SHIFT+1..5 never fire |
| Asset packs | Not required. The manifest deliberately does not declare dependency '/assetpacks' — nothing is streamed, so no licence-key entitlement is involved in starting the resource |
| oxmysql | Started before this resource. There is no fallback and no second database layer |
| MySQL / MariaDB | One schema. Two tables: rm_emotes, rm_emote_favs |
| Framework | Optional. VORP Core, RSG Core, RedEM:RP, or none |
Not required: no npm or build step (the interface ships prebuilt in ui/), no keypress helper resource, no notification resource.
Where to unzip
Anywhere your server already loads resources from:
resources/[rm]/rm_emotes
resources/[standalone]/rm_emotesKeep the folder named rm_emotes
The resource resolves its own name at runtime, so the menu itself would survive a rename — but exports are namespaced by folder name. Another resource calling exports.rm_emotes:Play(...) breaks the moment you rename it, and every ensure line, ACE example and SQL snippet in these docs assumes rm_emotes.
Do not nest it inside another resource folder, and strip any version suffix like rm_emotes-2.1.0.
A correct tree:
rm_emotes/
fxmanifest.lua
config.lua
client/ server/ shared/ locales/ ui/
sql/
install/
docs/web/ is present only in the Open Source edition. Its absence is not a fault.
server.cfg, and why the order matters
ensure oxmysql
ensure vorp_core # or rsg-core / redem_roleplay — omit on standalone
ensure rm_emotes
add_ace group.admin rm_emotes.admin allowTwo separate reasons the order is not optional:
oxmysql must be up first. The server reads the whole library on onResourceStart. If oxmysql is not connected, the library is empty and every database-backed tab shows zero. Shared and Props still show their entries — those come from shared/extras.lua and are merged in client-side, so they fill with no database at all.
Your framework must be up first. Detection runs once, at script load. It tests vorp_core, then rsg-core, then redem_roleplay, accepting either starting or started. A core that starts after RedM Emotes is never re-detected, and the resource behaves as standalone for the rest of its lifetime — no job restrictions, and notifications land in chat instead of your framework's notify.
If you cannot control the order, set both explicitly rather than leaving them on 'auto':
RM.Framework = 'vorp'
RM.NotifyMode = 'vorp'Import the SQL
Full detail in Database & SQL. The short version for a fresh install:
| Step | File | Required | What it adds |
|---|---|---|---|
| 1 | Exactly one of english, french, german, greek, spanish, portuguese``.sql | Yes | 208 emotes, ids 4–220. The only file that creates either table |
| 2 | walkstyles.sql | Recommended | 12 walk styles, ids 1000–1011 |
| 3 | scenarios.sql | Optional | 6 world scenarios, ids 4900–4905 |
| 4 | amount.sql | Optional | 4,133 animations, ids 5000–9132. 546 KB — import last |
Steps 2, 3 and 4 are order-free between themselves. All of them must come after step 1.
Three rules that are easy to get wrong
Pick one language and stick to it. A second seed does not translate anything — its INSERT collides on the primary key and the whole statement rolls back, so the installed language stays exactly as it was. Switching language means a full reset; see Languages.
Do not run upgrade_2.1.sql on a fresh install. The seeds already contain the 2.1 columns. It fails with #1060 - Duplicate column name 'command'.
Import the packs before you start creating emotes in the editor. Not for safety — the packs upsert and destroy nothing — but because each one sets AUTO_INCREMENT past its own range, and planning that once is easier than working around it later.
Clear the sample admin identifier
Do this before your first public start. config.lua ships with a real identifier in the admin list:
RM.Admins = {
'steam:11000014864548d',
}That is a sample value, not a placeholder the code ignores. Anyone connecting with that exact identifier gets the full in-game editor — create, edit, hide, restrict and delete — plus visibility of every hidden and restricted emote on your server.
Empty it and use the ACE instead:
RM.Admins = {}add_ace group.admin rm_emotes.admin allowEither grant works; they are checked with OR.
RM.Admins is cached on first use
The list is read once and never rebuilt. Editing it needs a resource restart — refresh is not enough.
Match the language (optional)
RM.Lang picks the interface strings. It is independent of the SQL seed you imported — emote names come from the database, menu text comes from locales/*.lua.
RM.Lang = 'English' -- English, French, German, Greek, Spanish, PortugueseSet both to the same language, or you get French emote names inside an English menu. An unknown value falls back to English rather than erroring. See Languages.
First start
Start the server, or run refresh then ensure rm_emotes.
A correct start is silent. The resource prints nothing on success — just the normal resource line:
Started resource rm_emotesThe client F8 console is silent too. There are exactly three print calls in the resource and all three are failure paths:
| Console line | Meaning |
|---|---|
[rm_emotes] preview model "<model>" failed to load | The mannequin model could not stream |
[rm_emotes] ghost model "<model>" failed to load | Adjust mode fell back to moving your real character |
[rm_emotes] aim placement unavailable on this build, using manual nudging | Crosshair placement off; keys and gizmo still work |
Any line naming rm_emotes alongside a SQL error comes from oxmysql, not from this resource, and means the tables are missing or are still on the 2.0 schema.
The library is a cache
Worth internalising before you touch anything:
The server reads
SELECT * FROM rm_emotesonce and serves every player from memory.
Editing the table in a SQL client changes nothing in game until you restart the resource, call exports.rm_emotes:Rebuild(), or save something in the in-game editor. See Making the server notice.
Verify it works, in two minutes
Each step tests a different subsystem, so the first failure tells you where to look.
- Menu opens.
/emotesor B. Tab counts appear on the left. Every tab except Shared and Props reading zero means the seed did not import, or oxmysql is not connected. Those two are never evidence that the import worked. - Playback works. Click any card in Actions. Press X to stop.
- Quick command works. Read the
/e <name>hint on a card, close the menu, type it. Then/e stop, then/e random. - Favourites persist. Star a card, press SHIFT+1, reconnect — the star is still there. If it vanishes, your identity is not resolving.
- Key binds work. Click the key chip on a quick slot, press a letter, close the menu, press it.
- Walk styles persist. Walks tab, pick one, reconnect. An empty Walks tab means
walkstyles.sqlwas not imported. - Adjust mode opens. Play a looping emote, then
/adjustanim. A translucent double appears; G toggles the gizmo. - Sitting works. Stand still next to a chair. A Chair prompt appears within about two seconds — the scan does not run while you are moving.
- Admin tab appears. With the grant in place, reconnect. Create a test emote and confirm a second player sees it without a restart.
- Layout switch persists. Switch Grand ↔ Compact, close the menu, reopen.
Upgrading from 2.0
Only if you already have a populated rm_emotes table from 2.0 and want to keep it — and your players' saved emotes with it.
- Back up the database. This is the one path where a mistake costs live player data.
- Replace the resource folder, keeping your
config.lua,locales/andshared/edits. - Run
sql/upgrade_2.1.sqlonce. It adds the five columns 2.1 needs —command,emote_type,restricted,hidden,upper_body— and backfills existing rows with the defaults, so every old emote stays a visible, unrestricted, full-body animation. - Only now import
walkstyles.sql,scenarios.sqloramount.sql. All three writeemote_typeand fail with#1054 - Unknown column 'emote_type'on a 2.0 table. - Compare the new
config.luaagainst your old one rather than pasting the old file over it. refresh, then start the resource.
Do not import a language seed on top of an existing install. It cannot upgrade anything — the CREATE TABLE IF NOT EXISTS is a no-op and the INSERT rolls back on the first duplicate id, so the run simply does nothing.
Next
- Database & SQL — schema, every file, import order, the traps in full
- Configuration — every key and what removing it does
- Admin guide — the editor, hidden and restricted emotes