> For the complete documentation index, see [llms.txt](https://ccfivem.gitbook.io/ccfivem-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ccfivem.gitbook.io/ccfivem-docs/player-and-ui/characters-cc_character.md).

# Characters (cc\_character)

Loading screen, login, multi-character, character creator, clothing stores, barber, tattoos and spawn selection – all in one script.

**Frameworks:** ESX Legacy, QBCore, QBox

## Features

* Custom loading screen with staff list (Discord), videos and music
* Multiple characters per player; existing characters are found and linked on first login
* Appearance editor with cameras; faces can be exported as JSON or XML
* Clothing stores with a shopping cart, barber shop, tattoo studio and surgeon
* Outfits with share codes, work uniforms, locker rooms and ped models
* Spawn selection including last position and housing (via adapter)
* Starter pack for new characters (cash, bank, vehicle, items) – handed out exactly once
* Optional accounts with username and password (scrypt-hashed, off by default)
* Replaces `esx_multicharacter`, `esx_identity`, `esx_skin`, `skinchanger` and `illenium-appearance` through compatibility bridges

## How it stores data

cc\_character creates **no character table of its own**. A character stays a `users` (ESX) or `players` (QBCore/QBox) row with its money, job and position. Only what the framework lacks is added: accounts, account-to-character mapping, appearance, tattoos, outfits, RP fields, a login log, share codes, job uniforms, ped models and the starter pack.

A character is only created **once the appearance is finished** – cancelling leaves nothing in the database.

{% hint style="info" %}
The code is protected by Cfx asset escrow. All `config/*.lua` files, `locales/*.json`, the framework bridge (`shared/cc_framework.lua`) and the compatibility bridges (`compat/*.lua`) stay editable.
{% endhint %}

## Works well with

* cc\_inventory/00%20Overview\.md) – clothing as items, starter items
* cc\_keys/00%20Overview\.md) – keys for the starter vehicle
* cc\_images%20(cc\_images)/00%20Overview\.md) – preview photos in the clothing stores
* cc\_weather/00%20Overview\.md) – fixed time/weather for the clothing photo tool
* cc\_lib/00%20Overview\.md) – shared notifications and dialogs

## Pages

* Installation
* Configuration
* API
* FAQ

## Installation

See also the general installation guide, dependencies and the framework bridge.

### Requirements

| Resource                                                | Required | Notes                                                     |
| ------------------------------------------------------- | -------- | --------------------------------------------------------- |
| `oxmysql`                                               | yes      | declared as `dependency`                                  |
| `es_extended`, `qb-core` or `qbx_core`                  | yes      | one framework                                             |
| FXServer with **Node 22**                               | yes      | `node_version '22'` is needed for password hashing        |
| `cc_lib`                                                | optional | shared notifications/dialogs, built-in fallback otherwise |
| `cc_inventory`                                          | optional | clothing as items and starter items                       |
| `cc_keys`                                               | optional | keys for the starter vehicle                              |
| `cc_images`                                             | optional | clothing preview photos                                   |
| `cc_weather`                                            | optional | fixed time/weather while taking photos                    |
| `chat` / `cc_chat`                                      | optional | `/ccdiscord` output in chat                               |
| `qb-houses`, `ps-housing`, `qs-housing`, `esx_property` | optional | properties in spawn selection                             |

`esx_skin`, `skinchanger` and `illenium-appearance` are **not** needed – cc\_character provides their exports and events itself. The manifest declares `provide 'illenium-appearance'`.

### 1. Copy the resource

Copy the folder to `resources/[crankchaos]/cc_character`.

### 2. Import the SQL file

Import once:

* `sql/07-crankchaos-charaktere.sql` – accounts, mapping, appearance, tattoos, outfits, RP fields, login log

```bash
mysql <database> < sql/07-crankchaos-charaktere.sql
```

The file is repeatable and deletes nothing. Tables for clothing, uniforms, ped models and the starter pack create themselves on start. `sql/08-crankchaos-kleidung.sql` only documents these self-created tables for manual database maintenance – you do not need to import it.

### 3. Framework-specific steps

#### ESX Legacy

Enable multichar in `es_extended/shared/config/main.lua`:

```lua
Config.Multichar = GetResourceState("esx_multicharacter") ~= "missing"
    or GetResourceState("cc_character") ~= "missing"
```

{% hint style="warning" %}
Re-apply this line after every ESX update. cc\_character reports it in the console on start if it is missing.
{% endhint %}

#### QBCore / QBox

Nothing to change.

### 4. server.cfg

Remove the default loading screen and do **not** start `esx_multicharacter`, `esx_identity`, `esx_skin`, `skinchanger` or `illenium-appearance`.

