Multicharacter Poses
Every pose a player can reach from the character screen lives in animations.lua. One file, two lists: the solo poses a character cycles with E, and the duo poses a paired character cycles with the same key.
This is not the Scene Creator's pose browser
The 305-pose library with 12 category tabs belongs to the Scene Creator and lives in config_emotes.lua. It is what you pick from while building a location. Adding a row there does not put the pose in front of players. See The emote library.
animations.lua is the much shorter player-facing list, and it is the one described here.
| Solo poses in the shared list | 20 — 11 scenarios, 4 raw clips, 5 kit emotes |
| Duo poses | 20 — lover 8, friend 12 |
| File | animations.lua, a shared_script loaded after config_selector.lua |
| Takes effect | On resource restart |
| Player key | E, configurable in ConfigSelector.Keys.pose |
A character also keeps its last pose: the choice is written to the player's own saved settings and restored the next time the selector opens.
Solo poses
ConfigSelector.Animations holds the solo list and decides which poses a given character is offered.
The three source modes
source | Poses offered |
|---|---|
"slot" | Only the scenarios config.lua defines for that character's position at that location |
"global" | Only ConfigSelector.Animations.list |
"merged" (default) | The location's own scenarios first, then everything from list |
"merged" removes duplicates as it builds the list, and it compares what plays — the scenario name, the clip name or the kit emote name — not the id. A location that already defines WORLD_HUMAN_SMOKE will not get a second copy of it from the shared list.
Which mode suits you
"slot" is the only mode that can never offer a pose the location cannot support, because every entry came from that location. It is also the thinnest: most shipped positions define a single scenario, so E has nothing to cycle to. "merged" is the default because it gives players a real list everywhere while still putting the location's own hand-picked poses first.
With source = "slot", a position whose scenario table has no entry for the character's sex (mp_male or mp_female) offers nothing at all and E does nothing. Locations and their scenario tables are covered on Locations.
Pose cycling can be switched off entirely with ConfigSelector.Scene.allowPoseCycle = false (default true).
The three entry shapes
{ type = "scenario", id = "smoke", scenario = "WORLD_HUMAN_SMOKE" }
{ type = "emote", id = "wait", dict = "...", anim = "...", flag = 1 }
{ type = "kitemote", id = "hype", emote = "KIT_EMOTE_REACTION_YEEHAW_1", repeatMs = 5000 }| Field | Applies to | Notes |
|---|---|---|
id | all | Must be unique. perLocation and the saved per-character pose refer to it |
scenario | scenario | A scenario name, hashed at runtime |
dict / anim | emote | animDict and animName are accepted as the same thing |
flag | emote | Defaults to 1. RDR3 flag values are not GTA V's |
emote | kitemote | A KIT_EMOTE_... name |
repeatMs | kitemote | Replay interval while the pose stays selected. Defaults to 5000 |
upperBody | kitemote | Plays the emote on the upper body only |
A few shipped scenario entries also carry a duration field. The selector does not read it — scenarios are started endless — so leaving it in or taking it out changes nothing.
Poses that need something to lean on
perLocation restricts which ids from list a given location may use. It ships empty, which means no restriction anywhere:
perLocation = {
[3] = { "smoke", "lobby_02" }, -- location 3 gets only these two from `list`
}The location's own scenarios are always kept, whatever perLocation says. A location with no key in the table is unrestricted.
This is the fix for a pose that only reads correctly in one kind of place. Two of the shipped entries are exactly that case:
leaning—WORLD_HUMAN_GUARD_LEAN_WALLwait3— a female wall-lean clip
At a location with no wall behind the mark, the character leans on nothing. The pose is not broken; it is in the wrong place. Restrict it to the locations that have a wall.
perLocation keys are positions in the combined location list
Config.SpawnPosition holds 11 locations and config_scenes.lua appends 2 more at load, so the shipped numbering runs 1 to 13 with the scene entries last. Adding a twelfth location to config.lua pushes those two scenes to 13 and 14 and every perLocation key above 11 then points at the wrong place. Check your numbering after adding a location.
The three kinds, and which ones can float
Both lists in animations.lua are built from the same three kinds of animation, and the difference decides whether a pose can ever sit wrong on the ground.
| Kind | type | Grounded by the engine | Loops |
|---|---|---|---|
| Scenario | scenario | Yes | Yes |
| Raw clip | emote | No | Depends on flag |
| Kit emote | kitemote (solo), kit (duo) | No | One-shot, replayed every repeatMs |
A scenario is a packaged behaviour: the engine places, grounds and loops the character itself, so there is no height to get wrong. A raw clip is played straight onto the ped and carries the height of whatever set it was authored on. That is the cause of almost every floating character.
The full treatment, including which categories are made of what, is on the emote library page. It describes the Scene Creator's library, but the three kinds behave identically here.
The blunt fix is one line
ConfigSelector.ScenariosOnly = true hides every clip-based pose everywhere at once — solo lists and duo lists both. What is left cannot float, because the engine grounds all of it. The default is false.
The filter has one safeguard: if removing clips would leave a list empty, the full list is kept and a line is written to the console instead. A character is never left with nothing to cycle.
Partner duo poses
While a paired character is on screen, E cycles ConfigSelector.Partner.animations instead of the solo list. Two lists, keyed by pairing type:
| List | Poses | Made up of |
|---|---|---|
lover (Couple) | 8 | 2 scenario, 5 kit, 1 raw clip |
friend | 12 | 3 scenario, 6 kit, 3 raw clips |
Pairing itself — the panel, requests, timeouts, unpairing — is on Partner system.
The three types and their fields
type | What it is | Fields |
|---|---|---|
"scenario" | A world scenario on each ped. No contact, always grounded | primary, partner |
"kit" | An RDO emote kit action on each ped. No contact | category, primary, partner, repeatMs, upperBody |
"emote" | Two clips played together. The only type with real contact | dict, primary, partner, primaryFemale, partnerFemale, swapByGender, flag |
kitemote is also accepted in a duo list and is handled exactly as kit is.
A kit entry's category resolves to one of reaction, action, taunt, greet, twirl or dance; anything unrecognised falls back to action. Omit it and the category is read out of the emote name itself, from the word after KIT_EMOTE_. One category is passed to both halves, so a pair that mixes a greeting with an action — the shipped "Blow a kiss" pairs KIT_EMOTE_ACTION_BLOW_KISS_1 with KIT_EMOTE_GREET_FLYING_KISS_1 — still plays under the single category written on the entry.
For "emote" entries, primaryFemale and partnerFemale supply a female variant of either half, and swapByGender = true gives a female character the woman's track and her partner the man's.
Where the partner stands
attach = vector4(right, forward, up, heading)| Component | Means |
|---|---|
right | Metres to your character's right. Negative moves the partner left |
forward | Metres in front of your character |
up | Metres up. Positive raises the partner off the ground |
heading | The partner's own turn in degrees. 180 faces your character |
The vector is relative to your character and its facing, not to the world, so one attach works at every location.
Defaults, used only by a pose that carries no attach of its own:
ConfigSelector.Partner.attach = {
lover = vector4(0.0, 0.60, 0.0, 180.0),
friend = vector4(0.0, 1.05, 0.0, 180.0),
}0.60 m in front for a couple, 1.05 m for a friend, both turned to face you. Every one of the 20 shipped duo poses carries its own attach, so these two values matter for poses you add.
"emote" entries can also carry scene options for builds that have real synchronised scenes: deltaZ raises or lowers the whole scene, sceneHeadingOffset turns it, and holdLastFrame stops on the last frame rather than looping.
attach.w and sceneHeadingOffset are not the same number
attach.w turns the partner. sceneHeadingOffset turns the pair as a unit. Copying one into the other produces two people facing the same direction at the right distance, which looks like a rendering bug and is not one.
Poses that want furniture
A duo entry marked needsProp = true is one written for a bench, a railing or a campfire, and ConfigSelector.Partner.allowPropPoses decides whether players see it. The default is true: prop poses are offered.
None of the shipped duo poses carries the flag, so setting allowPropPoses = false on a stock install removes nothing. The flag is there for poses you add — and for two shipped ones you may want to mark yourself, because there is no rail and no fire at the spawn marks:
friend→ At the railing (script_re@roaming_thugs@laramie)friend→ Campfire (script_campfire@ex_confed@background@ped02)
Add needsProp = true to either and it disappears the moment allowPropPoses is false.
Adding and removing
Open
animations.luaand find the list you want,loverorfriend.Append an entry. Give it a
label— it is what the pose editor and the debug commands show — and anattach:lua{ type = "kit", label = "Tip your hat", category = "greet", primary = "KIT_EMOTE_GREET_TIP_HAT_1", partner = "KIT_EMOTE_GREET_TIP_HAT_1", attach = vector4(0.0, 1.20, 0.0, 180.0), repeatMs = 5000 },Restart the resource.
animations.luais a shared script read at start.Pair two characters, press E to it, and line up the
attachwith the pose editor rather than by guesswork.
To remove a pose, delete its entry. To take one away from players without losing it, comment it out or move it behind needsProp.
Numbers out of the editor beat numbers out of your head
The pose editor saves to partner_poses.json, which overrides the attach written in animations.lua and reaches every player without a restart. Each save also prints its attach line in the F8 console, ready to paste back into the file. See Partner pose editor.
Paired poses
Two people in one pose is harder on RedM than it sounds, and the way the resource works around it explains most of what you will see go wrong.
RedM build b1491 exposes no synchronised scene natives. On GTA V a duo animation is one scene object with two peds added to it; the engine then holds both halves in the same timeline and in the right relative position. Those natives are not there.
SelectorScene.PairSceneAvailable() probes for them at runtime rather than assuming, and takes the first set it finds:
| Probe | Result |
|---|---|
NetworkCreateSynchronisedScene + NetworkAddPedToSynchronisedScene + NetworkStartSynchronisedScene | "network" |
CreateSynchronizedScene + TaskSynchronizedScene | "plain" |
| Neither | false — the fallback below |
So on a build that has them, duo poses play as real scenes. On b1491 they do not, and a duo pose is instead:
- Two independent
TaskPlayAnimclips, fired on the two peds in the same frame. - The partner placed from
attach, withSetEntityCoordsNoOffset, before its pose starts. The spawn height in a location is origin level — roughly 0.9 m above the feet — so the ordinarySetEntityCoordswould lift the ped by that much, and moving a ped after you have tasked it cancels the task. - Pushed back into step on a timer. Two clips started together still drift apart, so the second ped's playback position is reset to the first ped's. The interval is
ConfigCreator.Adjuster.phaseInterval, 400 ms by default, withlockPhase = true. Scenario pairs need none of this; the engine loops them.
TaskPlayAnim on RDR3 takes thirteen arguments
The twelfth is a string. The flag values are not GTA V's either, so a flag number copied out of a FiveM snippet will not do what the snippet says it does. The entries in animations.lua use flag = 1.
What follows from all this:
- Contact between the two characters is only ever as good as
attach. There is nothing holding hands together but two numbers, which is why the pose editor exists. scenarioandkitpairs make no contact at all by design. They are two people doing the same thing side by side, and they are the robust half of both lists.- A clip pair can slip out of step for a moment between re-syncs. On a dance, that reads as a small stutter rather than as two people dancing to different music.
Run /selectornatives in the F8 console to see which of these natives your build actually exposes, and /selectordump for the scene API that was picked.
When a pose floats or sinks
Raw clips carry their own height. The resource does not silently correct it, because moving a ped cancels its pose — so it measures the error, tells you the number, and applies it on the next placement once you have written it down.
Set
ConfigSelector.Debug = trueinconfig_selector.luaand restart. The default isfalse.Open the character screen and cycle to the pose that looks wrong.
Read the F8 console. Anything more than 0.05 m off the ground is reported with the key to fix it:
textcnv_camp@rchso@cnv@ccdtc33@player_karen/karen_dance_rot_rt_loop puts the partner 0.142m off the ground; add that to clipOffsetsPut that number in
ConfigSelector.Partner.clipOffsetsand restart:luaclipOffsets = { ["KIT_EMOTE_GREET_FANCY_BOW_1"] = 0.128, ["MP_LOBBY_SCENARIO_06"] = 0.116, ["cnv_camp@rchso@cnv@ccdtc33@player_karen/karen_dance_rot_rt_loop"] = 0.142, }
Two shipped corrections are already in that table, which is a fair indication of the size of the problem: 0.128 m and 0.116 m. A positive value lowers the ped.
Keys come in two shapes:
| Key | Matches |
|---|---|
"dict/anim" | That clip in that dictionary only |
"anim" | That clip name in any dictionary — and scenarios and kit emotes, which have no dictionary |
clipOffsets lives under Partner but is not only for partners
The same table is read when a character's own solo pose is placed. The console line for a solo pose reads "sits nm off the ground" rather than "puts the partner", and the fix is the same entry in the same table.
/selectordump gives the whole height picture for the highlighted slot in one go — the spawn mark's origin-level Z, the real foot-level ground Z, both peds' feet, a verdict, and the exact line to paste:
VERDICT FLOATING 0.13m ABOVE the ground
FIX ["KIT_EMOTE_GREET_FANCY_BOW_1"] = 0.128,It calls a gap floating past 0.15 m and sunk past −0.15 m.
Which tool for which problem
| Symptom | Fix |
|---|---|
| One duo pose puts the partner in the wrong place | Pose editor, then paste the attach line it prints |
| One clip is off the ground wherever it appears | clipOffsets |
| A pose needs a wall, rail or seat the location has not got | perLocation for solo, needsProp for duo |
| Several clips are wrong and you want it over with | ConfigSelector.ScenariosOnly = true |
Drifting and dropping out
Clips carry root motion, and RDR3 ignores the TaskPlayAnim lock flags that would stop it. A pose watchdog handles the result: one second after a pose change it starts checking, and if a character has dropped out of its pose while moving, or has strayed more than 0.75 m from its mark, it is put back and re-posed. Characters in a wagon seat, characters with a partner and marks with a forced pose are driven elsewhere and left alone.
A character that visibly walks away and snaps back is this watchdog working. A character that walks away and stays away is usually a clip whose dictionary failed to load — /selectorpose names the dictionaries a duo pose needs and reports whether this build has them.
Related
| Page | What's in it |
|---|---|
| The emote library | The Scene Creator's 305 poses, and adding your own |
| Partner system | Pairing, requests, Couple and Friend |
| Partner pose editor | Lining up attach in game |
| Locations | Config.SpawnPosition, the per-position scenario tables |
| Configuration | Every key in config_selector.lua |
| Player guide | What players see and press |
| Troubleshooting | Symptom to cause to fix |
For animation packs that add poses to the rest of your server rather than to the character screen, see RedM Emotes and the animations section. Framework notes are under VORP.
Support: https://discord.gg/w4Ew4k3Exn