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 server | Yes | On a current server build. Older builds cannot load escrow-protected resources |
| Server key | Yes | sv_licenseKey must belong to the Cfx.re account that bought the pack |
| Asset packs | Yes | The manifest declares dependency '/assetpacks' |
| Framework | No | VORP, RSG, RedEM:RP or none. The pack never touches one |
| Database | No | There is no server script to talk to one |
| OneSync | No | Nothing is replicated and nothing is stored |
| An emote menu or script | In practice, yes | Nothing 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
Sign in at portal.cfx.re with the Cfx.re account you used at checkout.
Open Assets, then Granted Assets.
Find
redmorrow2and 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
Unzip the download so the folder on disk is named exactly
redmorrow2, anywhere your server loads resources from:textresources/[animations]/redmorrow2 resources/[standalone]/redmorrow2Keep the name lowercase and without spaces, and strip any version suffix the unzip adds, such as
redmorrow2-1.0.0.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:textresources/[animations]/redmorrow2/fxmanifest.luaIf
fxmanifest.luais not directly inside the folder you pointensureat, move the inner folder up a level.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.
Add one line to
server.cfg:cfgensure redmorrow2Order 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.Restart the server, or from the server console:
textrefresh 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:
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:
Started resource redmorrow2That 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:
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:
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:
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
| Step | How | Expected |
|---|---|---|
| Asset packs | Server console on start | No entitlement error |
| Escrow | Server console on start | No Failed to verify protected resource |
| Resource mounted | Server console after ensure | Started resource redmorrow2 |
| Male dictionary streamed | DoesAnimDictExist('redmorrow2@dance') in F8 | true |
| Female dictionary streamed | DoesAnimDictExist('redmorrow2@dance@f') in F8 | true |
| A dance plays | The script above, in F8 | The character dances on a loop |
| Stop works | ClearPedTasks(PlayerPedId(), true, false) | The character returns to idle |
Common install mistakes
| Mistake | Symptom | Fix |
|---|---|---|
| Asset packs not enabled | Resource refuses to start | Enable asset packs on your Cfx.re key |
| Key from another account | You lack the required entitlement to use redmorrow2 | Use a key from the buying account, or have the asset transferred |
| Uploaded in ASCII mode | Failed to verify protected resource | Re-download and upload in binary mode |
| Doubled folder level | Couldn't find resource redmorrow2 | fxmanifest.lua must be directly inside the folder |
| Version suffix left on the folder | Same | Rename the folder to redmorrow2 |
Forgot refresh | Dictionaries missing after copying the folder in | refresh, then ensure |
| Hunting for a start-up message | Nothing branded in the console | There is none. Only Started resource redmorrow2 |
| Waiting for a menu or a command | Nothing happens on any key | There is none. See below |
| Typo in the dictionary name | Nothing plays, no error | It is redmorrow2@dance, not redmorrow2@dances |
Renamed a .ycd | That dictionary becomes unreachable | Restore the original name |
| Expecting FiveM | Nothing loads at all | These 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 have | You do not have |
|---|---|
2 streamed .ycd dictionaries | An in-game menu |
34 playable dances listed in clips.lua | A chat command |
| A male and a female version of every dance | A key binding |
A readable, editable clips.lua | Any events or exports |
Clean naming — every row's id is its clip name | Any 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 forHasAnimDictLoaded, thenTaskPlayAnim, andStopAnimTaskto 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:
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 {}
endThat 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
Back up your
clips.luaif you edited it.escrow_ignorecoversclips.lua, the two Markdown files at the root anddocs/*.md, soclips.luaships readable and editable — and a fresh copy will overwrite your labels, categories and modes.Stop the resource, or stop the server.
Replace the whole folder with the new one, keeping the name
redmorrow2so yourensureline still matches. Do not mix files from two versions: the.ycdfiles and the.fxapare versioned together, and a half-replaced folder fails escrow verification rather than running.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.refresh, thenensurethe 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
| File | Why |
|---|---|
stream/*.ycd | Escrow-protected, and a dictionary stores its own name internally |
The .fxap file | The escrow licence file. Do not edit it and do not delete it |
dict and clip in clips.lua | Not 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
- Scripting the pack — the natives, the 13 arguments, the RDR3 flag values, stopping cleanly
- Emote menus — getting the 34 dances into the menu you already run
- Dance list — all 34 with clip name and length
- The clips.lua table — every field, and why nothing reads it
- Troubleshooting — symptom, cause, fix
- FAQ — the short answers
- Animation Basics — how RedM animations work in general
- 24+ Dances — the other dance pack, compatible, runs alongside
- 100+ Female Poses — another assets-only pack, female dictionaries only
- 30+ Female Poses — a pose pack that does ship its own menu
- RedM platform notes — artifacts, natives and the differences from FiveM