```cfg
ensure oxmysql
ensure es_extended        # or qb-core / qbx_core
ensure cc_lib             # optional
ensure cc_character       # before anything that expects a loaded player
ensure cc_inventory       # optional

## Discord bot token – only as a convar, never in a config file
set cc_discord_token "YOUR_BOT_TOKEN"
```

### 5. ACE permissions

```cfg
add_ace group.admin cc_character.admin allow      # /pedmenu /firstcharacter /wardrobe /shop /migrateskins
add_ace group.admin cc.character.photos allow     # /ccphotos
add_ace group.admin command.ccdiscord allow       # /ccdiscord

## optional: extra character slots, see Config.BonusSlots
## add_ace group.vip cc.character.plus allow
```

### 6. Loading screen media

Videos and music go to `loading/media/`. Nothing is shipped. Supported formats and the playlist are set in `config/loading.lua`.

### 7. Discord staff list (optional)

1. Set `Config.Discord.enabled = true` in `config/discord.lua` and fill in the guild and role IDs (as strings in quotes).
2. The bot needs the **SERVER MEMBERS INTENT**, membership in your guild and no further permissions.
3. Put the token **only** into `server.cfg` as `set cc_discord_token "..."` (the convar name is `Config.Discord.tokenConvar`).

## Configuration

All options live in `config/`. The code is escrow-protected; config files, `locales/*.json`, `shared/cc_framework.lua`, `shared/cc_characters.lua`, `shared/cc_vehicles.lua` and `compat/*.lua` stay editable.

| File                    | Contents                                                                                                   |
| ----------------------- | ---------------------------------------------------------------------------------------------------------- |
| `config/config.lua`     | slots, deleting, switching, login, names, birth date, height, nationalities, buckets, transitions, logging |
| `config/loading.lua`    | loading screen: server name, logo, videos, music, links, rules                                             |
| `config/discord.lua`    | Discord guild, roles, staff order                                                                          |
| `config/appearance.lua` | editor categories, limits, cameras, tattoos, photo tool (`Config.Photos`)                                  |
| `config/spawns.lua`     | spawn points, preview, cameras, housing adapter                                                            |
| `config/shops.lua`      | clothing stores, barbers, tattoo studios, uniforms, prices, locks                                          |
| `config/clothing.lua`   | entry fees, barber, tattoo prices, blips, blacklist, ankle monitor, catalogue, surgeon                     |
| `config/wardrobe.lua`   | outfits, outfit rooms, uniforms, ped models, command limits, compatibility                                 |
| `config/starter.lua`    | starter pack                                                                                               |
| `config/panel.lua`      | look of the appearance editor (accent, corners, layout, cinematic camera)                                  |

### Characters (`config/config.lua`)

```lua
Config.Locale = 'de'
Config.Slots = 5
Config.BonusSlots = {
    -- ['cc.character.plus'] = 2,
}
Config.Delete = 'hard'
Config.DeleteNeedsName = true
Config.AllowSwitch = true
Config.SwitchCommand = 'charakter'
```

* **`Slots`** – character slots per player.
* **`BonusSlots`** – extra slots per ACE permission, checked on the server.
* **`Delete`** – `'hard'` deletes the character and everything attached to it (vehicles, licences, invoices, appearance, outfits). `'soft'` keeps it restorable. `DeleteNeedsName` makes the player type the name to confirm.
* **`DeleteCascade`** – with `'hard'`, every table with an `identifier`, `owner` or `ordered_by` (ESX) or `citizenid` (QBCore/QBox) column is found automatically. Use `tables` for extra `{ table, column [, nullify = true] }` entries and `skip` for tables that must never be touched.
* **`AllowSwitch` / `SwitchCommand`** – allow switching characters in-game with `/charakter`.

{% hint style="danger" %}
`Config.Delete = 'hard'` is final. Switch to `'soft'` if you want deleted characters to stay restorable.
{% endhint %}

### Login (`Config.Login`)

```lua
Config.Login = {
    enabled = false,
    allowRegister = true,
    usernameMin = 3, usernameMax = 24,
    passwordMin = 8,
    maxAttempts = 5, lockSeconds = 300,
    maxAttemptsPerIp = 20,
    remember = true,
}
```

With `enabled = false` (default) there is no login form and the account is bound to the player's FiveM licence. When enabled, only a scrypt hash is stored – never the password.

### Character data

```lua
Config.Names  = { minLength = 2, maxLength = 16, capitalise = true, forbidden = { 'admin', ... } }
Config.Birth  = { format = 'TT.MM.JJJJ', minAge = 18, maxAge = 90 }
Config.Height = { min = 150, max = 210, default = 180 }
Config.Nationalities = { 'Deutschland', 'Österreich', ... }
```

