# Configuration

{% hint style="info" %}
Multicharacter TriggerEvent : 0bug\_Multicharacter:start
{% endhint %}

```lua
-- From Server Side: 
TriggerClientEvent('0bug_Multicharacter:start', source)

-- From Client Side:
TriggerEvent('0bug_Multicharacter:start')
```

{% hint style="danger" %}
Important for ESX and QBox Users
{% endhint %}

For <mark style="color:blue;">**ESX**</mark> Go to <mark style="color:$primary;">**`es_extended/shared/config/main.lua`**</mark> configuration and make sure you have these 2 options set to <mark style="color:green;">true'</mark>

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

For <mark style="color:yellow;">**QBox**</mark> Go to client -> config.lua and make sure you have this option set to <mark style="color:green;">true</mark>.

```lua
useExternalCharacters = true
```

### Basic Settings

```lua
Customize = {
    DefaultCharSlot = 10,         -- Maximum character slots by default
    Rules = true,                 -- Enable/disable rules acceptance
    Lang = "en",                  -- Language setting (en, fr, es, etc.)
}
```

### Character Management

```lua
-- Character Slot Settings
Tebex_Buy_Slot_Enable = true,              -- Enable purchasing extra slots
Tebex_Buy_Slot_Command = "buySlot",        -- Command to buy slots

-- Discord Integration
Discord_Slot_Enable = false,                -- Enable discord-based slots
Discord_Slot_Roles = {
    ["ROLE_ID"] = 2,                       -- Extra slots per role
}

-- Character Deletion
Enable_Delete = true,                       -- Allow character deletion
Enable_Delete_By_Discord = false,           -- Enable Discord-based deletion
Discord_Delete_Roles = {
    ["ROLE_ID"] = true,                    -- Roles that can delete
}
```

### Character Creation Rules

```lua
MaxFirstNameLength = 18,
MaxLastNameLength = 11,
ForbiddenWords = {
        -- Profanity
        "fuck", "shit", "ass", "bitch", "bastard",
        
        -- Racial/Discriminatory
        "nigga", "nigger", "negro", "chink", "beaner",
        
        -- Sexual
        "sex", "cock", "dick", "penis", "pussy",
        
        -- Violence
        "kill", "murder", "rape", "terrorist",
        
        -- Game Terms
        "admin", "moderator", "mod", "staff", "owner",
        
        -- Misc Inappropriate
        "hitler", "nazi", "cocaine", "meth",
        
        -- Common Variants
        "fck", "fuk", "sht", "b1tch", "n1gga",
        
        -- Server Protection
        "console", "system", "server", "database",
        
        -- Placeholder Names
        "test", "player", "user", "character", "none",
        
        -- Numbers Only
        "123", "1234", "12345", "111", "000"
},
```

### Spawn System

```lua
SpawnSelector = "0bug_Spawnselector",    -- Options: qb-spawn, custom
Default_Spawn_Locations = {
    [1] = vector3(-1035.71, -2731.87, 12.86),
    [2] = vector3(-1035.71, -2731.87, 12.86)
}
```

