Skip to content

Installing 24+ Dances ​

Installing this pack is one line in server.cfg. Getting a dance onto a character takes one more thing, because the pack has no menu, no command and no keybind — read What you still need before you call the job done.

Requirements ​

Required
RedM serverYesOn a current server build. Older builds cannot load escrow-protected resources
Server keyYessv_licenseKey must belong to the Cfx.re account that bought the pack
Asset packsYesThe manifest declares dependency '/assetpacks'
FrameworkNoVORP, RSG, RedEM:RP or none. The pack never touches one
DatabaseNoThe only server script is a single print
OneSyncNoNothing is replicated and nothing is stored
An emote menu or scriptIn practice, yesNothing in the pack plays a dance. Something has to call the natives

That last row is the one that surprises people. What you install is 8 .ycd dictionaries and a reference table, and no code that plays them.

Two separate licence checks have to pass

Asset packs. dependency '/assetpacks' is an entitlement check Cfx.re runs against your server's licence key. Without it the resource refuses to start, and no configuration gets around it. Enable asset packs for your key in the Cfx.re portal first.

Asset Escrow. The pack is escrow-protected, so it runs only on a server whose sv_licenseKey belongs to the Cfx.re account that bought it. A key from a different account cannot start it — if you bought on one account and run your server on another, have the asset transferred.

Nothing else on this page matters until both pass.

No npm, no build step, no SQL import, no extra resources.

Download ​

  1. Sign in at portal.cfx.re with the Cfx.re account you used at checkout.

  2. Open Assets, then Granted Assets.

  3. Find rm_dance_24 and download it.

Not in the list? Wait a few minutes after paying and refresh the page — the grant is not always instant. Then check that you are signed in with the same Cfx.re account you used at checkout, which is the single most common cause. If it is still missing, contact support on Discord with your Tebex transaction id. It starts with tbx- and is in your receipt e-mail.

Install ​

  1. Unzip the download so the folder on disk is named exactly rm_dance_24, anywhere your server loads resources from:

    text
    resources/[animations]/rm_dance_24
    resources/[standalone]/rm_dance_24

    Keep the name lowercase and without spaces, and strip any version suffix the unzip adds, such as rm_dance_24-1.0.0.

  2. Check for a doubled folder level. Unzipping into a folder you already named creates rm_dance_24/rm_dance_24/, which the server reads as an empty resource. The test is one path:

    text
    resources/[animations]/rm_dance_24/fxmanifest.lua

    If fxmanifest.lua is not directly inside the folder you point ensure at, move the inner folder up a level.

  3. Upload in binary mode if you use FTP. ASCII mode rewrites line endings inside the protected files and corrupts them, which shows up later as a verification failure rather than an upload error.

  4. Add one line to server.cfg:

    cfg
    ensure rm_dance_24

    Order barely matters — there are no server scripts to race and no database to wait on. The one exception is an emote resource that reads dictionaries at start-up: put this line before or alongside it.

  5. Restart the server, or from the server console:

    text
    refresh
    ensure rm_dance_24

A correct tree. There is no config.lua, no client.lua and no html/ folder, and none of them are missing — the pack does not have them:

text
rm_dance_24/
  fxmanifest.lua
  clips.lua
  server.lua
  README.md
  CHANGELOG.md
  LICENSE.md
  docs/
  stream/
    [email protected]
    redmorrow_dance_24@[email protected]
    dnac@chicken_dance.ycd
    dnac@[email protected]
    dnac@jazz_dancing.ycd
    dnac@[email protected]
    dnac@dancing_twerk.ycd
    dnac@[email protected]

Eight files, 4.0 MB. The two redmorrow_dance_24@dance dictionaries are 1.9 MB each and hold 24 clips apiece; the six dnac@ files hold one clip each.

The folder name and the manifest name are different ​

This pack has two names, and the console shows you the one you do not write in server.cfg. It is worth being precise about which is which.

In CFX the resource name is the directory name. The name field in fxmanifest.lua is descriptive metadata — it does not rename anything, and the server never loads a resource by it.

WhereValue
Folder on diskrm_dance_24
name in fxmanifest.luaredmorrow_dance_24
Line in server.cfgensure rm_dance_24
Line printed to the console[redmorrow_dance_24] Dance animation pack started.

Do not write ensure redmorrow_dance_24

