Skip to content

RedM Emotes FAQ

Do I need a framework?

No. It runs fully standalone. The framework is used for exactly two things — notifications, and resolving a player's job for restricted emotes.

Favourites, key binds, the library, adjust mode and sitting are all framework-independent, because identity comes from the steam identifier with a license fallback.

What do I actually need?

oxmysql and a MySQL or MariaDB database. The manifest declares dependency 'oxmysql', so FXServer starts it before this resource whatever order server.cfg uses.

It deliberately does not declare dependency '/assetpacks' — nothing is streamed, and that constraint is a licence-key entitlement check that could only fail the start for no benefit.

That is it. No npm or build step — the interface ships prebuilt. No keypress helper. No notification resource. No streamed assets.

Does it increase my server's download size?

Nothing is streamed — no stream/ folder, no game assets, no data_file entries. The resource stores animation names and asks the game to load them at runtime — every dictionary, scenario, ped model and prop it drives is already part of Red Dead Redemption 2.

What clients do download once, and then cache, is the interface bundle: about 3.3 MB — a 2.2 MB menu background, 0.3 MB of fonts, 0.4 MB of category artwork, 0.19 MB of JS and CSS, plus 0.12 MB of Lua, locales and config. sql/ is never sent to clients; it is not in the manifest's files block.

How many emotes are there?

208 from the language seed, which is the base install. Then optionally:

PackRows
walkstyles.sql12
scenarios.sql6
amount.sql4,133

Fully imported, 4,359 rows, plus 5 prop emotes and 4 shared emotes defined in config.

Should I import the 4,133-row bulk pack?

Import it if you want breadth. The practical cost is that the All tab becomes very long, and the menu renders at most 400 rows per tab — so players end up searching rather than browsing.

A common compromise is to import it and hide its noisiest category:

sql
UPDATE `rm_emotes` SET hidden = 1 WHERE id >= 5000 AND category = 'other';

Safe to re-import

All nine of its statements upsert with ON DUPLICATE KEY UPDATE, so re-running it rewrites its own 5000–9132 rows in place. Admin-created emotes land at 9133 and above, outside the range, and survive untouched.

The one thing a re-import overwrites is an edit you made to a pack row in the editor — the upsert puts the shipped values back.

Can I change the emote language later?

The interface language, yes — one line in config.lua and a restart.

The emote names, not in place. A second seed cannot overwrite the first. The only route is a full reset, but favourites survive it because the seeds use fixed ids. See Languages.

Can players add their own emotes?

No — only admins, through the in-game editor. There is one admin level and no per-action permissions.

Do I need a database client to add emotes?

No. The in-game Admin tab creates, edits, hides, restricts and deletes rows live and pushes the change to every connected player immediately. No restart, no relog.

You only need SQL for bulk work, or for scenario rows, which the form will not save without a dictionary.

I edited the table directly and nothing changed

The library is an in-memory cache read once at start. Call exports.rm_emotes:Rebuild(), restart the resource, or make the edit in the in-game editor.

What happens when I delete an emote?

It is removed from every player's saved list, and their key bind for it goes too — rm_emote_favs has ON DELETE CASCADE. There is no undo and no confirmation dialog.

Use hidden instead. Hiding is reversible, keeps the favourite row, and strips the emote from every non-admin push so there is nothing for a modified client to find.

Can players reach hidden or restricted emotes by editing their client?

Not through this resource. Hidden and restricted rows are removed before the library leaves the server — a client never receives the id, the dictionary or the clip name, so there is nothing for any in-resource path to select. The filter runs again server-side when a player tries to star one.

But be honest about the boundary

Playback itself is entirely client-side. A player running a modified client can call TaskPlayAnim with any dictionary and clip they already know, exactly as they could with no emote resource installed at all.

restricted is a content-visibility feature, not anti-cheat. Do not plan a monetisation tier around a guarantee the resource does not make.

Can I lock emotes to a VIP rank rather than a job?

Yes, and ACE is the right tool for it — it works identically on all four framework setups. Put rm_emotes.vip in the emote's Restriction field, then grant the ACE to a group. Adding or removing a player needs no database change.

Can one emote be shared by two jobs?

Not directly. restricted holds one value — no lists. Either duplicate the row, or grant one ACE to both groups and use that.

How is performance?

