Skip to content

Installing 30+ 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.

This pack goes further than that. It has no scripts of any kind: no client.lua, no server.lua, and the manifest declares no client_scripts and no server_scripts at all. The whole resource is two .ycd files, a manifest and documentation. That changes what the server console can tell you after you start it, which is why Check it worked is the section to read carefully.

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
DatabaseNoThere is no server script to talk to one
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 two .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 redmorrow2 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 redmorrow2, anywhere your server loads resources from:

    text
    resources/[animations]/redmorrow2
    resources/[standalone]/redmorrow2

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

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

    text
    resources/[animations]/redmorrow2/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 redmorrow2

    Order does not matter. There are no scripts to race, no database to wait on and no start-up order to respect — stream/ is mounted by the platform itself. Putting the line before your emote menu is a habit worth keeping anyway, for the one case where an emote resource reads dictionaries while it starts.

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

    text
    refresh
    ensure redmorrow2

The folder on disk is redmorrow2, the name field in fxmanifest.lua is redmorrow2, and LoadResourceFile takes redmorrow2. All three agree, so ensure redmorrow2 is the line, and a script that reads the clip list off disk asks for the same string.

A correct tree ​

There is no config.lua, no client.lua, no server.lua and no html/ folder, and none of them are missing. The pack does not have them:

text
redmorrow2/
  fxmanifest.lua
  clips.lua
  README.md
  CHANGELOG.md
  docs/
    CUSTOMER_GUIDE.md
    SERVER_OWNER_GUIDE.md
    DEVELOPER_GUIDE.md
  stream/
    [email protected]
    redmorrow2@[email protected]

Two animation files, 2.9 MB together — [email protected] at 1.44 MB and redmorrow2@[email protected] at 1.43 MB. Each holds all 34 clips, under identical names. Both are referenced by clips.lua, neither is unused, and no file a row names is absent.

Your copy also contains a .fxap file, the escrow licence file that arrives with the customer download. Leave it where it is.

Check it worked ​

This is where the pack differs from everything else in the range, so be precise about what each check proves.

The pack prints nothing of its own. There is no server.lua, so there is no start-up message. The server console shows only the ordinary platform line:

text
Started resource redmorrow2

That line proves the resource mounted, and nothing more

It tells you the folder was found, the manifest parsed and both licence checks passed. It does not prove a .ycd reached a client, and it cannot prove a dance will play, because the pack contains no code that plays one.

If you went looking for a branded [redmorrow2] ... line and could not find it, nothing is wrong. There is none to find.

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

lua
DoesAnimDictExist('redmorrow2@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 = 'redmorrow2@dance', 'twist_dance'
    if not DoesAnimDictExist(dict) then
        print('FAILED: ' .. dict .. ' does not exist — is redmorrow2 started?')
        return
    end
    RequestAnimDict(dict)
    local deadline = GetGameTimer() + 5000
    while not HasAnimDictLoaded(dict) do
        if GetGameTimer() > deadline then
            print('FAILED: ' .. dict .. ' never loaded')
            return
        end
        Wait(0)
    end
    TaskPlayAnim(PlayerPedId(), dict, clip, 4.0, -4.0, -1, 1, 0.0, false, 0, false, 0, false)
    print('SUCCESS: twist_dance is looping. StopAnimTask stops it.')
end)

To stop it:

lua
StopAnimTask(PlayerPedId(), 'redmorrow2@dance', 'twist_dance', 2.0)

The blend-out figure has to be greater than 0. ClearPedTasks(PlayerPedId(), true, false) stops everything at once and works as a fallback.

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

Two details in the TaskPlayAnim 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, and -1 for the duration means no time limit, so with the loop flag the dance runs until something stops it. The full argument list and flag table are on Scripting the pack.

On a female character, swap the dictionary for redmorrow2@dance@f. The clip name does not change. There are only two dictionaries in the pack and no exceptions to that rule.

Verification checklist ​

StepHowExpected
Asset packsServer console on startNo entitlement error
EscrowServer console on startNo Failed to verify protected resource
Resource mountedServer console after ensureStarted resource redmorrow2
Male dictionary streamedDoesAnimDictExist('redmorrow2@dance') in F8true
Female dictionary streamedDoesAnimDictExist('redmorrow2@dance@f') 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 redmorrow2Use 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
Doubled folder levelCouldn't find resource redmorrow2fxmanifest.lua must be directly inside the folder
Version suffix left on the folderSameRename the folder to redmorrow2
Forgot refreshDictionaries missing after copying the folder inrefresh, then ensure
Hunting for a start-up messageNothing branded in the consoleThere is none. Only Started resource redmorrow2
Waiting for a menu or a commandNothing happens on any keyThere is none. See below
Typo in the dictionary nameNothing plays, no errorIt is redmorrow2@dance, not redmorrow2@dances
Renamed a .ycdThat dictionary becomes unreachableRestore the original name
Expecting FiveMNothing loads at allThese are RDR2 .ycd files. RedM only

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. With two files and 34 clips in each, renaming one takes out half the pack at a stroke.

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. redmorrow2 streams animations and nothing else.