### Routing buckets, transitions, logging

```lua
Config.Buckets = { base = 5000, lockdown = 'strict', population = false }
```

Every player gets their own bucket (`base + server ID`) while creating a character, so players do not see each other. `Config.Transition` holds fade and loading times in ms. `Config.Log` toggles which events are logged (registration, login, failed login, create, delete, security, shop).

### Loading screen and Discord

* `Config.Loading.server` – `name`, `claim` (locale key) and `logo` (file in `loading/media/`; empty shows the server name). Videos and music are configured in the same file.
* `Config.Discord.enabled = false` by default – no request is made and the staff area is hidden. Guild and role IDs must be **strings**. The token is read from the convar named in `tokenConvar` (default `cc_discord_token`).

### Spawns (`config/spawns.lua`)

* `Config.Spawns.lastPosition = true` – existing characters continue where they logged out (the position comes from the framework). New characters always choose from `Config.Spawns.starters`.
* `Config.Spawns.housing` – `enabled` (`'auto'`, `true`, `false`), `resource` (default `qb-houses`), `export` and how it is called.

### Shops (`config/shops.lua`, `config/clothing.lua`)

* `Config.Shops.enabled` – master switch; `false` removes all shops, blips and peds (for servers that sell clothes through another script).
* `Config.Shops.clothing`, `.barber`, `.tattoo`, `.uniforms`, `.surgeon` – locations and prices.
* `Config.EntryFees` – `clothing = 0, barber = 0, tattoo = 0, surgeon = 250`.
* `Config.Barber.allOverlays`, `Config.TattooPrices`, `Config.ShopBlips`, `Config.Blacklist`, `Config.AnkleMonitor`, `Config.Catalogue` (see `config/catalogue.example.json`).

### Wardrobe (`config/wardrobe.lua`)

```lua
Config.Outfits  = { max = 30, codeTtlDays = 0, importRate = { count = 5, window = 60 }, ... }
Config.Commands = { reloadCooldown = 10, migrateBatch = 100 }
Config.Compat   = { illenium = true, esxSkin = true, customize = false }
```

* `Config.OutfitRooms`, `Config.Uniforms`, `Config.PedModels` – locker rooms, job uniforms and allowed ped models.
* `Config.Compat.customize` – if `true`, third-party calls such as `startPlayerCustomization` may open the nearest real shop of the matching type (with its prices and locks).

### Starter pack (`config/starter.lua`)

```lua
Config.StarterPack = {
    enabled = true,
    money = { bank = 9500, cash = 500 },
    vehicle = { model = 'cruiser', garage = 'nearest', fallbackGarage = 'legion', keys = true },
    items = { { name = 'phone', count = 1 } },
    maxPerAccount = 5,
    delay = 4000,
}
```

Each part is handed out exactly once per new character; characters that existed before get none. Items need cc\_inventory/00%20Overview\.md), keys need cc\_keys/00%20Overview\.md).

### Editor look (`config/panel.lua`)

`Config.Panel.defaults` sets accent, corners, layout and cinematic camera; `Config.Panel.lock` locks a setting for all players.

## Exports, Events & Commands

### Commands

| Command                                     | Permission            | Purpose                                                           |
| ------------------------------------------- | --------------------- | ----------------------------------------------------------------- |
| `/charakter` (`Config.SwitchCommand`)       | –                     | switch character (if `Config.AllowSwitch`)                        |
| `/ccauswahl`                                | –                     | refocus the character selection                                   |
| `/reloadskin`                               | –                     | reload own appearance (cooldown `Config.Commands.reloadCooldown`) |
| `/clearstuckprops`                          | –                     | remove stuck props                                                |
| `/pedmenu [id]`                             | `cc_character.admin`  | ped model menu for a player                                       |
| `/firstcharacter [id]`                      | `cc_character.admin`  | open the editor for free, anywhere                                |
| `/wardrobe`                                 | `cc_character.admin`  | open the wardrobe                                                 |
| `/shop [clothing\|barber\|tattoo\|surgeon]` | `cc_character.admin`  | open a shop anywhere                                              |
| `/migrateskins [source] [dry]`              | `cc_character.admin`  | import appearances from old skin scripts                          |
| `/ccphotos`                                 | `cc.character.photos` | clothing photo tool                                               |
| `/ccdiscord`                                | `command.ccdiscord`   | reload the Discord staff list                                     |

### Server exports