There is no resource by that name. redmorrow_dance_24 is the manifest's name field, which is why the startup print carries it, and that print is the reason people try it. The ensure line has to match the folder.

Folder on diskLine in server.cfgWorks
rm_dance_24ensure rm_dance_24Yes
rm_dance_24ensure redmorrow_dance_24No — no such resource
rm_dance_24-1.0.0ensure rm_dance_24No — rename the folder first

The same folder name is what LoadResourceFile takes, so a script reading the pack's clip list asks for rm_dance_24, never redmorrow_dance_24. If you do rename the folder, update both the ensure line and any LoadResourceFile call.

The dictionary names are a separate matter again. redmorrow_dance_24@dance comes from inside the .ycd files, not from the resource, so renaming the folder to taco still leaves you playing redmorrow_dance_24@dance.

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 while the others keep working. If one dance fails and the rest are fine, this is almost always why.

Check it worked ​

On start, server.lua prints one line to the server console:

text
[redmorrow_dance_24] Dance animation pack started.

That string is hardcoded, so it reads redmorrow_dance_24 whatever you named the folder.

The console line proves less than it looks like it does

It proves the resource started and both licence checks passed. It does not prove a single .ycd reached a client, and it does not prove a dance will play — the pack contains no code that plays one.

The next check is client-side. In the F8 console in game:

lua
DoesAnimDictExist('redmorrow_dance_24@dance')

true means the dictionary streamed to your client. false means the resource is not started, you never ran refresh after copying the folder in, or a licence check failed.

The only test that proves the whole chain is playing a dance. Paste this into F8 — it reports the failure instead of leaving you looking at a character who is doing nothing:

lua
CreateThread(function()
    local dict, clip = 'redmorrow_dance_24@dance', 'samba_dancing'
    RequestAnimDict(dict)
    local timeout = GetGameTimer() + 5000
    while not HasAnimDictLoaded(dict) do
        if GetGameTimer() > timeout then
            print('FAILED: ' .. dict .. ' never loaded — is the resource started?')
            return
        end
        Wait(0)
    end
    TaskPlayAnim(PlayerPedId(), dict, clip, 4.0, -4.0, -1, 1, 0.0, false, 0, false, 0, false)
    print('SUCCESS: samba_dancing is looping. ClearPedTasks(PlayerPedId(), true, false) to stop it.')
end)

The timeout matters. A clip asked for from a dictionary that never loaded fails silently — no error, no red line, the character stands there. Always wait on HasAnimDictLoaded and always give the wait a deadline.

Two details in that call are worth noting now rather than debugging later. RDR3's TaskPlayAnim takes thirteen arguments, and its flag values are not GTA V's — a flag word copied out of a FiveM script does not mean the same thing here. 1 is LOOPING. Full detail is on Playing a dance.

Verification checklist ​

StepHowExpected
Asset packsServer console on startNo entitlement error
EscrowServer console on startNo Failed to verify protected resource
Resource startedServer console after ensure[redmorrow_dance_24] Dance animation pack started.
Dictionary streamedDoesAnimDictExist('redmorrow_dance_24@dance') in F8true
A dance playsThe script above, in F8The character dances on a loop
Stop worksClearPedTasks(PlayerPedId(), true, false)The character returns to idle

Common install mistakes ​

MistakeSymptomFix
Asset packs not enabledResource refuses to startEnable asset packs on your Cfx.re key
Key from another accountYou lack the required entitlement to use rm_dance_24Use a key from the buying account, or have the asset transferred
Uploaded in ASCII modeFailed to verify protected resourceRe-download and upload in binary mode
ensure used the manifest nameNo such resource in the consoleWrite ensure rm_dance_24
Doubled folder levelCouldn't find resource rm_dance_24fxmanifest.lua must be directly inside the folder
Version suffix left on the folderSameRename the folder
Forgot refreshDictionaries missing after copying it inrefresh, then ensure
Renamed a .ycdOne dance fails, the rest workRestore the original name
Waiting for a menu or a commandNothing happens on any keyThere is none. See below
Expecting FiveMNothing loads at allThese are RDR2 .ycd files. RedM only

What you still need ​

The pack's own documentation is straight with you about this, which is not always the case — so take it at face value. rm_dance_24 streams animations and nothing else.

