# Adding emote

How to add your own emotes, dances, walks, and expressions to the system.

***

### Data files

All emote data is defined in `shared/data/`. Each file contains a global Lua table:

| File                | Category    | Table name        |
| ------------------- | ----------- | ----------------- |
| `emotes.lua`        | Emotes      | `DataEmotes`      |
| `dances.lua`        | Dances      | `DataDances`      |
| `props.lua`         | Props       | `DataProps`       |
| `walks.lua`         | Walks       | `DataWalks`       |
| `expressions.lua`   | Expressions | `DataExpressions` |
| `animals.lua`       | Animals     | `DataAnimals`     |
| `shared_emotes.lua` | Shared      | `DataShared`      |

***

### Standard emote format

```lua
DataEmotes["emote_id"] = {
    dict  = "anim@dictionary",       -- Animation dictionary
    anim  = "animation_name",        -- Animation clip name
    label = "Display Name",          -- Shown in menu
    options = {                       -- All optional
        loop     = true,             -- Loop the animation
        movable  = true,             -- Allow movement while playing
        stuck    = false,            -- Freeze in place
        duration = 5000,             -- Auto-stop after ms

        prop = {                     -- Attached object
            model    = "prop_name",
            bone     = 28422,        -- Bone index
            offset   = {0.0, 0.0, 0.0},
            rotation = {0.0, 0.0, 0.0},
        },

        prop2 = { ... },             -- Second prop (same format)

        exit_emote = "other_emote",  -- Play this emote on stop
        exit_type  = "emote",        -- Category of exit emote
    },
}
```

***

### Walk style format

```lua
DataWalks["walk_id"] = {
    anim  = "move_m_confident",   -- Movement clipset name
    label = "Confident",
}
```

Walk styles are applied with `SetPedMovementClipset()` and persist across sessions.

***

### Expression format

```lua
DataExpressions["expr_id"] = {
    anim  = "mood_happy_1",    -- Facial animation override
    label = "Happy",
}
```

Expressions use `SetFacialIdleAnimOverride()`.

***

### Shared emote format

```lua
DataShared["shared_id"] = {
    dict  = "anim@dict",
    anim  = "anim_clip_a",           -- Initiator animation
    label = "Handshake",
    partner_emote = "shared_id_b",   -- Partner's emote ID
    options = {
        duration = 5000,
        sync = {
            front   = 1.0,           -- Distance in front
            side    = 0.0,           -- Lateral offset
            height  = 0.0,           -- Vertical offset
            heading = 180.1,         -- Facing offset (180 = face to face)
        },
        attach = {                   -- Optional bone attachment
            bone = 0,
            pos  = {0.0, 0.0, 0.0},
            rot  = {0.0, 0.0, 0.0},
        },
    },
}

-- The partner emote
DataShared["shared_id_b"] = {
    dict  = "anim@dict",
    anim  = "anim_clip_b",
    label = "Handshake (Partner)",
    partner_emote = "shared_id",
    options = { duration = 5000 },
}
```

***

### Custom animation files

To add custom `.ycd` animations:

1. Place your animation files in the `stream/` folder (organized in subfolders)
2. The resource will automatically stream them
3. Reference the dictionary and animation names in the data files

{% hint style="info" %}
Animation dictionary names in streamed files follow the format: `folder@subfolder@filename` based on the file path under `stream/`.
{% endhint %}

***

### Animation flags reference

The engine computes animation flags from the `options` table:

| Options          | Flag | Behavior                   |
| ---------------- | ---- | -------------------------- |
| `stuck = true`   | 50   | Frozen in place            |
| `loop + movable` | 51   | Looping, player can move   |
| `loop = true`    | 1    | Looping only               |
| `movable = true` | 51   | Can move                   |
| *(none)*         | 0    | Plays once and stops       |
| *(in vehicle)*   | 51   | Always movable in vehicles |