| Export                                                 | Returns                                                    |
| ------------------------------------------------------ | ---------------------------------------------------------- |
| `OpenWardrobe(src, { coords?, radius?, ttl? })`        | token or `nil`                                             |
| `GetOutfits(identifier)`                               | `{ id, label, data, verified }[]`                          |
| `OpenShop(src, kind, opts)`                            | `kind`: `clothing`, `barber`, `tattoo`, `surgeon`, `admin` |
| `SetMenuSections(src, sections)`                       | –                                                          |
| `IsSlotLocked(src, part, id)`                          | `boolean`                                                  |
| `HasPed(src)`                                          | `boolean`                                                  |
| `WearApply(src, list)` / `WearClear(src)`              | –                                                          |
| `WearVariant(src)`                                     | `'male'`, `'female'` or `nil`                              |
| `WearMigrate(src)`                                     | `boolean`                                                  |
| `DressedAppearance(identifier, appearance)`            | –                                                          |
| `Hash(password, cb)` / `Verify(password, encoded, cb)` | callback with hash / `boolean`                             |

```lua
exports.cc_character:OpenShop(source, 'clothing', { anywhere = true, free = true })
local token = exports.cc_character:OpenWardrobe(source, { coords = vec3(452.0, -992.0, 30.7), radius = 3.0 })
```

### Client exports

`WearApply(list)`, `WearClear()`, `WearWorn()`, `WearVariant()`.

### Compatibility exports

**skinchanger** (also as `exports.skinchanger:*` while the real resource is not running): `GetSkin`, `GetMaxVals`, `LoadSkin`, `GetData`, `LoadClothes`, `Change`.

**illenium-appearance / fivem-appearance** (while the real resource is not running, `Config.Compat.illenium`): `getPedModel`, `getPedComponents`, `getPedProps`, `getPedHeadBlend`, `getPedFaceFeatures`, `getPedHeadOverlays`, `getPedHair`, `getPedTattoos`, `getPedAppearance`, `setPlayerModel`, `setPedHeadBlend`, `setPedFaceFeatures`, `setPedHeadOverlays`, `setPedHair`, `setPedEyeColor`, `setPedComponent`, `setPedComponents`, `setPedProp`, `setPedProps`, `setPedTattoos`, `setPlayerAppearance`, `setPedAppearance`, `startPlayerCustomization(cb, config)` (only opens a shop with `Config.Compat.customize = true`).

### Compatible events

* Client: `skinchanger:loadSkin`, `loadClothes`, `getSkin`, `getData`, `loadDefaultModel`, `change`; `esx_skin:openSaveableMenu`, `openMenu`, `openRestrictedMenu`; `illenium-appearance:client:reloadSkin`. Fires `skinchanger:modelLoaded`.
* Server: `esx_skin:save`, `illenium-appearance:server:saveAppearance`.

### Public events

| Event                       | Side   | Payload           |
| --------------------------- | ------ | ----------------- |
| `cc_character:playing`      | server | `src, identifier` |
| `cc_character:schemaReady`  | server | –                 |
| `cc:characterChanged`       | server | `src, identifier` |
| `cc_character:wearRejected` | client | `rejected`        |

## FAQ & Troubleshooting

**The resource does not start or complains about Node.** cc\_character needs an FXServer build with Node 22 (`node_version '22'`). Update your server artifacts.

**On ESX the character selection never appears.** The `Config.Multichar` line in `es_extended/shared/config/main.lua` is missing – see Installation. Re-apply it after every ESX update.

**Errors about missing tables on first start.** The base tables do not create themselves. Import `sql/07-crankchaos-charaktere.sql` once.

**Do I still need esx\_skin, skinchanger or illenium-appearance?** No. Remove them from `server.cfg`; cc\_character provides their exports and events.

**My old characters are gone.** They are not. Existing characters in `users`/`players` are found on first login and linked to the new account – nothing is deleted.

**The clothing stores show no preview photos.** Photos are not shipped. They are created with `/ccphotos` and stored via cc\_images%20(cc\_images)/00%20Overview\.md).

**Houses are missing from spawn selection.** Housing is connected via adapter (`Config.Spawns.housing`). Without a supported housing resource the group is intentionally missing.

**The Discord staff list is empty.** Check `Config.Discord.enabled`, that guild and role IDs are strings in quotes, that the bot has the SERVER MEMBERS INTENT and that `cc_discord_token` is set in `server.cfg`. Use `/ccdiscord` to reload.

**Clothing is not an item.** Clothing as items requires cc\_inventory/00%20Overview\.md).

**Is the password code encrypted?** `server/crypto.js` is JavaScript and not encrypted by escrow; it contains no secrets.

Still stuck? See Support.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://ccfivem.gitbook.io/ccfivem-docs/player-and-ui/characters-cc_character.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
