> For the complete documentation index, see [llms.txt](https://prfortiq.gitbook.io/wolfstudio/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://prfortiq.gitbook.io/wolfstudio/fivem/ws-advanced-skinchar-system.md).

# WS Advanced Skinchar System

<figure><img src="/files/6KCNpgXIstgxcL5VSZrw" alt=""><figcaption></figcaption></figure>

A modern **character creator** and **clothing shop** with a custom UI.\
Compatible with **QBCore** and **ESX**.

{% hint style="info" %}
**QBox support will follow in a later update.** The scripts are currently shipped and officially supported for QBCore and ESX. As soon as the QBox version is ready, it will be provided free of charge as an update.
{% endhint %}

## Features

* Full character creator (face, parents, hair, eyes, beard, make-up, body, clothing, accessories)
* Separate modes: creator, clothing shop, barber, tattoo
* Live preview with a rotatable camera and multiple views
* Randomize, reset, save & confirm
* Multilingual (English / German) via `Config.Locale`

## Requirements

| Dependency                       |  Required  | Purpose                |
| -------------------------------- | :--------: | ---------------------- |
| `oxmysql`                        |      ✅     | Database / skin backup |
| `qb-core` **or** `es_extended`   |      ✅     | Framework              |
| `qb-clothing` (QBCore)           | ✅ (QBCore) | Save/load the skin     |
| `esx_skin` + `skinchanger` (ESX) |   ✅ (ESX)  | Save/load the skin     |

## Commands

| Command     | Function                                         |
| ----------- | ------------------------------------------------ |
| `/skinchar` | Full character creator                           |
| `/clothing` | Clothing shop mode (clothing, hair, accessories) |

The command names are freely adjustable via `Config.Command` and `Config.ClothingCommand` (see Configuration).

## Installation – QBCore

{% stepper %}
{% step %}

### Add the resource

Copy the `ws-skinchar` folder into your `resources` folder (e.g. into `[ws]` or `[custom]`).
{% endstep %}

{% step %}

### server.cfg

```cfg
ensure oxmysql
ensure qb-core
ensure qb-clothing
ensure ws-skinchar
```

{% endstep %}

{% step %}

### Framework setting

In `config.lua`:

```lua
Config.Framework = 'auto' -- auto, qb, esx
```

* `'auto'` detects QBCore automatically (`qb-core`).
* Or set it explicitly to `'qb'`.
  {% endstep %}

{% step %}

### Redirect qb-clothing to ws-skinchar

Open `qb-clothing/client.lua` and adjust the `openMenu` function. Add the redirect to ws-skinchar at the beginning of the function:

{% code title="qb-clothing/client.lua" %}

```lua
local function openMenu(allowedMenus)
    if GetResourceState("ws-skinchar") == "started" then
        if allowedMenus[1].menu == 'character' then
            TriggerEvent('ws-skinchar:client:openCreator')
            return
        elseif allowedMenus[1].menu == 'clothing' then
            TriggerEvent('ws-skinchar:client:openClothing')
            return
        elseif allowedMenus[1].menu == 'hair' then
            TriggerEvent('ws-skinchar:client:openBarber')
            return
        end
    end

    -- ... the original openMenu code continues here ...
end
```

{% endcode %}

{% hint style="info" %}
ws-skinchar also reacts automatically to the event `qb-clothes:client:CreateFirstCharacter` and opens the creator during initial character creation.
{% endhint %}
{% endstep %}

{% step %}

### Database

On first start ws-skinchar creates the backup table `ws_skinchar_skins` automatically. The actual skin is additionally saved through qb-clothing.
{% endstep %}
{% endstepper %}

## Installation – ESX

{% stepper %}
{% step %}

### Add the resource

Copy the `ws-skinchar` folder into your `resources` folder.
{% endstep %}

{% step %}

### server.cfg

```cfg
ensure oxmysql
ensure es_extended
ensure skinchanger
ensure esx_skin
ensure ws-skinchar
```

{% endstep %}

{% step %}

### Framework setting

In `config.lua`:

```lua
Config.Framework = 'auto' -- auto, qb, esx
```

* `'auto'` detects ESX automatically (`es_extended`).
* Or set it explicitly to `'esx'`.
  {% endstep %}

{% step %}

### Switch dependencies (esx\_skin → ws-skinchar)

In the following resources, replace the dependency on `esx_skin` with `ws-skinchar` or `ws_skinchar`:

{% code title="esx\_multicharacter/fxmanifest.lua" %}

```lua
dependencies { 'es_extended', 'esx_context', 'esx_identity', 'ws-skinchar' }
-- before: ... 'es-skin' / 'esx_skin'
```

{% endcode %}

{% code title="esx\_accessories/fxmanifest.lua" %}

```lua
dependencies { 'es_extended', 'ws-skinchar', 'esx_datastore' }
-- before: ... 'esx_skin' ...
```

{% endcode %}

{% code title="esx\_clothingshop/fxmanifest.lua" %}

```lua
dependencies { 'es_extended', 'ws-skinchar' }
-- before: ... 'esx_skin'
```

{% endcode %}

{% code title="esx\_barberjob/fxmanifest.lua" %}

```lua
dependencies { 'es_extended', 'ws_skinchar' }
-- before: ... 'esx_skin'
```

{% endcode %}
{% endstep %}

{% step %}

### Redirect esx\_skin to ws-skinchar

Open `esx_skin/client/main.lua` and replace the `esx_skin:open...` events so they open ws-skinchar. Add a status variable at the top and replace the menu calls:

{% code title="esx\_skin/client/main.lua" %}

```lua
local isSkincharOpen = false

AddEventHandler('ws-skinchar:client:onMenuClose', function()
    isSkincharOpen = false
end)

RegisterNetEvent("esx_skin:openMenu", function(submitCb, cancelCb)
    isSkincharOpen = true
    TriggerEvent('ws-skinchar:client:openClothing')
    CreateThread(function()
        while isSkincharOpen do Wait(100) end
        if submitCb then submitCb({}, { close = function() end }) end
    end)
end)

RegisterNetEvent("esx_skin:openSaveableMenu", function(submitCb, cancelCb)
    isSkincharOpen = true
    TriggerEvent('ws-skinchar:client:openCreator')
    CreateThread(function()
        while isSkincharOpen do Wait(100) end
        if submitCb then submitCb({}, { close = function() end }) end
    end)
end)
```

{% endcode %}

{% hint style="info" %}
The same pattern applies to the remaining events (`esx_skin:openRestrictedMenu`, `esx_skin:openSaveableRestrictedMenu`): for hair/beard/make-up restrictions trigger `ws-skinchar:client:openBarber`, otherwise `ws-skinchar:client:openClothing`.
{% endhint %}
{% endstep %}

{% step %}

### Remove the automatic menu call

In `esx_skin/client/main.lua`, find the event `esx_skin:playerRegistered` (around line 62) and remove the automatic `Menu:Saveable()` call there, since `esx_multicharacter` handles the menu:

```lua
if skin == nil then
    exports["skinchanger"]:LoadSkin({ sex = 0 })
    -- Menu:Saveable()  -- remove / comment out this line
else
```

{% endstep %}

{% step %}

### Database

On first start ws-skinchar creates the backup table `ws_skinchar_skins` automatically. The actual skin is additionally saved through ESX (`users.skin`).
{% endstep %}
{% endstepper %}

## Configuration

All settings are located in `config.lua`.

### General settings

```lua
Config.Framework      = 'auto'      -- auto, qb, esx
Config.Locale         = 'de'        -- Language: 'de' or 'en'
Config.Command        = 'skinchar'  -- Command for the character creator
Config.ClothingCommand = 'clothing' -- Command for the clothing shop
Config.SaveOnConfirm  = true        -- Save the skin automatically on confirm
Config.Price          = 0           -- Price (0 = free)
```

| Setting                  | Description                                                     |
| ------------------------ | --------------------------------------------------------------- |
| `Config.Framework`       | Framework selection. `'auto'` detects QBCore/ESX automatically. |
| `Config.Locale`          | UI language (`locales/de.lua` or `locales/en.lua`).             |
| `Config.Command`         | Command to open the full creator.                               |
| `Config.ClothingCommand` | Command to open the clothing mode.                              |
| `Config.SaveOnConfirm`   | If `true`, saves automatically on confirm.                      |
| `Config.Price`           | Cost of use (0 = free).                                         |

### Camera

```lua
Config.Camera = {
    distance = 2.2,   -- Distance to the character
    height   = 0.55,  -- Camera height
    fov      = 35.0   -- Field of view
}
```

### Modes & categories

The category lists define which sections are shown in each mode:

```lua
-- Full character creator (/skinchar)
Config.CreatorCategories = {
    'face', 'parents', 'hair', 'eyes', 'beard',
    'makeup', 'body', 'clothing', 'accessories'
}

-- Clothing shop (/clothing)
Config.ClothingCategories = { 'clothing', 'accessories' }

-- Barber
Config.BarberCategories = { 'hair', 'eyes', 'beard', 'makeup' }

-- Tattoo
Config.TattooCategories = { 'makeup', 'body' }
```

Available categories: `face`, `parents`, `hair`, `eyes`, `beard`, `makeup`, `body`, `clothing`, `accessories`.

### Shop restrictions

`Config.ShopRestricted` controls which components can be edited in the clothing shop – separated by framework (`qb` / `esx`). Only the components listed there may be changed in shop mode.

```lua
Config.ShopRestricted = {
    qb  = { 'hair', 't-shirt', 'torso2', 'pants', 'shoes', ... },
    esx = { 'hair_1', 'hair_2', 'tshirt_1', 'torso_1', ... }
}
```

### Adjusting the language

You can edit custom text or add more languages in the files under `locales/` (e.g. `de.lua`, `en.lua`). After changes: `restart ws-skinchar`.

## Important Notice

{% hint style="danger" %}
**Info**

Our scripts are available exclusively on tebex. All other third-party providers are considered leaks and therefore violate our terms of use and intellectual property rights.

If you discover that our scripts are found on third-party websites such as vag.gg, Launcher-Leaks, or other shopping systems that have nothing to do with fivem and cfx.re, please report them urgently via Discord. The third-party provider will face appropriate consequences.

It is also not permitted to download, purchase, upload, sell, or use third-party scripts. This can have consequences for both users and server owners.

If our scripts contain errors or you need help, you can also report them via our Discord.
{% endhint %}
