> For the complete documentation index, see [llms.txt](https://izzyshop-1.gitbook.io/izzyshop-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://izzyshop-1.gitbook.io/izzyshop-docs/multicharacter-resources/multicharacter-v5/configuration.md).

# Configuration

Modern multi-character selector with 3D ped preview, spawn selector, Tebex slot unlock, and ESX / QBCore support.

#### Configuration <a href="#izzy-multicharacterv5-configuration-configuration" id="izzy-multicharacterv5-configuration-configuration"></a>

#### `server/sv_cfg.lua` — Tebex <a href="#izzy-multicharacterv5-configuration-server-sv-cfg-lua-tebex" id="izzy-multicharacterv5-configuration-server-sv-cfg-lua-tebex"></a>

```lua
tebexSecret = "YOUR_TEBEX_SECRET"   -- Tebex plugin secret
packageId = 1234567                    -- Numeric package ID for slot unlock
```

| Property        | Type | Default | Description                                                                       |
| --------------- | ---- | ------- | --------------------------------------------------------------------------------- |
| **Unlock Slot** | `—`  | `—`     | Players redeem Tebex transaction IDs or admin codes in the **Unlock Slot** modal. |
| `isKeyValid`    | `—`  | `—`     | `isKeyValid` checks Tebex API when the code is not in `codes.json`.               |

#### `shared/cfg.lua` — Main settings <a href="#izzy-multicharacterv5-configuration-shared-cfg-lua-main-settings" id="izzy-multicharacterv5-configuration-shared-cfg-lua-main-settings"></a>

| Option                  | Default        | Description                                            |
| ----------------------- | -------------- | ------------------------------------------------------ |
| `locale`                | `'en'`         | Active language key from `cfg.locales`                 |
| `defaultFreeSlotAmount` | `2`            | Free character slots per player                        |
| `maxSlotAmount`         | `4`            | Maximum slots shown in UI                              |
| `canDeleteCharacter`    | `true`         | Allow delete button in UI                              |
| `minimumAge`            | `18`           | Minimum DOB age on create                              |
| `manualShutdown`        | `true`         | Shutdown GTA loading screen when ready                 |
| `useOwnSpawnSelector`   | `true`         | Use built-in spawn UI                                  |
| `useQBApartments`       | `true`         | QB apartment spawn integration                         |
| `housing`               | `'none'`       | `none` / `qb-houses` / `ps-housing` / `qbx_properties` |
| `giveStarterItems`      | `true`         | Give items on new character                            |
| `pedCoords`             | vector4        | 3D ped preview position                                |
| `firstSpawn`            | vector4        | First spawn for new characters                         |
| `createCodeCommand`     | `'createCode'` | Admin command to add codes                             |
| `admins`                | table          | License keys allowed to run `createCode`               |

#### Starter items <a href="#izzy-multicharacterv5-configuration-starter-items" id="izzy-multicharacterv5-configuration-starter-items"></a>

```lua
starterItems = {
    { name = 'phone', amount = 1 },
    { name = 'id_card', amount = 1 },
    -- ...
}
```

Match item names to your inventory (ox\_inventory / qb-inventory).

#### Spawn locations <a href="#izzy-multicharacterv5-configuration-spawn-locations" id="izzy-multicharacterv5-configuration-spawn-locations"></a>

Add entries under `cfg.locations`:

```lua
{
    id = 'my_spawn',
    name = 'My Location',
    coords = vector4(x, y, z, heading),
    description = 'Short text shown on the map UI.'
}
```

{% hint style="info" %}
`lastLocation` id is handled specially (last disconnect position).
{% endhint %}

#### UI colors <a href="#izzy-multicharacterv5-configuration-ui-colors" id="izzy-multicharacterv5-configuration-ui-colors"></a>

```lua
colors = { primary = '#8FD733', secondary = '#43993E', tertiary = '#83B93A' }
```

#### Currency display <a href="#izzy-multicharacterv5-configuration-currency-display" id="izzy-multicharacterv5-configuration-currency-display"></a>

```lua
currency = { language = 'en-US', currency = 'USD' }
```

Used for cash/bank formatting in the character details panel.

#### Character slots <a href="#izzy-multicharacterv5-configuration-character-slots" id="izzy-multicharacterv5-configuration-character-slots"></a>

| Type             | How it works                                                  |
| ---------------- | ------------------------------------------------------------- |
| **Free slots**   | First `defaultFreeSlotAmount` slots (e.g. 1–2)                |
| **Locked slots** | Slots above free count until redeemed                         |
| **Extra slots**  | `slots.json` stores bonus slots per license after code redeem |

**Player flow:**

1. Empty free slot → Create character
2. Locked slot → Enter Tebex / admin code → slot unlocks
3. Redeem success → `slots.json` updated, config refreshed client-side

***

#### Tebex & admin codes <a href="#izzy-multicharacterv5-configuration-tebex-admin-codes" id="izzy-multicharacterv5-configuration-tebex-admin-codes"></a>

#### Tebex (automatic) <a href="#izzy-multicharacterv5-configuration-tebex-automatic" id="izzy-multicharacterv5-configuration-tebex-automatic"></a>

1. Set `tebexSecret` and `packageId` in `sv_cfg.lua`.
2. Player enters payment / transaction ID in unlock modal.
3. Server validates via Tebex API or local `codes.json`.

#### Admin codes (manual) <a href="#izzy-multicharacterv5-configuration-admin-codes-manual" id="izzy-multicharacterv5-configuration-admin-codes-manual"></a>

**Console or in-game admin** (license must be in `cfg.admins`):

```lua
createCode MYCODE123
```

Adds `MYCODE123` to `codes.json`. Player redeems the same way as Tebex codes.

**Remove used codes:** Handled in `transactions.json` — do not edit while server is running unless you know what you are doing.

***

#### Appearance resources <a href="#izzy-multicharacterv5-configuration-appearance-resources" id="izzy-multicharacterv5-configuration-appearance-resources"></a>

Preview and spawn load skins from your DB. Supported resources (auto-detect by resource state):

| Resource                 | Support   |
| ------------------------ | --------- |
| `izzy-appearance`        | Yes       |
| `rcore_clothing`         | Yes       |
| `qb-clothing`            | Yes       |
| `illenium-appearance`    | Yes       |
| `fivem-appearance`       | Yes       |
| `esx_skin` / skinchanger | Yes (ESX) |

**New character:** Redirects to the first available creation menu (`izzy-appearance`, `qb-clothes`, `esx_skin`, etc.).

**Default clothes:** `cfg.defaultClothes["m"]` and `cfg.defaultClothes["f"]` used when no skin exists (ESX new chars).

***

#### Housing integration <a href="#izzy-multicharacterv5-configuration-housing-integration" id="izzy-multicharacterv5-configuration-housing-integration"></a>

Set `cfg.housing`:

| Value            | Integration                         |
| ---------------- | ----------------------------------- |
| `none`           | Locations from `cfg.locations` only |
| `qb-houses`      | QB house spawns in selector         |
| `ps-housing`     | PS-Housing spawns                   |
| `qbx_properties` | QBX properties spawns               |

Requires the housing resource to be started and configured on your server.

***

#### Locales <a href="#izzy-multicharacterv5-configuration-locales" id="izzy-multicharacterv5-configuration-locales"></a>

Default language pack is under `cfg.locales['en']`.

**Add Turkish (example):**

```lua
cfg.locale = 'tr'

cfg.locales['tr'] = {
    fillParts = "Tüm alanları doldur",
    header = {
        title = 'Karakter Seçici',
        description = 'Karakterlerini yönet ve sunucuya gir.',
    },
    -- copy keys from ['en'] and translate ...
}
```

All UI strings are sent to NUI via `SET_LANG` on open.

#### Commands & events <a href="#izzy-multicharacterv5-configuration-commands-events" id="izzy-multicharacterv5-configuration-commands-events"></a>

\
Commands

| Command             | Who                     | Description                                          |
| ------------------- | ----------------------- | ---------------------------------------------------- |
| `createCode <code>` | Console or `cfg.admins` | Add unlock code to `codes.json`                      |
| `logout`            | Player (framework)      | Return to character select (see `shared/shared.lua`) |

#### Client events <a href="#izzy-multicharacterv5-configuration-client-events" id="izzy-multicharacterv5-configuration-client-events"></a>

| Event                                | Description                      |
| ------------------------------------ | -------------------------------- |
| `izzy-multicharacterv5:open`         | Open character selector          |
| `izzy-multicharacterv5:close`        | Close UI                         |
| `izzy-multicharacterv5:openSpawn`    | Open spawn selector only         |
| `izzy-multicharacterv5:updateConfig` | Refresh slot/config data         |
| `qb-spawn:client:setupSpawns`        | QB spawn bridge → opens spawn UI |

#### Exports (client) <a href="#izzy-multicharacterv5-configuration-exports-client" id="izzy-multicharacterv5-configuration-exports-client"></a>

```lua
-- Open spawn selector (e.g. after apartment logic)
exports['izzy-multicharacterv5']:open()
```

Defined in `client/spawn.lua` as `open`.

#### Server events <a href="#izzy-multicharacterv5-configuration-server-events" id="izzy-multicharacterv5-configuration-server-events"></a>

<br>

| Event                                    | Description                              |
| ---------------------------------------- | ---------------------------------------- |
| `izzy-multicharacterv5:server:play`      | Character selected / spawn pipeline      |
| `izzy-multicharacterv5:server:applyCode` | Slot unlock after redeem                 |
| `izzy-multicharacterv5:server:setBucket` | Routing bucket for char select isolation |

#### ESX notes <a href="#izzy-multicharacterv5-configuration-esx-notes" id="izzy-multicharacterv5-configuration-esx-notes"></a>

| Property                | Description                                                                                                            |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `prefixForESX = "char"` | `prefixForESX = "char"` — default ESX multichar identifier prefix; change only if your server uses a different scheme. |
| Uses `esx`              | playerLoaded and standard ESX character queries (see server implementation).                                           |

#### QBCore notes <a href="#izzy-multicharacterv5-configuration-qbcore-notes" id="izzy-multicharacterv5-configuration-qbcore-notes"></a>

{% hint style="info" %}
Nationality field shown in create UI and stored for QB.
{% endhint %}

{% hint style="info" %}
`useQBApartments` adds apartment options to spawn flow.
{% endhint %}

{% hint style="info" %}
Compatible with `qb-spawn:client:setupSpawns` event.
{% endhint %}

#### NUI callbacks (reference) <a href="#izzy-multicharacterv5-configuration-nui-callbacks-reference" id="izzy-multicharacterv5-configuration-nui-callbacks-reference"></a>

| Callback         | Purpose                            |
| ---------------- | ---------------------------------- |
| `play`           | Start game with selected character |
| `delete`         | Delete character by identifier     |
| `redeem`         | Submit unlock code                 |
| `updateSelected` | Change preview ped / gender        |
| `spawn`          | Confirm spawn location             |
| `updateLocation` | Preview spawn on map               |

#### Troubleshooting <a href="#izzy-multicharacterv5-configuration-troubleshooting" id="izzy-multicharacterv5-configuration-troubleshooting"></a>

| Issue                | Check                                                           |
| -------------------- | --------------------------------------------------------------- |
| Stuck on loading     | `manualShutdown`, NUI errors (F8), `oxmysql` connection         |
| No characters listed | Framework DB, ESX prefix, QB citizenid                          |
| Ped invisible        | `pedCoords`, skin load, appearance resource started             |
| Unlock code fails    | `tebexSecret`, `packageId`, code already in `transactions.json` |
| Spawn menu empty     | `cfg.locations`, housing resource, `useOwnSpawnSelector`        |
| Duplicate spawn      | Disable other multichar / spawn scripts                         |
| QB apartments error  | Remove `@qb-apartments/config.lua` from manifest if not used    |

**Debug:**

```lua
cfg.debug = true   -- in shared/cfg.lua (if supported in your build)
```


---

# 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 dynamically by asking a question.

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

```
GET https://izzyshop-1.gitbook.io/izzyshop-docs/multicharacter-resources/multicharacter-v5/configuration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
