Skip to content

24+ Dances ​

27 dance animations for RedM, streamed as native RDR2 .ycd dictionaries: 24 main dances plus 3 bonus ones, each with a male version and a female version, listed in a readable clips.lua.

It is an asset pack. It streams the animations and tells you what they are called. It does not play them for you — there is no menu, no chat command, no keybind and no export. The dances reach your players through an emote menu you already run, or through your own script.

No framework No database 27 dances Male and female All looping Asset pack — no menu

The 60-second version ​

  1. Unzip into resources, keeping the folder name rm_dance_24:

    text
    resources/[animations]/rm_dance_24
  2. Add one line to server.cfg:

    cfg
    ensure rm_dance_24

    Position does not matter. Before your emote menu is a good habit.

  3. Restart, or from the server console:

    text
    refresh
    ensure rm_dance_24
  4. Check the server console. server.lua prints one line, and that line is the whole of its server-side behaviour:

    text
    [redmorrow_dance_24] Dance animation pack started.

No framework, no database, no SQL, no build step. One ensure line and nothing else.

The console line says redmorrow_dance_24, the ensure line says rm_dance_24

Both are correct. redmorrow_dance_24 is the name field in fxmanifest.lua, which is metadata the print statement quotes. rm_dance_24 is the folder on disk, which is what CFX actually calls the resource. The ensure line must match the folder.

Nothing happens in game yet, and that is correct

That console line is the only confirmation the pack gives you. There is no key to press and no command to type. Until an emote menu or your own code calls TaskPlayAnim, the 8 dictionaries sit on the client unused.

Go to Emote menus or Playing a dance next.

Your server key needs asset packs enabled

The manifest declares dependency '/assetpacks', a Cfx.re licence-key entitlement check. Without it the resource refuses to start, and nothing in the resource can work around it. See Installation.

This is an asset pack, not an emote menu ​

This is the thing most worth knowing before you install it. The resource is a manifest, a data file, a one-line server script and eight animation files:

fxmanifest.luacerulean, rdr3, lua54 'yes'. Loads clips.lua as a client script and server.lua as a server script. Declares dependency '/assetpacks'
clips.luaA data table and nothing else. Sets the global Config.Clips — 27 rows, all 27 live
server.luaOne line. A print that confirms the resource started
stream/8 .ycd dictionaries, 4.0 MB total
README.md, CHANGELOG.md, LICENSE.md, docs/*.mdReadable, and accurate for this build

There is no client.lua, no config.lua and no html/ folder. So:

Not in this packConsequence
No client.luaNothing requests a dictionary or calls TaskPlayAnim. No dance can play on its own
No menu, no NUIPlayers have nothing to open
No RegisterCommandThere is no chat command
No key bindingThere is no key to press
No exportsexports['rm_dance_24'] has no methods on it
No eventsNothing to trigger from the server or from another client script
No config.luaThere are no settings to change. Everything tunable lives in clips.lua

The sibling 30+ Female Poses pack does ship a menu, a command and five exports, and can be handed to players as-is. This one cannot. Owning both is not the same experience, so if you were expecting the same shape, that is the difference. The other sibling, 100+ Female Poses, is assets-only like this one.

There are two routes to actually using it:

RoutePage
Feed the 27 dictionary and clip pairs into an emote menu you already runEmote menus
Write a few lines of Lua that play a clip by dictionary and clip namePlaying a dance

The minimum that puts a dance on screen, in a client script of your own:

lua
local dict, clip = 'redmorrow_dance_24@dance', 'samba_dancing'

CreateThread(function()
    RequestAnimDict(dict)
    local timeout = GetGameTimer() + 5000
    while not HasAnimDictLoaded(dict) do
        if GetGameTimer() > timeout then
            print('dictionary did not load — is rm_dance_24 started?')
            return
        end
        Wait(0)
    end
    TaskPlayAnim(PlayerPedId(), dict, clip, 4.0, -4.0, -1, 1, 0.0, false, 0, false, 0, false)
end)

Stop it with StopAnimTask(ped, dict, clip, 2.0) — the blend-out speed has to be greater than 0 — or ClearPedTasks(ped, true, false). Release the dictionary with RemoveAnimDict(dict) when you are finished with it, for example in onResourceStop.

RDR3's TaskPlayAnim takes thirteen arguments

Its flag values are different numbers meaning different things from GTA V's, so a flag word copied from a FiveM script will not do what it says there. 1 is LOOPING here. Duration -1 means no time limit, so with the loop flag the dance runs until something stops it.

A clip requested from a dictionary that never loaded fails silently — the character stands there doing nothing, with no error anywhere. Always wait on HasAnimDictLoaded with a timeout, as above. Full argument list and flag table on Playing a dance.

Config.Clips is not readable from another resource

CFX gives every resource its own Lua state, so a global set inside rm_dance_24 does not exist in yours. Two ways round it: copy the rows into your own resource, or read the file off disk and evaluate it in a sandbox.

lua
local function getDanceClips()
    local src = LoadResourceFile('rm_dance_24', 'clips.lua')
    if not src then return {} end
    local env = { Config = {} }
    local chunk = load(src, '@rm_dance_24/clips.lua', 't', env)
    if not chunk or not pcall(chunk) then return {} end
    return env.Config.Clips or {}
end

That works because clips.lua is in escrow_ignore and therefore still plain text on disk. LoadResourceFile takes the folder name, so it is rm_dance_24 here too. More on this in The clips.lua table.

What is actually in it ​

Dances27 — 24 main, 3 bonus
Rows in clips.lua27, all live. Nothing is commented out
Stream files8 .ycd, 4.0 MB total
FormatNative RDR2 .ycd (RSC8 v58)
BodiesA male and a female version of every dance
ModeEvery row is loop
Root motionNone. No dance moves the character
Total runtime299.3 s across all 27
Server scriptsOne print

Every dictionary a row names is present in stream/, and every file in stream/ belongs to a live row — nothing missing, nothing orphaned. The full table, with the clip name and length of all 27, is on the dance list.

The count on the label is honest

"24+" means 24 main dances plus 3 bonus ones, and all 27 play. This pack is not one short of its name: clips.lua has no commented-out rows and no dead entries.

Requirements ​

Required
RedM serverYesA current build. Old builds cannot load escrow-protected resources
Asset packsYesThe manifest declares dependency '/assetpacks'
An emote menu, or your own codeYesThe pack cannot play a dance by itself
FrameworkNoVORP, RSG, RedEM:RP or none — it looks for nothing
DatabaseNoNo SQL, no server-side state
OneSyncNoNothing is synchronised by the pack

Every dance loops, holds its position, and ships in both bodies ​

All 27 rows agree on two things, which keeps the integration simple:

mode = 'loop'. There is not one once or hold row. Play them with duration -1 and flag 1, and clear the task to stop. mode maps to flags as 'loop' = 1, 'hold' = 2, 'once' = 0.

rootMotion = false. No dance walks, turns or slides the character. Where you start the clip is where the character stays.

Each row carries id, label, dict, clip, category, duration, mode, rootMotion and bodies. The comment header at the top of clips.lua also documents optional walk, flags and blendIn keys; no row in this build uses any of them. label, category and mode are yours to rename — dict and clip are not, because they have to match the names stored inside the .ycd files.

Both bodies, every dance ​

The female dictionary is always the male name plus @f, with identical clip names inside. That holds for all 27 rows without exception: bodies.male equals dict, and bodies.female equals dict with @f appended.

BodyMain dictionary
Maleredmorrow_dance_24@dance
Femaleredmorrow_dance_24@dance@f

The 3 bonus dances each have their own pair instead — dnac@chicken_dance, dnac@jazz_dancing and dnac@dancing_twerk, plus the @f form of each. They are listed on the dance list.

Both versions play on either body; the matching one fits better. Picking between them in code has one trap worth knowing up front:

lua
-- true when the ped uses the female body.
-- GET_META_PED_TYPE: 0 = male, 1 = female. Compare the NUMBER — 0 is truthy in Lua.
-- Falls back to IS_PED_MALE, which RedM may return as 0/1 rather than a boolean.
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

If your emote menu cannot pick a dictionary per body, add the dance twice (for example "Samba (M)" and "Samba (F)"), or use the male version for everyone. See Emote menus.

One naming collision to design around ​

Twenty-six of the 27 rows have id equal to clip. One does not, and it causes the only real integration hazard in the pack:

IDDictionaryClip
jazz_dancing_2dnac@jazz_dancingjazz_dancing
jazz_dancingredmorrow_dance_24@dancejazz_dancing

The clip name jazz_dancing belongs to two different dances

They are two separate animations in two separate dictionaries. A menu that keys its rows on the clip name alone collides on these two and will show one dance twice. Key on id, or on dictionary and clip together.

This is the only row whose id differs from its clip, and the only clip name used twice. Details on the dance list.

The categories are lopsided ​

clips.lua groups rows with a category field, and the grouping is not useful as shipped:

CategoryRows
dance24
Chicken Dance1
Jazz Dancing1
Dancing Twerk1

A menu built straight from category gets one group of 24 and three groups of one, with lowercase on the big group and title case on the three singletons. Rewriting the field is explicitly allowed and is the most worthwhile edit in the file — see The clips.lua table and the category breakdown.

Durations ​

The duration field spans 0.5 s to 27.867 s, with a median of 8.833 s and 299.3 s of animation in total.

Shortestbreakdance_1990_2 at 0.5 s
Longestsamba_dancing_1 at 27.867 s
Median8.833 s

breakdance_1990_2 is half a second long

It is the only row under a second — the next shortest is 2.033 s. Looped, half a second reads as a fast repeating twitch rather than a dance you would leave running. Worth looking at on screen before you put it in a player-facing menu.

duration is metadata, and nothing reads it

It is a number written into clips.lua by hand. No code in the pack consults it, and it is not read out of the .ycd. If a dance looks like it runs longer or shorter than the table says, trust the game — GET_ANIM_DURATION gives the real figure. Full list on the dance list.

The folder name is the resource name ​

In CFX the resource name is the directory name on disk. The name 'redmorrow_dance_24' line in fxmanifest.lua is metadata and renames nothing — it is only why the startup print says [redmorrow_dance_24].

The folder is rm_dance_24, so the line is ensure rm_dance_24. Strip any version suffix like rm_dance_24-1.0.0 before adding it, and remove the extra folder level that unzipping sometimes leaves behind: resources/rm_dance_24/fxmanifest.lua has to exist.

Never rename a .ycd file

An RDR2 dictionary stores its own name inside the file. Renaming the file does not rename the dictionary — it only makes the two disagree, and that dictionary becomes unreachable.

Escrow, and what you can edit ​

The resource is protected with Cfx.re Asset Escrow. It starts only on a server whose sv_licenseKey belongs to the Cfx.re account that bought it; a key from another account cannot start it. Download it from portal.cfx.re under Assets then Granted Assets, and if you upload over FTP, use binary mode — ASCII mode corrupts the protected files.

escrow_ignore covers clips.lua and all the markdown, so those ship readable and stay editable after escrow.

EditableLeave alone
clips.lua — label, category, mode, and adding walk or flagsdict and clip, which must match the names inside the .ycd
README.md, CHANGELOG.md, LICENSE.md, docs/*.mdserver.lua, stream/*.ycd and the .fxap file

Editing a protected file stops the resource starting

Escrow refuses to start a changed protected file, with Failed to verify protected resource in the console. If you hit that, download the folder again and re-upload in binary mode.

Editing clips.lua does not change your emote menu, either. It is a reference list: whatever you rename there also has to be renamed in your menu's own config.

Runtime cost ​

Nothing. The pack registers no loops and no threads, so it reads 0.00 ms on both the client and the server resource monitor. Players download about 4 MB of animation files the first time they join and the files are cached after that, and a dictionary only occupies memory once someone plays a dance from it.

Where to go next ​

PageWhat's in it
InstallationRequirements, folder name, the asset-pack check, verifying the dictionaries streamed
Playing a danceThe 13-argument TaskPlayAnim call, loading a dictionary safely, RDR3 flags, stopping cleanly
Dance listAll 27 with dictionary, clip and length
Emote menusGetting the 27 pairs into the menu you already run, including both bodies
The clips.lua tableEvery field, what is safe to change, reading the list from your own resource
TroubleshootingSymptom to cause to fix, including the silent failures
FAQThe questions that come up first

Related reading: Animation Basics for how RedM streams .ycd dictionaries, RedM Emotes if you want a menu to put these in — its three ways to add an emote applies directly — and RedM platform notes for how RDR3 differs from FiveM.

Support ​

RedMorrow Discord. Bring your server console output and whether DoesAnimDictExist('redmorrow_dance_24@dance') returns true on your client.

Version 1.0.0.

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