# Creating Sets

Sets are themed collections of items for players to find. Configure them in `config/server.lua`.

## Example

```lua
sets = {
    my_set_name = {
        -- Display
        label = 'My Set Name',
        description = 'Find all the items in this set!',

        -- Object
        model = 'prop_box_wood01a',
        icon = 'my_icon.png',
        grounded = true,

        -- Pickup
        pickupType = 'target',
        pickupDistance = 2.5,

        -- State
        enabled = true,

        -- Hints
        hint = 'Look around the city...',

        -- Rewards
        rewards = {
            onCollect = { money = 100, moneyType = 'cash' },
            onComplete = { money = 5000, moneyType = 'bank' },
        },

        -- Locations
        items = {
            { coords = vec3(123.45, 678.90, 12.34) },
            { coords = vec3(234.56, 789.01, 23.45), hint = 'Near the bench' },
        },
    },
},
```

***

## Set Structure

Structure for set table.

* label: [`Label`](#display)
  * Display name for the set shown in the UI
* description: [`Description`](#display)
  * Description for the set shown in the UI
* model [`Model`](#object)
  * Model for the spawned collectable object
* icon: [`Icon`](#object)
  * Icon for stickers in UI (image path `'action-figure-pogo.png'`, or `'fa:icon-name'` for Font Awesome)
* grounded? [`Grounded`](#object)
  * Whether to snap the spawned object to the ground, (default: `true`)
* pickupType? [`PickupType`](#pickup)
  * How to collect the item, (default: `'target'`)
* pickupDistance? [`PickupDistance`](#pickup)
  * Distance to trigger pickup (default: `1.5`)
* enabled? [`Enabled`](#enabled)
  * Whether to enable this collectable set (default: `true`)
* collectSound? [`Sound`](#sound)
  * Play sound on collection (default: `true` for `'nearby'`, `false` for `'target'` and `'prompt'`)
* hint? [`Hint`](#hints)
  * Default hint for all items in set
* rewards? [`Rewards`](#rewards)
  * Rewards for collecting items and completing the set
* blip? [`Blip`](#blip)
  * Optional blip for all items
* animations? [`Animations`](#animations)
  * Animations to use for this set
* items [`Items`](#items-structure)
  * List of collectable items in this set

***

## Items Structure

Structure for items table.

* coords: `vector3`
  * Where to spawn the collectable object
* rotation?: `number`
  * Optional rotation of the collectable object
* grounded?: [`Grounded`](#object)
  * Optional toggle of snapping object to ground for this item
* model? [`Model`](#object)
  * Optional model for this item
* icon?: [`Icon`](#object)
  * Optional icon for this item
* hint? [`Hint`](#hints)
  * Optional hint for this item
* blip? [`Blip`](#blip)
  * Optional blip for this item
* animations? [`Animations`](#animations)
  * Optional animation for this item
* collectSound? [`Sound`](#sound)
  * Optional sound played when item is picked up for this item

***

## Set Options

### Display

| Option        | Type   | Description                 |
| ------------- | ------ | --------------------------- |
| `label`       | string | Name shown in the UI        |
| `description` | string | Description shown in the UI |

### Object

| Option     | Type    | Default  | Description                           |
| ---------- | ------- | -------- | ------------------------------------- |
| `model`    | string  | required | Prop model to spawn                   |
| `icon`     | string  | -        | Sticker image (filename or `fa:icon`) |
| `grounded` | boolean | `true`   | Snap object to ground                 |

### Pickup

| Option           | Type   | Default    | Description                                           |
| ---------------- | ------ | ---------- | ----------------------------------------------------- |
| `pickupType`     | string | `'target'` | How to collect: `'target'`, `'prompt'`, or `'nearby'` |
| `pickupDistance` | number | `1.5`      | Distance to trigger pickup                            |

**Pickup Types:**

* `'target'` - Requires target resource in bridge
* `'prompt'` - Shows TextUI prompt, press key to collect
* `'nearby'` - Auto-collects when player is within range

### Enabled

| Type    | Description                |
| ------- | -------------------------- |
| boolean | Whether to enable this set |

### Blip

| Option    | Type    | Default | Description                                                                                 |
| --------- | ------- | ------- | ------------------------------------------------------------------------------------------- |
| `enabled` | boolean | `true`  | Whether to enable the blip                                                                  |
| `sprite`  | number  | `57`    | [The sprite to use for the blip](https://docs.fivem.net/docs/game-references/blips/)        |
| `colour`  | number  | `1`     | [The colour to use for the blip sprite](https://docs.fivem.net/docs/game-references/blips/) |
| `title`   | string  | `nil`   | The name to use for the blip                                                                |

### Sound

| Option         | Type          | Default | Description         |
| -------------- | ------------- | ------- | ------------------- |
| `collectSound` | boolean/table | varies  | Sound on collection |

```lua
-- Use default sound
collectSound = true,

-- Disable sound
collectSound = false,

-- Custom sound
collectSound = {
    audioName = 'PLAYER_COLLECT', -- Name of the audio to play
    audioRef = 'DLC_PILOT_MP_HUD_SOUNDS', -- Audio reference/set to use
},
```

Default: `true` for `'nearby'` pickup type, `false` for others.

### Animations

| Option   | Type  | Default | Description                                                 |
| -------- | ----- | ------- | ----------------------------------------------------------- |
| `pickup` | table | `nil`   | Animation to play on the client when an object is collected |

```lua
animations = { -- Animations to use for this set
    pickup = { -- Pickup animation
       animDictionary = 'anim@move_m@trash', -- The animation dictionary
       animationName = 'pickup', -- The name of the animation within the dictionary
       animFlags = 0, -- Animation flag
       duration = 3000, -- Duration in milliseconds
    },
},
```

### Hints

| Option | Type   | Description                           |
| ------ | ------ | ------------------------------------- |
| `hint` | string | Default hint for all items in the set |

Individual items can override the set hint:

```lua
items = {
    { coords = vec3(123.45, 678.90, 12.34) },                    -- Uses set hint
    { coords = vec3(234.56, 789.01, 23.45), hint = 'Custom' },   -- Uses custom hint
},
```

### Rewards

```lua
rewards = {
    onCollect = {
        money = 100,
        moneyType = 'cash',  -- 'cash' or 'bank'
        item = { name = 'token', count = 1 },
    },
    onComplete = {
        money = 5000,
        moneyType = 'bank',
        item = { name = 'trophy', count = 1 },
    },
},
```

| Option       | Type   | Description                                 |
| ------------ | ------ | ------------------------------------------- |
| `onCollect`  | table  | Reward given each time an item is collected |
| `onComplete` | table  | Reward given when the set is completed      |
| `money`      | number | Amount of currency                          |
| `moneyType`  | string | `'cash'` or `'bank'`                        |
| `item`       | table  | Optional inventory item `{ name, count }`   |

### Full Example

```lua
example_set = { -- Unique set name
    label = 'Example Set', -- Display name for the set
    description = 'This is the set description shown in the UI', -- Description shown in UI
    model = 'xm3_prop_xm3_box_wood03a', -- Prop model to spawn
    icon = 'action-figure-pogo.png', -- Icon for stickers in UI (image path 'action-figure-pogo.png', or 'fa:icon-name' for Font Awesome)
    grounded = true, -- Place object on ground (default: true)
    pickupType = 'target', -- How to collect: 'target' | 'prompt' | 'nearby' (default: 'target')
    pickupDistance = 2.5, -- Distance to trigger pickup (default: 1.5)
    enabled = false, -- Enabled/disable the collectable set
    collectSound = { -- Play sound on collection: boolean|table (default: true for 'nearby', false for 'target' and 'prompt')
        audioName = 'PLAYER_COLLECT', -- Name of the audio to play
        audioRef = 'DLC_PILOT_MP_HUD_SOUNDS', -- Audio reference/set to use
    },
    hint = 'The hint for all the items', -- Default hint for all items in set
    rewards = { -- Rewards for collecting items and completing the set
        onCollect = { money = 100, moneyType = 'cash' }, -- Reward for each collected item
        onComplete = { -- Reward for completing the entire set
            money = 5000, -- Amount of money
            moneyType = 'bank', -- Money type to give ('cash', 'bank')
            item = { name = 'reward_trophy', count = 1 }, -- Item to give and amount
        },
    },
    blip = { -- Optional blip for all items (https://docs.fivem.net/docs/game-references/blips/)
        enabled = true, -- Enable/disable the blip (enabled by default)
        sprite = 478, -- Blip sprite
        colour = 1, -- Blip colour
        title = 'Example Collectable Item', -- Blip title
        scale = 0.5, -- Optional custom scale
    },
    animations = { -- Animations to use for this set
        pickup = { -- Pickup animation
            animDictionary = 'anim@move_m@trash', -- The animation dictionary
            animationName = 'pickup', -- The name of the animation within the dictionary
            animFlags = 0, -- Animation flag
            duration = 3000, -- Duration in milliseconds
        },
    },
    items = { -- List of collectable items in this set
        { coords = vec3(-140.39, -173.98, 93.70) }, -- With just coordinates
        { coords = vec3(-146.05, -166.42, 95.00), grounded = false }, -- With grounded override
        { coords = vec3(-133.97, -163.08, 93.70), model = 'prop_alien_egg_01' }, -- With model override
        { coords = vec3(-129.66, -163.58, 93.70), icon = 'fa star' }, -- With image override
        { coords = vec3(-138.27, -163.77, 93.70), hint = 'A hint just for this item' }, -- With hint override
        {
            coords = vec3(-140.48, -164.42, 93.70), -- With multiple overrides
            grounded = false,
            model = 'prop_box_ammo07a',
            icon = 'fa box-open',
            hint = 'This box looks different..',
        },
        {
            coords = vec3(-145.03, -170.40, 93.70), -- With optional blip
            blip = { -- Optional blip for this item
                sprite = 514, -- Blip sprite
                colour = 27, -- Blip colour
                title = 'Special Test Box', -- Blip title
                scale = 0.7, -- Optional custom scale
            },
        },
        {
            coords = vec3(-141.85, -166.10, 93.70), -- With animation override
            animations = { -- Animation only for this item
                pickup = { -- Pickup animation
                    animDictionary = 'anim@gangops@facility@servers@bodysearch@', -- The animation dictionary
                    animationName = 'player_search', -- The name of the animation within the dictionary
                    animFlags = 0, -- Animation flag
                    duration = 1500, -- Duration in milliseconds
                },
            },
        },
        {
            coords = vec3(-130.67, -168.78, 92.70), -- With collect sound override
            collectSound = {
                audioName = 'RANK_UP',
                audioRef = 'HUD_AWARDS',
            },
        },
    },
},
```

***

## Tips

* Use unique keys for each set (e.g., `action_figures`, `movie_posters`)
* The key is used internally; players see the `label`
* Set `enabled = false` to disable a set without removing it
* Use the [coordinate finder](/docs/premium-resources/mad_collectables/placing-new-items.md) to place items
* Test pickup distances in-game to find what feels right
* If an item you create is spawning inside another object, try using `grounded = false`, then manually adjust the `z` coordinate


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://madcap.gitbook.io/docs/premium-resources/mad_collectables/creating-sets.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
