# QBCore Setup

### ✅ Requirements

* QBCore (latest version)
* ox\_lib
* oxmysql
* A compatible inventory
* A compatible clothing script

***

### 🚀 Quick Setup

#### Step 1: Disable Default Multicharacter

If you have `qb-multicharacter` installed:

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

#### Step 2: Configure QBCore

Edit `qb-core/config.lua`:

```lua
QBShared.DefaultSpawn = false  -- Let multicharacter handle spawning
```

#### Step 3: Start Order

```cfg
ensure oxmysql
ensure ox_lib
ensure qb-core
ensure ox_inventory  # or your inventory
ensure bl_appearance # or your clothing
ensure 0r-multicharacterv3
```

***

### 🗄️ Database

QBCore uses the `players` table for character storage. The script reads:

| Column    | Usage                        |
| --------- | ---------------------------- |
| citizenid | Unique character identifier  |
| cid       | Character slot number        |
| license   | Player identifier            |
| charinfo  | Character information (JSON) |
| job       | Job data (JSON)              |
| money     | Money data (JSON)            |
| position  | Last position (JSON)         |

***

### 🔧 Character Data Format

The script converts QBCore data to a standardized format:

```lua
{
    cid = 1,
    citizenid = 'ABC12345',
    charinfo = {
        firstname = 'John',
        lastname = 'Doe',
        birthdate = '1990-01-15',
        gender = 0,
        nationality = 'American',
    },
    job = {
        name = 'unemployed',
        label = 'Unemployed',
        grade = { name = 'Freelancer' }
    },
    money = {
        cash = 500,
        bank = 5000,
    },
    position = {
        x = 0.0,
        y = 0.0,
        z = 0.0,
        w = 0.0,
    }
}
```

***

### 🏠 Housing Integration

#### qb-houses

The script automatically loads house data:

```lua
-- server/functions.lua
function LoadHouseData(source)
    -- Loads from houselocations table
    -- Triggers qb-garages:client:houseGarageConfig
    -- Triggers qb-houses:client:setHouseConfig
end
```

#### qb-apartments

Configure in `config/apartments.lua`:

```lua
Apartments.SpawnCreateCharacter = function(apartmentType)
    TriggerServerEvent('apartments:server:CreateApartment', apartmentType)
    TriggerServerEvent('0r-multicharacterv3:server:changeRoutingBucket', true)
end
```

***

### ⚡ Events

#### Server Events

```lua
-- When player loads character
AddEventHandler('QBCore:Server:PlayerLoaded', function(Player)
    -- Triggered after character selection
end)

-- When player unloads
AddEventHandler('QBCore:Server:OnPlayerUnload', function(src)
    -- Cleanup
end)
```

#### Client Events

```lua
-- After spawning
TriggerEvent('QBCore:Client:OnPlayerLoaded')
TriggerServerEvent('QBCore:Server:OnPlayerLoaded')
```

***

### 🔄 Character Deletion

Configure tables to clean up in `config/database.lua`:

```lua
Database.List = {
    ['qb-core'] = {
        { table = 'players', column = 'citizenid', type = 'citizenid' },
        { table = 'playerskins', column = 'citizenid', type = 'citizenid' },
        { table = 'player_vehicles', column = 'citizenid', type = 'citizenid' },
        { table = 'player_houses', column = 'citizenid', type = 'citizenid' },
        { table = 'player_gangs', column = 'citizenid', type = 'citizenid' },
        { table = 'player_contacts', column = 'citizenid', type = 'citizenid' },
        { table = 'player_mails', column = 'citizenid', type = 'citizenid' },
        { table = 'bank_accounts', column = 'citizenid', type = 'citizenid' },
    }
}
```

***

### ❓ Troubleshooting

#### "Player already loaded" error

This usually means qb-core is trying to load the player before multicharacter:

1. Ensure `QBShared.DefaultSpawn = false`
2. Check start order in server.cfg

#### Characters not saving

1. Check oxmysql connection
2. Verify `players` table exists
3. Check server console for SQL errors

#### Clothing not loading

1. Verify clothing script is started
2. Check `playerskins` table has data
3. Ensure `citizenid` matches

#### Spawn issues

1. Disable `basic-gamemode`
2. Check spawn selector configuration
3. Verify position data in database