You haveYou do not have
2 streamed .ycd dictionariesAn in-game menu
34 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
Clean naming — every row's id is its clip nameAny config options
Any scripts at all, client or server

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

  • Feed the pairs to the emote menu you already run. The dictionary 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 Scripting the pack.

Four things to know before you build either one.

The naming gives you nothing to work around. Every row has id equal to its clip, no id is repeated, no clip name is repeated and no label is repeated. A menu keyed on the clip name alone is safe here, and there is nothing to derive — the clip name is the id.

Every row is the same shape. All 34 are mode = 'loop' with rootMotion = false. No row sets walk and no row sets flags. So the flag you want is 1, and no dance moves the character off the spot, the moonwalk included.

Do not reach for upper-body play. 1 + 8 + 16 = 25 loops a clip on the upper body so the player can keep walking, and it is the right choice for a wave or a salute. These are full-body moves, breakdance above all, and they look wrong played that way. Leave them full body.

Pick the dictionary from the body. GET_META_PED_TYPE returns 0 for male and 1 for female. Compare the number, because 0 is truthy in Lua, and if you fall back to IsPedMale handle both a boolean and a 0/1, which is what RedM may hand back. The helper is on Scripting the pack. Both versions play on either body; the matching one fits better.

clips.lua is never loaded, by anything

The manifest declares no client_scripts and no server_scripts, and clips.lua is in neither list. So Config.Clips does 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.

To read the list in code, load it from disk yourself. LoadResourceFile is server-side, so the usual shape is to read it on the server and send it to clients over an event:

lua
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

That works because clips.lua is listed in escrow_ignore, so it ships readable on disk. Copying the rows into your own resource is the other option, and often the simpler one. Both are on The clips.lua table.

About the count ​

clips.lua holds 34 rows and all 34 are live. Nothing is commented out, both dictionaries a row can name are present in stream/, and neither .ycd is unused.

"30+" on the label means 34: 20 breakdance moves, 6 hip hop dances and 8 party dances. The count is not short and there is nothing to re-enable.

One grouping point is worth knowing before you build a menu from the data. category is dance on all 34 rows — a single flat category — so a menu built straight from the field gets one undifferentiated list of 34. The three groups exist as prose in the resource's own server owner guide, not as data. They are exact and complete though: 20 + 6 + 8 = 34, and every clip is in exactly one group. Rewrite category in clips.lua, or group them in your menu's own config. The split is listed on the dance list.

Six of the breakdance moves start on the ground and carry blendIn = 2.0, about half a second, instead of the 4.0 everything else uses. If your menu exposes a blend-in setting, use 2.0 for those six so the character eases down instead of snapping to the floor. They are listed on Floor moves.

Performance ​

Nothing to tune. The resource runs no scripts at all — no loops, no threads, no events — so it sits at 0.00 ms on both the client and the server, and there is no figure for a profiler to show you. Players download about 3 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 two 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 name redmorrow2 so your ensure line still matches. Do not mix files from two versions: the .ycd files and the .fxap 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.

Remember that your emote menu holds its own copy of the dictionary and clip names. Editing clips.lua changes nothing in game on its own, because nothing loads it — the names have to be in the menu's config too.

What you must never edit ​

FileWhy
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

Escrow refuses to start a protected file that has changed, so an edit here is not a subtle bug — the resource stops working until you restore the original.

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

What you may do with the pack

The licence terms are straightforward: run it on servers whose key belongs to your Cfx.re account, edit clips.lua and the documentation, use the dances in your own scripts and menus there — and do not redistribute or extract the animation files. The exact wording is in docs/CUSTOMER_GUIDE.md inside your download, which is the authority. Ask on Discord if a case is not covered there.

Running it alongside the 24+ pack ​

Both packs can run on the same server, started at the same time, with no conflict. They use different dictionary names: redmorrow2@dance and redmorrow2@dance@f here, against redmorrow_dance_24@dance and the dnac@ dictionaries there. Nothing is shared and nothing overrides anything. The two clips.lua files cannot collide either, for an asymmetric reason: the other pack loads its copy as a client script, while this manifest never loads anything at all. The other pack is documented at 24+ Dances.

Next ​

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