The library is read once into memory and every client is served from that cache, so it costs one query per rebuild regardless of library size.

The collection query is the one to watch: it is not cached and not rate limited, running once per star, unstar, key assignment and character load. It is a single indexed join. If you integrate from another resource, do not call pullCollection on a timer.

Does it conflict with my walk-style resource?

Yes. Both drive the same MP_Style_* natives, so the last writer wins — and this one re-applies the player's stored style 4 seconds after resource start and 6 seconds after character load, which will overwrite a style another resource set in that window.

Run one of the two. Either skip walkstyles.sql or remove the other resource.

Does it conflict with my sitting resource?

It registers its own prompt on 82 chair props, so players see two "Sit" prompts. Set RM.Seats.enabled = false in shared/seats.lua — that file stays editable on both editions.

Another resource already uses B or X

Turn off either key thread and drive the menu from your own keybinding system:

lua
RM.Keys = {
    open   = { active = false, control = 0x4CC0E2FE },
    cancel = { active = false, control = 0x7DA48D2A, forceStop = true },
}
lua
TriggerEvent('rm_emotes:client:open')

Keep the table in place — removing it errors at start.

Does it work with controllers?

Partly, and the split is predictable.

Works on a gamepadKeyboard or mouse only
Opening the menu and stopping an emoteThe menu itself — it is an NUI page with a mouse cursor and no gamepad navigation
The chair prompts — sit, stand, change style, rotateSaved-emote key binds and SHIFT+1..5, which poll raw Windows virtual-key codes
Accepting or declining a shared emote/e, /emotes and /adjustanim, which need the chat box
Adjust mode — move, rotate, height, confirm, cancelThe adjust-mode gizmo, which is dragged with the mouse

A gamepad player can open the menu, but needs a mouse to pick an emote.

Can I rename the resource folder?

Technically the menu would survive it, but don't. Exports are namespaced by folder name, so exports.rm_emotes:Play(...) in any other resource breaks immediately, and every ensure line, ACE example and SQL snippet in the docs assumes rm_emotes.

What are the two editions?

EscrowOpen Source
config.lua, locales/, shared/, sql/, all .mdEditableEditable
client/, server/, ui/EncryptedFull source
web/ (React interface source)Not includedIncluded

Both carry the same licence restrictions. Source access changes what you can read and edit, and nothing else — redistribution, resale and public publication are prohibited on both.

What can I do only on the Open Source edition?

Two things these docs point at:

  1. Adding a real bridge for a fifth framework — that means editing RMBridge.jobOf and RMBridge.notify, which live in encrypted files.
  2. Rebuilding the interface from web/ with npm run build.

Everything else in this documentation works on both. Escrow customers get RM.Framework, RM.NotifyMode and ACE-based restrictions, which covers most of what a custom bridge would have given you.

What counts as supported?

SituationSupported
Escrow edition with only the editable files changedYes
Open Source edition, interface rebuilt from web/Yes
Open Source edition with client/ or server/ Lua modifiedBest effort only — restore a clean copy of the modified files and confirm the problem still happens before reporting
VORP, RSG Core, RedEM:RP or no frameworkYes
Any other frameworkDegrades to standalone — ACE-only restrictions, and notifications need RM.NotifyMode
A second emote or animation resource running alongsideNo. Two resources issuing TaskPlayAnim and clearing ped tasks will fight
A separate walk-style resource alongside walk emotesNo. Pick one
oxmysql missingWill not work. The manifest declares dependency 'oxmysql', so a late ensure is not fatal — but with oxmysql absent the server refuses to start this resource and prints a could-not-find-dependency error

Will it keep working after a RedM update?

The manifest carries the standard RedM prerelease warning, and the licence makes no promise of compatibility with future game builds. A RedM or framework update can break behaviour that worked yesterday — that is a fix request, not a defect claim.

Is there a database to import?

Yes, and this is the one step you cannot skip. Exactly one language seed, which is the only file that creates either table. walkstyles.sql is recommended; the other two packs are optional.

See Database & SQL — particularly the parts about what a second seed does.

Where do I get help?

Work through Troubleshooting first, then gather what the support checklist asks for.

Redact two things before sending your config

RM.Webhook is a credential — anyone holding it can post into that channel. The identifiers in RM.Admins are personal data.

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