You haveYou do not have
8 streamed .ycd dictionariesAn in-game menu
27 playable dances listed in clips.luaA chat command
A male and a female version of every danceA key binding
A readable, editable clips.luaAny events or exports
A server console line on startAny config options

So one more step is needed before players can use it:

  • Feed the pairs to the emote menu you already run. The dict and clip values from the dance list go straight into an emote table. RedM Emotes takes them — see three ways to add an emote. Other emote systems work the same way with their own table format. Worked examples are on Emote menus.
  • Or write the few lines yourself. RequestAnimDict, wait for HasAnimDictLoaded, then TaskPlayAnim, and StopAnimTask to end it. Walked through on Playing a dance.

Two things to know before you build either one.

One clip name is used by two different dances

jazz_dancing is the clip name of the dance jazz_dancing in redmorrow_dance_24@dance, and also the clip name of the dance jazz_dancing_2 in dnac@jazz_dancing. They are two different dances.

A menu keyed on the clip name alone collides on these two. Key on the id, or on the dictionary and clip together. This is the only row in the pack whose id differs from its clip, and the only clip name used twice — details on the dance list.

The other is the bodies. Every dance ships a male version and a female version, and the female dictionary is always the male name plus @f with identical clip names inside — redmorrow_dance_24@dance@f, dnac@chicken_dance@f, and so on. There are no exceptions to that rule in the 27 rows. Both versions play on either body; the matching one fits better. Picking between them in code means comparing GET_META_PED_TYPE as a number, because it returns 0 for male and 0 is truthy in Lua — the helper is on Playing a dance.

Config.Clips is not readable from another resource the direct way

clips.lua sets a global called Config.Clips, and it is a global inside this resource. CFX gives every resource its own Lua state, so your script cannot see it however it asks.

Either copy the rows into your own resource, or read the file off disk and evaluate it in a sandbox:

lua
local src = LoadResourceFile('rm_dance_24', 'clips.lua')
local env = { Config = {} }
local chunk = src and load(src, '@rm_dance_24/clips.lua', 't', env)
local clips = (chunk and pcall(chunk)) and env.Config.Clips or {}

That works because clips.lua is listed in escrow_ignore, so it ships readable on disk. Both approaches are on The clips.lua table.

About the count ​

clips.lua holds 27 rows and all 27 are live. Nothing is commented out, every dictionary a row names is present in stream/, and no .ycd in stream/ is unused.

"24+" on the label means 24 main dances in redmorrow_dance_24@dance plus 3 bonus dances in their own dnac@ dictionaries. The count is not short and there is nothing to re-enable.

One grouping quirk is worth knowing before you build a menu from the data. The category field puts those same 24 rows under dance in lowercase, and gives each bonus dance a title-case category of its own — Chicken Dance, Jazz Dancing, Dancing Twerk. Built straight from category, a menu gets one group of 24 and three groups of one. Rewriting the field is allowed; see categories.

Performance ​

Nothing to tune. server.lua is one print and clips.lua is a data table, so the resource runs no loops and no threads and sits at 0.00 ms on both the client and the server. Players download about 4 MB of animation files the first time they join and the files are cached after that. A dictionary only loads into memory when someone plays a dance from it, and RemoveAnimDict releases it again.

Updating ​

  1. Back up your clips.lua if you edited it. escrow_ignore covers clips.lua, the three Markdown files at the root and docs/*.md, so clips.lua ships readable and editable — and a fresh copy will overwrite your labels, categories and modes.

  2. Stop the resource, or stop the server.

  3. Replace the whole folder with the new one, keeping the same name so your ensure line still matches. Do not mix files from two versions: the .ycd files and the protected scripts are versioned together, and a half-replaced folder fails escrow verification rather than running.

  4. Copy your edits back into the new clips.lua. Diff the two rather than dropping your old file in blind — a new version may add rows you want.

  5. refresh, then ensure the resource, and re-run the F8 play test above.

What you must never edit ​

FileWhy
server.luaEscrow-protected. A changed protected file refuses to start
stream/*.ycdEscrow-protected, and a dictionary stores its own name internally
The .fxap fileThe escrow licence file. Do not edit it and do not delete it
dict and clip in clips.luaNot protected, but they must match the names inside the .ycd files

Everything else in clips.lua — label, category, mode, walk — is yours to change, and so is the documentation. The clips.lua table lists every field.

Next ​

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