-- From Server Side: TriggerClientEvent('0bug_Multicharacter:start', source)-- From Client Side:TriggerEvent('0bug_Multicharacter:start')
Important for ESX and QBox Users
For ESX Go to es_extended/shared/config/main.luaconfiguration and make sure you have these 2 options set to true'
Config.Multichar=trueConfig.Identity=true
For QBox Go to client -> config.lua and make sure you have this option set to true.
useExternalCharacters=true
Basic Settings
Customize= {DefaultCharSlot=10, -- Maximum character slots by defaultRules=true, -- Enable/disable rules acceptanceLang="en", -- Language setting (en, fr, es, etc.)}
Character Management
Character Creation Rules
Spawn System
Framework-Specific Settings
LoadHouse should be set to true if you use our Spawn Selector V2 and enabled spawning at your own house.
Starter Items
Load Character Custom Code
Custom Clothing Script
If you have a custom clothing script you need to follow this guide:
Open this Paths in your visual studio code
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 .
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
Scene Creation Mode
Translations
All translations are under the locales/en.lua file
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 threads.lua file in 0bug-core:
Open 0bug-core/threads.lua
Locate the GetFramework() function
Modify the export paths according to your framework:
Important Notes
Always backup your configuration before making changes
Restart the resource after modifying the config
Test changes in a development environment first
Make sure all coordinates are valid for your server
-- SERVER TRIGGER
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,
elseif WIZ_SCRIPT_CONFIG["Clothes"].Name == "your_clothing_script_name" then
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"
}
}
CreateSceneMode = false,
-- Scene locations and animations are configured in the Locations table
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",
}
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