# ESX Setup

### ✅ Requirements

* ESX Legacy (1.9.0+) or ESX Infinity
* ox\_lib
* oxmysql
* A compatible inventory
* A compatible clothing script (skinchanger or alternatives)

***

### 🚀 Quick Setup

#### Step 1: Enable Multicharacter in ESX

Edit `es_extended/config.lua`:

```lua
Config.Multichar = true  -- Enable multicharacter support
```

#### Step 2: Disable Default Multicharacter

```cfg
# server.cfg
# ensure esx_multicharacter  <-- Comment out or remove
ensure 0r-multicharacterv3
```

#### Step 3: Start Order

```cfg
ensure oxmysql
ensure ox_lib
ensure es_extended
ensure ox_inventory  # or qs-inventory
ensure skinchanger   # or bl_appearance
ensure 0r-multicharacterv3
```

***

### 🗄️ Database

ESX uses the `users` table for character storage:

| Column      | Usage                                               |
| ----------- | --------------------------------------------------- |
| identifier  | Character identifier (char1:license, char2:license) |
| firstname   | First name                                          |
| lastname    | Last name                                           |
| dateofbirth | Birth date                                          |
| sex         | Gender (m/f)                                        |
| job         | Job name                                            |
| job\_grade  | Job grade                                           |
| accounts    | Money accounts (JSON)                               |
| position    | Last position (JSON)                                |
| skin        | Appearance data (JSON)                              |

***

### 🔧 Character Identifier Format

ESX multicharacter uses a specific identifier format:

```
char{number}:{license}
```

Examples:

* `char1:abc123def456` - First character
* `char2:abc123def456` - Second character
* `char3:abc123def456` - Third character

Configure the prefix in `config/config.lua`:

```lua
Config.Prefix = 'char'  -- Creates char1:, char2:, etc.
```

***

### 📊 Data Conversion

The script converts ESX data to a standardized format:

```lua
-- ESX format
{
    identifier = 'char1:license123',
    firstname = 'John',
    lastname = 'Doe',
    dateofbirth = '1990-01-15',
    sex = 'm',
    job = 'unemployed',
    job_grade = 0,
    accounts = '{"money":500,"bank":5000}',
    position = '{"x":0,"y":0,"z":0}',
}

-- Converted format
{
    cid = 1,
    citizenid = 'char1:license123',
    charinfo = {
        firstname = 'John',
        lastname = 'Doe',
        birthdate = '1990-01-15',
        gender = 'm',
        nationality = 'N/A',
    },
    job = {
        name = 'Unemployed',
        label = 'Unemployed',
        grade = { name = 'Unemployed' }
    },
    money = {
        cash = 500,
        bank = 5000,
    },
    position = {
        x = 0.0,
        y = 0.0,
        z = 0.0,
        w = 0.0,
    }
}
```

***

### ⚡ Events

#### Server Events

```lua
-- When player loads character
RegisterNetEvent('esx:playerLoaded', function(player, xPlayer, isNew)
    -- Triggered after character selection
end)

-- When player disconnects
RegisterNetEvent('esx:playerDropped', function(playerId, reason)
    -- Cleanup
end)
```

#### Client Events

```lua
-- After spawning
TriggerServerEvent('esx:onPlayerSpawn')
TriggerEvent('esx:onPlayerSpawn')
TriggerEvent('playerSpawned')
TriggerEvent('esx:restoreLoadout')
```

***

### 🔄 Character Deletion & Reindexing

When a character is deleted, remaining characters are reindexed:

```lua
-- Before deletion: char1, char2, char3
-- Delete char2
-- After reindex: char1, char2 (was char3)
```

Configure tables in `config/database.lua`:

```lua
Database.List = {
    ['es_extended'] = {
        { table = 'users', column = 'identifier', type = 'citizenid' },
        { table = 'user_accounts', column = 'identifier', type = 'citizenid' },
        { table = 'user_inventory', column = 'identifier', type = 'citizenid' },
        { table = 'owned_vehicles', column = 'owner', type = 'citizenid' },
        { table = 'user_licenses', column = 'owner', type = 'citizenid' },
        -- Add more tables as needed
    }
}
```

***

### 📋 Complete Configuration

```lua
-- config/config.lua for ESX

Config.Debug = false
Config.DeveloperMode = false
Config.Locale = 'en'
Config.HideRadar = true
Config.Prefix = 'char'  -- ESX character prefix
Config.DefaultCharacterSlots = 2
Config.SkipWarning = false
Config.DisableDeleteCharacter = false

-- Spawn configuration
Config.SkipSpawnSelector = true
Config.SpawnSelector = '0r-spawn'
Config.ApartmentStart = false
Config.NewPlayerSpawnCoords = vec4(195.17, -933.77, 29.7, 144.5)
```

***

### 🆚 ESX vs QBCore Differences

| Feature       | ESX           | QBCore      |
| ------------- | ------------- | ----------- |
| Identifier    | char1:license | citizenid   |
| Gender        | m/f           | 0/1         |
| Money Storage | JSON accounts | JSON money  |
| Skin Storage  | users.skin    | playerskins |
| Player Object | xPlayer       | Player      |

***

### ❓ Troubleshooting

#### "Multichar not enabled" error

Ensure in `es_extended/config.lua`:

```lua
Config.Multichar = true
```

#### Skin not loading

1. Check `users.skin` column has data
2. Verify skinchanger is started
3. Ensure skin format is correct

#### Character reindex issues

If characters are out of order after deletion:

```sql
-- Manual reindex query
UPDATE users 
SET identifier = CONCAT('char', @row := @row + 1, ':', SUBSTRING_INDEX(identifier, ':', -1))
WHERE identifier LIKE 'char%:your-license-here'
ORDER BY identifier;
```

#### Job not showing correctly

The script reads job labels from ESX's job system. Ensure jobs are properly configured in your database.


---

# 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://docs.0resmon.org/0resmon/0resmon-1/0r-resources/0r-multicharacter-v3/frameworks/esx-setup.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.
