Integrating Everyday Animations
This is the route most servers take, and the one the pack is shaped for.
The resource streams animations and ships a list of them. It is fxmanifest.lua, a data table in clips.lua, a one-line server.lua, and 38 .ycd files in stream/. There is no client script, so nothing inside the pack plays an animation — players reach these through the emote menu your server already runs, or through code of your own.
That turns out to be the easy case, because an emote menu asks for exactly what this pack is made of.
What an emote menu needs from you
Every emote system reduces a custom animation to the same small set of values. Whatever the fields are called in your resource, these are what to put in them:
| What the menu asks for | What to give it |
|---|---|
| Dictionary | The dictionary from the animation list — one of 19 |
| Clip name | The id. On all 94 rows the clip name is the id |
| Flag | 1 to loop. See Flags below |
| Duration | Whatever the resource uses for "run until stopped", normally -1 |
| Loop setting | On for the 46 loop rows, off for the 48 once rows |
| Label and category | Yours to choose |
Two properties of the data make this mechanical rather than fiddly, and they hold on every row with no exceptions:
clip == id
bodies.male == dict
bodies.female == dict .. '@f'So one line in the list gives you both strings for a male row and both for a female row. There is nothing to look up twice and nothing to cross-reference. The proof per row is in Every dictionary ships twice.
A row in a generic emote resource therefore looks like this, with your resource's own field names:
{
label = 'Salute',
command = 'salute',
dict = 'rm@salute',
clip = 'salute',
duration = -1,
}Ninety-three more rows differ from that one in three strings.
Do not build the dictionary from the id
'rm@' .. id is correct for the 15 Greetings & Social animations, which each have a dictionary of their own, and wrong for the other 79, which live in four shared dictionaries — rm@communication_gestures, rm@reactions_expressions, rm@standing_idle and rm@casual_actions.
'rm@' .. 'salute' is rm@salute and plays. 'rm@' .. 'yawn' is rm@yawn, which does not exist, and a clip asked for from a dictionary that never loaded fails silently — no console error, no warning, the character stands there. Read dict off the row instead of constructing it.
Flags
RedM has its own animation flag values, and they are not GTA V's. A flag word copied out of a FiveM emote resource will not mean here what it meant there, which is the single most common reason a row that looks right behaves oddly.
Flag 1 — loop — is the known-good value for this pack and the one to start from. If your menu exposes other flag values, set one animation up with them and watch it in game before you apply it to the rest; guessing from a FiveM number is how a whole category ends up subtly wrong. Playing an animation covers the native call, where RDR3's TaskPlayAnim takes thirteen arguments.
Duration -1 means no time limit. Combined with the loop flag, the animation runs until something stops it.
Do not pass the duration figure to the menu as a play time
The numbers in the list are metadata the pack author wrote into clips.lua. Nothing reads them, and a 1.967-second gesture given a 1.967-second play time is over before the player has let go of the key. Use the figure to sort or label your menu, and let the loop flag and your stop control decide when the animation ends. GET_ANIM_DURATION is the authority on what the game thinks a clip's length actually is.
The 15 greetings ship as loop, and they are one-shot gestures
Every row in Greetings & Social carries mode = 'loop' in the list, but a 0.533-second waving on repeat reads as a twitch rather than a wave. Set your menu's loop setting off for those 15 unless you specifically want them repeating. The split across all 94 is 48 once and 46 loop — see Lengths.
Handling both bodies
Every animation ships twice: a version fitted to the male body and one fitted to the female body, under an identical clip name. Both versions play on either body. Neither one breaks. The matching one fits better — a male-fitted gesture on a female character reads as slightly off rather than wrong.
| If your menu | Then |
|---|---|
| Supports a per-body dictionary | Point female characters at dict .. '@f' |
| Does not | Add each animation twice, labelled "(M)" and "(F)", or pick one version for everyone |
Adding each one twice turns 94 rows into 188 and puts the choice on the player, which is honest but doubles the list. Using the male version for everyone is a legitimate choice if your menu cannot branch, and most of these animations are gestures where the difference is small.
If your menu hands the animation to a function of yours, pick the dictionary there:
-- isFemale comes from your own character data. On this pack the female
-- dictionary is always the male one with '@f' appended, so there is nothing
-- to look up.
local function dictFor(row, isFemale)
if isFemale then
return row.dict .. '@f'
end
return row.dict
endPrefer your server's own character-sex field over IsPedMale
IsPedMale is reliable on standard multiplayer and story peds and can be wrong on heavily customised ones. If your framework already stores a sex on the character — and in a roleplay server it almost always does — read that instead. It is the value the player picked, which is also the value they expect their animations to follow.
Appending @f is safe here precisely because the pairing is mechanical on all 94 rows. All 38 files are present: 19 dictionaries times two bodies, none missing and none left over.
With RedM Emotes
RedM Emotes stores its library as rows, and each row carries a dictionary and a clip name. That is all these animations need, so they drop in like any other custom dictionary: one row per animation, the dictionary from the list, the clip name equal to the id, the loop setting to taste, and a label of your choosing.
The three supported ways to add a row, the exact column names, and the cache rebuild you need afterwards are documented at Three ways to add an emote. Nothing about this pack changes that procedure.
Two things are worth deciding before you start inserting rows, because both are cheaper to settle up front than to unpick in a library of a few thousand entries:
- The label and the category are yours. Several ids in this pack read as filenames rather than as names —
idle_clip,good_by,hand_in_back— and the two long ones read as sentences. The id has to match the clip; the label a player sees does not. - Two ids appear twice.
pointingandpointing_gestureeach exist in two different dictionaries, so two of your rows will want distinct names. See Generating the rows below.
Generating the rows instead of typing 94
Ninety-four rows is past the point where hand-typing is a good use of an evening, and hand-typing is exactly where a wrong dictionary gets introduced as a bug you then have to find.
Because the clip name equals the id on every row, a row is fully determined by two strings — the id and the dictionary. Take those from the animation list, then emit whatever shape your menu wants:
local rows = {
{ id = 'salute', dict = 'rm@salute' },
{ id = 'yawn', dict = 'rm@communication_gestures' },
{ id = 'laughing', dict = 'rm@reactions_expressions' },
-- ... 91 more
}
for _, r in ipairs(rows) do
print((" { label = '%s', dict = '%s', clip = '%s', duration = -1 },")
:format(r.id, r.dict, r.id))
endChange the format string to emit your resource's field names, a SQL INSERT, or a JSON array. Add a second line using r.dict .. '@f' if you want the female rows generated in the same pass.
Three things need handling before you run a generated list past a player.
The two duplicate ids
pointing and pointing_gesture each appear twice — once in rm@communication_gestures, once in a standalone dictionary of their own. A generator keyed on id writes one of each pair and silently loses the other, or produces two menu rows with the same name that players cannot tell apart.
Key on the dictionary and the clip together, or rename one side. Full detail, including the lengths that differ, is in Duplicate ids.
The two very long ids
Two ids were generated from source filenames and run past sixty characters. They work, but they are awkward in a command and ugly in a menu row. Rename the id and the label in your own menu — yoga_tree_pose and reading_map read far better — and leave the clip string alone, because an RDR2 dictionary stores its own name inside the .ycd file. The pair is listed in Two very long ids.
Copying out of clips.lua gives you 15 rows, not 94
This is the trap worth knowing about before you point a script at the file.
clips.lua contains five Config.Clips blocks. One is live — the 15 Greetings & Social rows — and four are commented out. A script that loads the file and reads the table gets 15 entries and no indication that anything else exists.
Nothing is missing from your download
All 38 .ycd files ship, and every one of the 94 clip names resolves inside them. An emote menu given a dictionary and a clip name plays any of the 94 today. The commented blocks are a state of one text file, not a gap in the assets.
Two consequences, depending on how you work:
- In a text editor, all 94 rows are in the file.
clips.luais listed inescrow_ignore, so it ships readable; stripping the leading comment markers from the four blocks gives you every row as data, which a find-and-replace can reshape into your menu's format. - In a script, uncommenting the blocks is not enough.
Config.Clipsassigns rather than appends, so five live blocks leave only the last one and silently discard the other four. Merge all 94 into a single table, and resolve the duplicate ids while you are in there. More on the file in The clips.lua file.
The animation list on this site is generated from all 94 rows, which makes it the easier source of the two.
Which animations suit which use
The pack covers a wide spread of lengths and behaviours, and the groups are not interchangeable. Deciding where each kind belongs is most of the design work.
| Use | Reach for | Why |
|---|---|---|
| A long scene — sitting in a saloon, waiting on a porch, an NPC on a shop floor | The five 89-second idles, and batter_on_deck at 37.333 s | Long enough that nothing visibly repeats while a conversation happens |
| A social moment — a greeting, a laugh, a shrug, an insult | The 48 one-shot rows in Communication Gestures and Reactions & Expressions | They have a beginning and an end, so they read as a single action and release |
| A screenshot | The five single-frame poses, plus the standing and leaning idles | A held position, framed on purpose |
| Anything with space around it | The four root-motion clips | They move the character, so they need room |
The five 89-second idles — idle_clip, idle_2_clip, idle_3_clip, idle_6_clip and idle_8_clip — are the longest things in the pack by a wide margin. Set them to loop and they hold a scene indefinitely without the loop point being obvious.
The one-shot gestures are the 32 Communication Gestures and the 16 Reactions & Expressions, all 48 of them mode = 'once' in the list. Setting aside male_sitting_pose, which is a single-frame pose sitting in that group, the shortest is clapping at 1.167 s and the longest one-shot in the pack is terrified at 20.000 s. These are the rows to put behind a quick-access wheel or a chat command, because a player triggers one and gets on with the scene.
The five single-frame poses carry duration = 0.033 — one frame at 30 fps. They are poses, not animations: they need loop or hold-last-frame behaviour to be usable, and played once they flash and vanish. Which five, and which way each one ships, is in Single-frame poses.
The four root-motion clips move the character across the ground rather than animating in place. Play them full body, and keep them off a porch edge, a rooftop or a crowded saloon floor, where a character drifting off its mark is the difference between a nice moment and a player wedged in a wall. The four are named in Root-motion clips.
Nine rows start seated or kneeling
Nine animations carry a blendIn of 2.0 in the list — roughly half a second, slower than the default — because they begin on the ground. If your menu exposes a blend-in setting, use that figure on those nine and leave the rest at the default. If it does not, they still play; they arrive hard, which is a cosmetic problem rather than a broken row. The nine are listed in Special cases.
Start the pack before your emote menu
The dictionaries have to exist on the client before a player opens the menu and picks something:
ensure rm_everyday_v1
ensure your_emote_menuStreaming does not strictly depend on start order — CFX collects stream/ whenever the resource starts — so position in server.cfg is not critical. Putting the pack first is a habit worth keeping anyway, because it rules the question out when you are debugging something else.
The ensure line follows the folder, not the manifest
In CFX the resource name is the directory name on disk. The name field in fxmanifest.lua is metadata and renames nothing, so whatever the folder is called is what ensure has to say. If you rename the folder, change the ensure line to match in the same sitting.
The dictionary names are baked into the .ycd files either way, so your menu rows never change when the folder does. Download and entitlement are on Installation.
Check one animation before you add all 94
Confirm the pack streamed. In the F8 client console:
luaDoesAnimDictExist('rm@salute')truemeans the dictionaries reached the client.falsemeans the resource is not started, theensureline does not match the folder name, or the asset-pack entitlement check failed — see Troubleshooting.Add one row to your emote menu:
saluteout ofrm@salute, flag1, duration-1.Restart the emote resource, not only the pack. Most emote menus read their config once at start and will not see your edit until they do.
Play it, then play it on a female character with
rm@salute@f, so you have seen both bodies work before you paste in the other 93.Try one row from a shared dictionary —
yawnout ofrm@communication_gestures— so you have proved the four big dictionaries work as well as the single-animation ones.Try one single-frame pose and one root-motion clip, which are the two kinds most likely to need a setting your menu may or may not expose.
Add the rest, generated rather than typed.
That first check is worth the ten seconds
A clip from a dictionary that never loaded produces no error in the server console and nothing in F8. The character stands there, which is also what a wrong clip name looks like, and what a menu row with a typo looks like. Confirming the dictionary exists separates "the pack is not reaching the client" from "my row is wrong", and those two have nothing in common except the symptom.
The pack has no menu of its own
Worth saying plainly at the end, because it decides what your players actually experience.
This resource makes 94 animations available on the client and stops there. Everything a player sees or does — the menu, the labels, the grouping, the stop control, the key binding, who is allowed to use which animation, whether a gesture loops — belongs to whatever you wire it into. Rename good_by to "Farewell" in your menu and that is the name of the animation on your server. Hide the root-motion clips behind a photo mode and nobody will ever trip over them.
The pack's job is to put the clip on the client. The rest is yours, and the list is the only thing you have to be faithful to.
Next
- Playing an animation — the native call, the dictionary wait, stopping cleanly
- Animation list — all 94 with dictionary, clip name and length
- The clips.lua file — every field, and the four commented-out blocks
- Installation — download, upload,
ensure, entitlement - Troubleshooting — symptom, cause, fix
- FAQ — the short answers
- Animation Basics — how two resources end up fighting over one character
- 100+ Female Poses — a sibling asset pack, with the same shape and different dictionary names, so both can run on one server
- 24+ Dances and 30+ Dances — dance packs built the same way
Still stuck? Ask in Discord.