> For the complete documentation index, see [llms.txt](https://atiysus-organization.gitbook.io/aty-scripts/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://atiysus-organization.gitbook.io/aty-scripts/clothing/clothes-as-items.md).

# Clothes as Items

## Clothes as Items

On some servers clothes are inventory items: a jacket in the bag, a mask you put on and take off, a stolen hat. ATY Clothing works with that out of the box when it runs next to **aty\_inventory**, and it keeps what the character wears, what the inventory says is worn and what the database has saved as **one story**. This page explains the model, every setting, the console commands and how to plug in another inventory.

If you only want it on: install both resources, start `aty_inventory` anywhere in `server.cfg`, and leave `Config.ClothingItems` as it is. Everything below is detail.

### The problem it solves

With clothes as items, what a character has on exists in two places:

* the **skin** the clothing menu saves (`playerskins` on QBCore, `users` on ESX), and
* the **worn kit**, the items the inventory says the character has put on.

Left alone the two drift apart, and every way "clothes as items" can feel broken is that drift:

| What a player sees                                   | Why it happened                                                                         |
| ---------------------------------------------------- | --------------------------------------------------------------------------------------- |
| A mask bought in a shop is not in the bag            | Only a purchase ever handed items over; a creator or an admin's `/skin` never did       |
| An outfit made in the admin menu never becomes items | Same: the save did not tell the inventory                                               |
| Taking a jacket off brings the *old* jacket back     | The inventory restores "what was under it", and what was under it was the skin's jacket |
| A jacket taken off comes back on the next login      | The skin still said jacket, and the skin loads first                                    |
| Buying a new top leaves the old one worn under it    | The new item arrived in the bag; the old one stayed on                                  |

### The model

```
          ┌──────────────── skin → items ────────────────┐
 shop · creator · /skin · wardrobe outfit · login · API
          │                                              ▼
     saved skin  ───────────────────────────────►  worn kit + bag
          ▲                                              │
          └──────────────── items → skin ────────────────┘
              the player puts an item on or takes one off
```

**Skin → items.** After every save the skin made, the inventory is handed every clothing slot of the skin and brings the worn kit into line:

| The slot's piece is…                                          | What happens                                                                     |
| ------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| already what the kit shows                                    | nothing                                                                          |
| a look the player owns (it is in the bag)                     | that item goes on                                                                |
| a new look                                                    | an item is made and put **straight on the slot**, with no room needed in the bag |
| another look than the one worn                                | the worn item goes to the bag, then one of the rules above applies               |
| bare (nothing on)                                             | the worn clothing item comes off into the bag                                    |
| held by something that is not a clothing item (a cap, a vest) | left alone — the player chose it                                                 |

It is idempotent, so running it after every save never piles items up.

**Items → skin.** When the player puts a clothing item on or takes one off — dragging it in the inventory, an admin command, another script — the inventory says so and the saved skin follows:

* putting one on writes its look into the skin
* taking one off writes the slot's **bare value**, and the clothes the skin had saved **do not come back**
* taking a top off also bares the arms, because a jacket's sleeves are the arms component
* putting a top back on restores the sleeves it was made with (the item remembers them), or the arms GTA pairs with that jacket

Only the slots that **changed** are written, so putting on a hat never rewrites a saved jacket.

### When it runs

| Event                                                                                | Source in the console | Notes                                                                                                          |
| ------------------------------------------------------------------------------------ | --------------------- | -------------------------------------------------------------------------------------------------------------- |
| A shop purchase                                                                      | `shop`                | The skin was saved first; the sync follows                                                                     |
| A creator save, including an admin's `/skin <id> creator` and the new-character flow | `creator`             | This was the gap: admin-menu clothes never became items                                                        |
| Wearing a wardrobe outfit                                                            | `outfit`              | The outfit is now what the character wears, so it is saved as the skin as well                                 |
| Another script setting the skin (`SavePlayerSkin`, the `qb-clothing:saveSkin` event) | `api`                 |                                                                                                                |
| A player spawns                                                                      | `login`               | Characters whose clothes are not items yet get theirs; characters that already have them lose and gain nothing |
| `clothingitems sync <id>` in the console                                             | `console`             | Forces it for one player                                                                                       |

{% hint style="info" %}
**Upgrading a live server.** The first time a character spawns after the update, every piece of clothing in its saved skin becomes a worn item — up to ten per character, made once. A player who wears a cap or a vest item keeps it. Turn this off with `Config.ClothingItems.OnLogin = false`; items are then made the next time that character saves in a clothing menu.
{% endhint %}

### Setup

Both sides have to be on.

**1. aty\_clothing** — `Config.ClothingItems` (on by default):

```lua
Config.ClothingItems = {
    Enabled = true,
    Inventory = "auto",
    Equip = true,
    OnLogin = true,
}
```

| Key         | Default  | What it does                                                                                                                                                                            |
| ----------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Enabled`   | `true`   | Turns all of it on or off                                                                                                                                                               |
| `Inventory` | `"auto"` | `"auto"` finds the supported inventory that is running. Or name one: `"aty_inventory"`, `"core_inventory"`, `"custom"`. The resource name of a renamed copy of aty\_inventory works too |
| `Equip`     | `true`   | The two-way flow above. `false` is the older behaviour: a purchase adds only what it sold to the bag, and the worn kit and the skin are not tied together                               |
| `OnLogin`   | `true`   | Tell the inventory what the skin wears when a player spawns                                                                                                                             |
| `Custom`    | —        | For `Inventory = "custom"`: `function(src, pieces, skin)`, see Other inventories                                                                                                        |

**2. aty\_inventory** — in its `Config.Wear`:

```lua
Config.Wear.enabled = true
Config.Wear.clothingItems = { hat = 'clothing_hat', mask = 'clothing_mask', torso = 'clothing_top', … }
Config.Wear.clothingRestore = 'bare'
```

`clothingItems` names the item each worn slot uses, `clothingRestore = 'bare'` makes a clothing item come off to the slot's bare value rather than to what the skin had saved, and `Config.Wear.bare` holds those bare values per freemode model. All three ship ready. They are explained on aty\_inventory's *Clothing & Wear* page. Use an aty\_inventory version that has `SyncClothing`; with an older one aty\_clothing prints `SyncClothing is missing` once and falls back to nothing.

{% hint style="warning" %}
Keep `clothingRestore = 'bare'` while `Equip` is on. With `'previous'` taking an item off puts back what was under it, which is the skin's jacket again — the exact thing this page removes.
{% endhint %}

#### Check it

```
clothingitems status
clothingitems sync <player id>
```

`status` prints whether it is on, which inventory it found and how it is set. `sync` runs the skin → items step for one online player and says how many items it made. Both run from the server console, and in game for a clothing admin.

### What the player sees

* A shop purchase, a creator save or a login that **made** items says how many (*"3 item(s) added to your inventory"*)
* Pieces that could not become items because something refused (a worn bag whose room is in use, say) are counted in *"2 item(s) did not fit in your inventory"*
* A slot with a cap, a vest or any other worn item that is not a clothing item is left alone, without a message
* Undershirts, chains, decals, bracelets and arms are not items in aty\_inventory and stay part of the skin; **Gloves** and other carved menus (`Config.Slots`) are the same
* Every item keeps its exact look and a label such as *Top #60-1*, and the inventory shows a photo of that very piece when the photo studio has taken one

### Other inventories

aty\_clothing is not tied to one inventory: each is a small adapter in `server/items.lua`, and anything else can be reached with the `custom` hook. Which ones are possible depends on what the inventory's authors publish. This is what was checked, and where.

| Inventory                                                       | Status                                     | How                                                                                                                                                                                                                                                                                                                                                         |
| --------------------------------------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **aty\_inventory**                                              | Full                                       | `SyncClothing` and the `wearChanged` event; every behaviour on this page                                                                                                                                                                                                                                                                                    |
| **core\_inventory**                                             | Works through its documented client export | After a save, the client calls `addClothingItemFromPedSkinInClothHolder(ped, false, true, false)`, which its docs describe as the way for a custom clothing script to hand an outfit to the holder. The reverse direction (items → skin) is not available to us, because the docs name no event or export for it. Not tested against a live core\_inventory |
| **NextGen inventory**                                           | Needs nothing from us                      | Its clothing system reads the ped's appearance itself (its docs: sync on join and when the inventory opens). Set its clothing `bridge` to `'native'`, since aty\_clothing is not on its list of bridges, or write a `custom` bridge as its docs describe                                                                                                    |
| **tgiann-inventory**                                            | Not possible                               | Its seller states that its clothing-as-item feature requires `tgiann-clothing` and is not compatible with other clothing scripts                                                                                                                                                                                                                            |
| **qs-inventory, codem-inventory, origen\_inventory** and others | Use the hook                               | No public documentation of a clothing export was found. If your inventory has a function that gives a worn clothing item, call it from `Custom`                                                                                                                                                                                                             |
| **Stock ox\_inventory, qb-inventory**                           | No worn items                              | They have no wearable clothing of their own; aty\_clothing keeps the skin only                                                                                                                                                                                                                                                                              |

#### The `custom` hook

```lua
Config.ClothingItems = {
    Enabled = true,
    Inventory = "custom",
    Custom = function(src, pieces, skin)
        -- pieces: { component = id | prop = id, drawable, texture, gender, arms?, arms_2? }
        -- Hand them to your inventory. Return how many items you made and how many you could not.
        local made = 0
        for _, piece in ipairs(pieces) do
            -- e.g. exports['my_inventory']:GiveWornClothing(src, piece)
        end
        return made, 0
    end,
}
```

`pieces` lists every clothing slot of the saved skin in GTA's own ids — the same list aty\_inventory is given, bare slots included (a prop below zero, a component at its bare value) — so your function decides what a bare slot means for your inventory. `skin` is the whole saved skin. An error inside the function is caught and printed once; it never stops a purchase that has already been paid for and saved.

### For developers

The pure part — which pieces a skin has, and what a change of worn items means for a skin — is `server/clothing_pieces.lua`, covered by `tests/items.spec.lua`. `server/items.lua` holds the adapters and the events.

| Name                                | Where                            | What                                                       |
| ----------------------------------- | -------------------------------- | ---------------------------------------------------------- |
| `ClothingOutfitPieces(skin)`        | server, global                   | Every clothing slot of a skin as pieces                    |
| `ClothingSkinPatch(changes)`        | server, global                   | What the inventory's `changes` mean as skin keys           |
| `SyncClothingItems(src, skin, why)` | server, global                   | Runs the skin → items step for one player                  |
| `aty_inventory:wearChanged`         | server event, from the inventory | `(src, kit, changes)`: the items → skin step listens to it |

### Troubleshooting

| Symptom                                                    | Cause and fix                                                                                                                                                                      |
| ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Nothing becomes an item                                    | `clothingitems status` — is the inventory found, is `Enabled` on? `Config.Wear.enabled` and `Config.Wear.clothingItems` in aty\_inventory must be on                               |
| Console: `a worn slot has no clothing item`                | `Config.Wear.clothingItems` has no item for a slot that aty\_inventory can wear, or the named item is not wearable in that slot. Fix the table; the console says it once per start |
| Console: `SyncClothing is missing`                         | aty\_inventory is too old for the two-way flow. Update it, or set `Equip = false` for the older behaviour                                                                          |
| A taken-off jacket still comes back                        | `Config.Wear.clothingRestore` is `'previous'`, or `Equip` is `false`. Set `'bare'` and `Equip = true`                                                                              |
| Taking a top off leaves odd arms                           | The bare values in aty\_inventory's `Config.Wear.bare` do not match your clothing. Adjust the arms (component 3) and top (11) values for your pack                                 |
| "did not fit in your inventory"                            | The bag was full when a worn item had to move into it. Free a slot and run `clothingitems sync <id>`                                                                               |
| A cap or vest item stays on when buying clothes            | By design: items that are not clothing items are the player's choice and are left alone                                                                                            |
| Each login adds nothing                                    | Correct. The sync only makes what is missing                                                                                                                                       |
| Items missing for a ped model that is not a freemode model | Only the two freemode models are supported; other ped skins have no clothing items                                                                                                 |