<pre class="language-lua"><code class="lang-lua"><strong>-- SERVER TRIGGER
</strong>    SpawnSelectorTrigger = function(source, cData, FrameworkName, new)
        if Customize.SpawnSelector == "0bug_Spawnselector" then
            if new and Customize.Private[FrameworkName].Apartment ~= nil and Customize.Private[FrameworkName].Apartment then
                TriggerClientEvent('0bug_Spawnselector:OpenUI', source, cData.identifier, new)
            elseif new and
                (Customize.Private[FrameworkName].Apartment == nil or Customize.Private[FrameworkName].Apartment ==
                    false) then
                SpawnLocationsFormat = {}

                afterSpawnActionFunction = {
                    event = "createClothingMenu",
                    side = "client"
                }

                for k, v in pairs(Customize.Default_Spawn_Locations) do
                    table.insert(SpawnLocationsFormat, {
                        name = "Location",
                        adress = "Location",
                        coords = v,
                        type = "pin"
                    })
                end
                TriggerClientEvent('0bug_Spawnselector:CustomOpenUI', source, SpawnLocationsFormat,
                    afterSpawnActionFunction)
            else
                TriggerClientEvent('0bug_Spawnselector:OpenUI', source)
            end
        elseif Customize.SpawnSelector == "qb-spawn" then
            if Customize.Private[FrameworkName].Apartment == true and new == true then
                local randbucket = (GetPlayerPed(source) .. math.random(1, 999))
                SetPlayerRoutingBucket(source, randbucket)
                TriggerClientEvent('apartments:client:setupSpawnUI', source, cData, new)
            elseif Customize.Private[FrameworkName].Apartment == false and new == true then
                randomIndex = math.random(1, #Customize.Default_Spawn_Locations)
                SetEntityCoords(GetPlayerPed(source), Customize.Default_Spawn_Locations[randomIndex])
            else
                TriggerClientEvent('qb-spawn:client:setupSpawns', source, cData, false, nil)
                TriggerClientEvent('qb-spawn:client:openUI', source, true)
            end
        else
            if new then
                randomIndex = math.random(1, #Customize.Default_Spawn_Locations)
                SetEntityCoords(GetPlayerPed(source), Customize.Default_Spawn_Locations[randomIndex])
            else
                while ZeroBug.PlayerData == nil or ZeroBug.PlayerData.position == nil do
                    Wait(1)
                end
                SetEntityCoords(GetPlayerPed(source), ZeroBug.PlayerData.position.x, ZeroBug.PlayerData.position.y,
                    ZeroBug.PlayerData.position.z)
            end
        end
    end,
</code></pre>

### Framework-Specific Settings

{% hint style="info" %}
LoadHouse should be set to <mark style="color:green;">true</mark> if you use our <mark style="color:orange;">Spawn Selector V2</mark> and enabled spawning at your own house.&#x20;
{% endhint %}

```lua
Private = {
    ['QBCore'] = {
            RefreshCommand = true,
            Apartment = true,
            LoadHouse = false
        },
        ['QBox'] = {
            RefreshCommand = true,
            LoadHouse = false
        },
        ['ESX'] = {}
}
```

### Starter Items

```lua
StarterGiveItem = true,
StarterGiveItemList = {
        ['QBCore'] = {{
            amount = 1,
            item = 'phone'
        }, {
            amount = 1,
            item = 'id_card'
        }, {
            amount = 1,
            item = 'driver_license'
        }},
        ['QBox'] = {{
            amount = 1,
            item = 'phone'
        }, {
            amount = 1,
            item = 'id_card'
        }, {
            amount = 1,
            item = 'driver_license'
        }},
        ['ESX'] = {{
            item = "water",
            amount = 1
        }, {
            item = "burger",
            amount = 1
        }}
    },

```

### Load Character Custom Code&#x20;

```lua
LoadingCharacter = function(characterData)
-- SKIN CHANGER LOAD
    TriggerEvent("skinchanger:loadSkin", characterData.skin.skin)
end,
```

### Custom Clothing Script

{% hint style="warning" %}
If you have a custom clothing script you need to follow this guide:&#x20;
{% endhint %}

Open this Paths in your visual studio code&#x20;

* 0bug-core/client/Clothes
* 0bug-core/server/Clothes

Add in every part of the code an elseif condition for your custom script and add your exports and triggerevents then adapt them with the existing provided data in each function .

```lua
 elseif WIZ_SCRIPT_CONFIG["Clothes"].Name == "your_clothing_script_name" then
```

You can take example of how we did with multiple pre-configured clothing scripts in there to have a better look and idea with the help of your custom clothing script providers if you don't have enough coding knowledge.

### Music System

```lua
PlaySong = true, -- false if you don't want the music to start playing at UI display
MusicList = {
    {
        title = "Song Title",
        artist = "Artist Name",
        artwork = "artwork_url",
        url = "song_url",
        id = "1"
    }
}
```

### Scene Creation Mode

```lua
CreateSceneMode = false,
-- Scene locations and animations are configured in the Locations table
```

#### Translations&#x20;

All translations are under the locales/en.lua file&#x20;

```lua
Locales['en'] = {
  aboutCharacter = {
    frontTitle = "CHARACTER",
    backTitle = "ABOUT",
    infoName = "Name",
    infoGender = "Gender",
    infoBirthday = "Birthday",
    infoJob = "Job",
    infoCash = "Cash",
    infoBank = "Bank",
    playButton = "Play",
    deleteCharacter = "Delete Character",
  
    handleDeleteActionBox = {
        text = "Are you sure you want to delete your character?",
        actionButton = "YES, DELETE",
    },
  },
  
  actionBox = {
    actionBoxCancel = "CANCEL",
  },
  
  calendar = {
    daysOfWeek = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"},
    months = {
        "January",
        "February",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "November",
        "December",
    },
    selectDate = "Select Date",
  },
  
  characterBox = {
    lastPlay = {
        lastPlayed = "Last played",
        justNow = "just now",
        minute = "minute",
        hour = "hour",
        day = "day",
        ago = "ago",
    },
  },
  
  createCharacter = {
    frontTitle = "CHARACTER",
    backTitle = "REGISTER",
    firstName = "First Name",
    lastName = "Last Name",
    selectGender = "Select your gender",
    birthDay = "Birthday",
    male = "Male",
    female = "Female",
    nationalities = "Nationality",
    createButton = "CREATE",
    cancelButton = "CANCEL",
  },
  
  extraSlot = {
    titleOne = "Extra",
    titleTwo = "Slot",
    description = "Enter your Tebex transaction ID to verify your extra character slot purchase. Check your payment confirmation email or receipt for the ID.",
    inputPlaceholder = "Tebex Purchase ID here...",
    claimButton = "Claim Your Extra Slot",
  },
  
  favoriteCharacter = {
    frontTitle = "CHARACTER",
    backTitle = "FAVORITE",
  },
  
  music = {
    frontTitle = "PLAYER",
    backTitle = "MUSIC",
  },
  
  rules = {
    frontTitle = "RULES",
    backTitle = "RULES",
    signatur = "Signature",
    description = "Click on the box to sign so you can Continue",
    acceptButton = "ACCEPT",
    cancelButton = "CANCEL",
  },
  
  selectCharacter = {
    frontTitle = "CHARACTER",
    backTitle = "SELECT",
    notFound = "Not Found",
    description = "Here you can choose between your characters, or create a new one if necessary.",
  },
  
  settings = {
    title = "Settings",
    positioning = "Positioning",
    vertical = "Vertical Layout",
    horizontal = "Horizontal Layout",
    description = "Select an option to change the Multicharacter layout. It applies instantly; click 'Save' to confirm.",
    edit = "Edit",
    primaryColor = "Primary Color",
    primaryDescription = "Use the selector to change the primary color.",
    secondaryColor = "Secondary Color",
    secondaryDescription = "Use the selector to change the secondary color.",
    resetSettings = "Reset Settings",
    reset = "Reset",
    resetDescription = "Restore all settings to their default values.",
    cancelButton = "Cancel",
    saveButton = "Save",
  },
  
  errorMessage = {
    warning = "WARNING",
    success = "SUCCESS",
    info = "INFO",
    firstName = "Please enter a valid first name for your character.",
    lastName = "Please enter a valid last name for your character.",
    gender = "You need to select your character's gender.",
    birthday = "Please enter your character's date of birth.",
    nationality = "Please select your character's nationality.",
    firstNameForbidden = "The first name contains forbidden words. Please choose a different name.",
    lastNameForbidden = "The last name contains forbidden words. Please choose a different surname.",
  },

  progressBar = {
    text = "Final touches underway",
    text2 = "Just a sec",
  },

  logoutCommandDescription = "Logout of Character",
}

```

### Framework Configuration Guide

If you're using a different framework path/name (e.g., np-core instead of qb-core), you'll need to modify the <mark style="color:blue;">threads.lua</mark> file in <mark style="color:green;">0bug-core</mark>:

1. Open <mark style="color:orange;">0bug-core/threads.lua</mark>
2. Locate the <mark style="color:red;">GetFramework()</mark> function
3. Modify the export paths according to your framework:

```lua
function GetFramework()
    local Get = nil
    
    -- For ESX with custom path
    if WIZ_CONFIG.Framework == "ESX" then
        Get = exports['your-es-extended-path']:getSharedObject()
        if Get == nil then
            while Get == nil do
                TriggerEvent('esx:getSharedObject', function(Set) Get = Set end)
                Citizen.Wait(200)
            end
        end
    end
    
    -- For QBCore with custom path (e.g., bl-core)
    if WIZ_CONFIG.Framework == "QBCore" then
        Get = exports["your-qb-path"]:GetCoreObject()  -- Example: exports["bl-core"]:GetCoreObject()
        if Get == nil then
            while Get == nil do
                TriggerEvent('QBCore:GetObject', function(Set) Get = Set end)
                Citizen.Wait(200)
            end
        end
    end
    
    -- For QBox with custom path 
     if WIZ_CONFIG.Framework == "QBox" then
        Get = exports['your-qbox-path']:GetCoreObject()
        if Get == nil then
            while Get == nil do
                Get = exports['qb-core']:GetCoreObject()
                Citizen.Wait(200)
            end
        end
    end
    
    return Get
end
```

### Important Notes

1. Always backup your configuration before making changes
2. Restart the resource after modifying the config
3. Test changes in a development environment first
4. Make sure all coordinates are valid for your server


---

# 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://0bugscripts.gitbook.io/0bugscripts/infinity-scripts/multicharacter-v2/configuration.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.
