Adding 30+ Dances to an Emote Menu
This is the route most servers take, and the one the pack is built for.
redmorrow2 streams animations and does nothing else. The whole resource is fxmanifest.lua, a data table in clips.lua, two .ycd files in stream/, and the documentation. There is no menu, no command, no key binding, no events, no exports and no config options. Players reach the dances through the emote menu your server already runs, or through code of your own.
The pack's own three guides in docs/ say the same thing, and for this pack they are accurate.
The manifest loads no scripts at all
fxmanifest.lua has no client_scripts and no server_scripts. This is the structural fact that shapes the whole page:
clips.luais never loaded.Config.Clipsdoes not exist at runtime, on the client or on the server, and clients never download the file. It is a reference document that happens to be valid Lua.stream/is picked up automatically by CFX without a manifest entry, which is why the pack works with no scripts.- There is no
server.lua, so the pack prints no startup message of its own. The server console shows only the ordinary start line.
To read the list programmatically you have to load it from disk yourself — see Generating the rows.
Nothing is missing from your download
All 34 rows in clips.lua are live and nothing is commented out. Both dictionaries are present in stream/, both are referenced, and every clip name resolves. "30+" means 34, so the count is not short. The full list is on Dance list.
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 | redmorrow2@dance, or redmorrow2@dance@f for the female version |
| Clip name | The clip from Dance list |
| Flag | 1 — loop |
| Duration | Whatever the resource uses for "run until stopped", normally -1 |
| Loop setting | On. All 34 dances are mode = 'loop' |
| Blend-in, if exposed | 4.0, or 2.0 for the six floor moves |
| Label and category | Yours to choose |
Do not pass the figure from the duration column to the menu as a play time. That number is metadata the pack author wrote into clips.lua; nothing in the resource reads it, and a 2.467 s dance given a 2.467 s duration ends before the player has let go of the key. Use it to sort or label your menu, and let the loop flag decide when the dance stops. -1 means no time limit — with the loop flag the dance runs until something stops it.
Flags
RedM has its own eScriptedAnimFlags values. They are not GTA V's, so a flag word copied out of a FiveM emote resource will not mean here what it meant there.
| Use | Flag |
|---|---|
| Loop the dance | 1 |
| Play once | 0 |
| Play once and hold the last frame | 2 |
| Loop upper body only, so the player can walk | 1 + 8 + 16 = 25 |
For these dances, 1 is almost always what you want. The individual values are LOOPING 1, HOLD_LAST_FRAME 2, NOT_INTERRUPTABLE 4, UPPERBODY 8, SECONDARY 16 and ABORT_ON_PED_MOVEMENT 32; the mode field maps as 'loop' = 1, 'hold' = 2, 'once' = 0, with 8 + 16 added when walk is set. No row in this pack sets walk or flags.
Upper-body play looks wrong on these
These are full-body moves, breakdance especially. Flag 25 keeps the legs on the walk animation while the arms dance, which is useful for a wave or a salute and visibly broken on a headspin. Use 1 and let the dance own the whole body.
Two dictionaries, 34 clips, no exceptions
| Body | Dictionary |
|---|---|
| Male | redmorrow2@dance |
| Female | redmorrow2@dance@f |
That is the entire mapping. All 34 dances are in both dictionaries, under identical clip names. There are no per-dance dictionaries, and in every row dict equals bodies.male while bodies.female equals bodies.male with @f appended.
The naming is equally plain. Every row has id equal to clip, and no id, clip name or label is repeated anywhere in the pack. The clip name is the id, so there is nothing to derive and nothing to key around: a menu that stores rows by clip name works, and so does one that stores them by id.
A row in a generic emote resource therefore looks like this, with your resource's own field names:
{
label = 'Moonwalk',
command = 'moonwalk',
dict = 'redmorrow2@dance',
clip = 'moonwalk',
duration = -1,
loop = true,
}Thirty-three more rows differ from that one in three strings.
Handling both bodies
Every dance ships twice: a version fitted to the male body and one fitted to the female body. Both versions play on either body. Neither one breaks. The matching one fits better — a male-fitted dance on a female character reads as slightly off rather than wrong.
| If your menu | Then |
|---|---|
| Supports a per-body dictionary | Point female characters at redmorrow2@dance@f |
| Does not | Add each dance twice, labelled "(M)" and "(F)", or use the male version for everyone |
Adding each dance twice turns 34 rows into 68 and puts the choice on the player, which is honest but noisy. Using the male version for everyone is a legitimate choice if your menu cannot branch.
If your menu hands the dance to a function of yours, pick the dictionary there:
-- GET_META_PED_TYPE returns 0 for male and 1 for female.
-- Compare the number: 0 is truthy in Lua, so testing it as a boolean is wrong.
-- IsPedMale may come back as 0/1 rather than true/false on RedM, so handle both.
local function isFemale(ped)
if GetMetaPedType then
local ok, t = pcall(GetMetaPedType, ped)
if ok and t == 1 then return true end
if ok and t == 0 then return false end
end
local male = IsPedMale(ped)
return not (male == true or (type(male) == 'number' and male ~= 0))
end
local function dictFor(row, ped)
if isFemale(ped) then return row.dict .. '@f' end
return row.dict
endAppending @f is safe in this pack precisely because the pairing is mechanical in all 34 rows. More on the native side of this in Scripting the pack.
The six floor moves
Six moves begin on the ground rather than standing, and clips.lua gives each of them blendIn = 2.0 — about half a second — instead of the 4.0 every other row uses. The slower blend-in makes the character ease down to the floor instead of snapping to it.
| Clip | Name |
|---|---|
crossleg_freeze | Crossleg Freeze |
flair_1 | Flair (1) |
breakdance_footwork_1 | Breakdance Footwork 1 |
breakdance_footwork_3 | Breakdance Footwork 3 |
breakdance_footwork_to_freeze | Breakdance Footwork To Freeze |
breakdance_footwork_to_idle | Breakdance Footwork To Idle |
All six are in the breakdance group. If your emote menu exposes a blend-in setting, set 2.0 on these six rows and leave the other 28 at 4.0. If it does not expose one, they still play — they just arrive hard, and that is a cosmetic problem rather than a broken entry.
blendIn is the only optional field this pack uses. Lengths and the rest of the per-row detail are on Floor moves.
Groups, if your menu uses them
The resource's server owner guide suggests three groups, and they are worth applying because the split is exact and complete: 20 + 6 + 8 = 34, and every clip is in exactly one group.
| Group | Count | Clips |
|---|---|---|
| Breakdance | 20 | breakdance_ready, breakdance_uprock, breakdance_uprock_var_1_start, breakdance_uprock_to_ground, breakdance_1990, breakdance_1990_1, breakdance_footwork_1, breakdance_footwork_3, breakdance_footwork_to_freeze, breakdance_footwork_to_idle, breakdance_swipes, flair, flair_1, headspin_start, breakdance_freezes, breakdance_freeze_var_1, breakdance_freeze_var_2, breakdance_freeze_var_3, breakdance_freeze_var_4, crossleg_freeze |
| Hip hop | 6 | wave_hip_hop_dance, wave_hip_hop_dance_1, tut_hip_hop_dance, booty_hip_hop_dance, slide_hip_hop_dance, step_hip_hop_dance |
| Party | 8 | moonwalk, can_can, hokey_pokey, twist_dance, shopping_cart_dance, butterfly_twirl, bellydancing, silly_dancing_1 |
The split is not in the category field
Every one of the 34 rows carries category = 'dance' — a single flat category. The three groups above are prose in the resource's server owner guide, not data you can read. A menu built straight from category gets one undifferentiated list of 34.
Use the table above in your menu's own config, or rewrite category in clips.lua first and generate from that. category is one of the fields you are allowed to change — see The clips.lua table.
With RedM Emotes
RedM Emotes stores its library as rows, and each row carries a dictionary and a clip name. That is all these dances need, so they drop in like any other custom dictionary: one row per dance, with redmorrow2@dance (or redmorrow2@dance@f) as the dictionary, the clip name from the dance list, the loop setting on, 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, and because every row here has one dictionary pair and one clip name per dance, there is no special case to work around.
Start the pack before your emote menu
The dictionaries have to exist on the client before a player opens the menu and picks a dance:
ensure redmorrow2
ensure your_emote_menuStreaming does not actually 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. Download, upload and entitlement are on Installation.
Generating the rows instead of typing 34
Thirty-four rows is past the point where hand-typing is a good use of an evening. Generate them from the pack's own table instead.
This is the one place where the missing client_scripts line matters in practice. In a pack that loaded clips.lua, you could read a global or call an export. Here Config.Clips never exists at runtime, so a script has to read the file from disk and parse it. clips.lua is listed in escrow_ignore, so it ships readable, which is what makes this work.
LoadResourceFile is server-side, so the shape is: read it on the server, hand it to clients over an event.
Server side, in your own resource:
-- Returns redmorrow2's Config.Clips, or an empty table if the pack is not
-- installed or the file will not parse.
local function getDanceClips()
local src = LoadResourceFile('redmorrow2', 'clips.lua')
if not src then return {} end
local env = { Config = {} }
local chunk = load(src, '@redmorrow2/clips.lua', 't', env)
if not chunk or not pcall(chunk) then return {} end
return env.Config.Clips or {}
end
local danceClips = getDanceClips()
RegisterNetEvent('mydances:requestClips', function()
TriggerClientEvent('mydances:clips', source, danceClips)
end)The sandboxed env is the point. The file assigns to a global called Config, and running the chunk inside env keeps that assignment out of your own globals while still giving you the table.
Client side, in the same resource:
local danceClips = {}
RegisterNetEvent('mydances:clips', function(clips)
danceClips = clips
-- build your menu rows here
end)
CreateThread(function()
TriggerServerEvent('mydances:requestClips')
end)Rename the mydances:* events to fit your resource. Read it once at server start rather than per request; the file does not change while the server runs.
If your menu wants rows in a config file instead, print them and copy the output:
RegisterCommand('dancedump', function()
local clips = getDanceClips()
for _, c in ipairs(clips) do
print((" { label = '%s', dict = '%s', clip = '%s', duration = -1, loop = true },")
:format(c.label, c.dict, c.clip))
end
print(('-- %d rows'):format(#clips))
end, true)Change the format string to emit your resource's field names, a SQL INSERT, or a JSON array. Add c.dict .. '@f' to the line if you want the female dictionary in the same row, and c.blendIn or 4.0 if your menu takes a blend-in.
#clips is 34 and the array is contiguous
Nothing in clips.lua is commented out, so there is no filtering to do and no gap to skip. If you get 0, the pack is not installed where LoadResourceFile is looking — it takes the resource name redmorrow2, which is both the folder name and the manifest name.
Check one dance before you add all 34
Confirm the pack streamed. In the F8 client console:
luaDoesAnimDictExist('redmorrow2@dance')truemeans the dictionaries reached the client.falsemeans the resource is not started or the asset-pack entitlement check failed — see Troubleshooting.Add one row to your emote menu's config:
moonwalkout ofredmorrow2@dance, flag1, duration-1.Restart the emote resource, not just 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
redmorrow2@dance@f, so you have seen both bodies work before you paste in the other 33.Try one floor move —
crossleg_freeze— so you know whether your menu lets you soften the blend-in.Add the rest, generated rather than typed.
A clip from a dictionary that never loaded fails silently
No error in the server console, nothing in F8, the character just stands there. That is why step 1 is worth the ten seconds: it separates "the pack is not reaching the client" from "my menu row is wrong", and those two have nothing in common except the symptom.
Editing clips.lua does not change your emote menu
The two lists are separate, and this is the most common misunderstanding about packs shaped like this one.
clips.lua is a reference list that ships with the pack, and here the manifest does not even load it. Your emote menu has its own config, its own database table or its own file. Renaming a dance in clips.lua renames it in clips.lua and nowhere else — the new name has to be copied into the menu's own config as well. Equally, nothing in redmorrow2 reads your menu, so the pack cannot break it.
What you may and may not change in that file is covered in The clips.lua table. The short version: label, category, mode and walk are yours; dict and clip are not, because an RDR2 dictionary stores its own name inside the .ycd file.
Next
- Scripting the pack — the native call, the dictionary wait, stopping cleanly
- Dance list — all 34 with clip name and length
- The clips.lua table — every field in the row
- Installation — download, upload,
ensure, entitlement - Troubleshooting — symptom, cause, fix
- FAQ — the short answers
- Animation Basics — how two resources end up fighting over one character
- 24+ Dances — the sibling dance pack, 27 dances. Different dictionary names, so both packs can run on the same server
- 30+ Female Poses — a pack that does ship its own menu, so none of this page applies to it
Still stuck? Ask in Discord.