esx_multicharacter
esx_multicharacter gives ESX Legacy players multiple characters per account. Config, slot commands, database tables, events and fixes for common errors.
esx_multicharacter lets one FiveM account own several ESX characters. Players pick, create or delete a character on a selection screen before they spawn, and admins can grant extra slots or lock characters. ESX enables multicharacter mode automatically as soon as this resource is present on the server.
Overview
| Resource | esx_multicharacter |
| Version | 1.16.3 (fxmanifest, ships with ESX Legacy 1.16.4) |
| Side | Client + server, React NUI |
| Dependencies | es_extended, esx_context, esx_identity, esx_skin, esx_lib, oxmysql |
| Requirements | OneSync enabled (not off or legacy), server artifact 10188 or newer |
es_extended sets Config.Multichar = GetResourceState("esx_multicharacter") ~= "missing". You do not toggle multicharacter in the es_extended config; you add or remove this resource.
How characters are stored
Every character is a normal row in users. Its identifier is <Config.Prefix><slot>:<license>, for example char1:1a2b3c.... The player keeps one license; the prefix selects the character.
On start the resource migrates the database itself:
- adds
users.disabled(TINYINT(1), default0) used by/disablechar - creates the
multicharacter_slotstable (identifier,slots) - scans every table with an
identifierorownerVARCHARcolumn, widens it to fit the prefix and adds an index
The scanned tables are also the ones cleaned when a character is deleted, so you do not need to register your own tables for deletion as long as they use an identifier or owner column.
If the migration fails, the console prints [esx_multicharacter] 1.16.0 migration failed; character selection is disabled and players hang on a black screen. Check that your database user can run ALTER TABLE and CREATE INDEX.
Configuration
config.lua is shared, but some keys only exist on one side.
| Key | Side | Default | Description |
|---|---|---|---|
Config.Locale | Shared | GetConvar("esx:locale", "en") | UI language. |
Config.CanDelete | Shared | true | Allows players to delete their own characters. |
Config.Relog | Shared | true | Registers the /relog command. |
Config.Slots | Server | 3 | Default slot count for every player. The code falls back to 4 if you remove the key. |
Config.Prefix | Server | "char" | Identifier prefix. Keep it short; changing it on a live server orphans existing characters. |
Config.Spawn | Client | { { x = -284.2856, y = 562.4627, z = 172.9182, w = 19.9895 } } | List of camera positions for the selection scene. One is picked at random. |
Config.Default | Client | { m = {...}, f = {...} } | Default skinchanger appearance for new male and female characters. |
Config.Spawn is only the selection scene. The spawn point of a new character is the default value of the position column in the users table.
Commands
| Command | Permission | Arguments | Description |
|---|---|---|---|
/relog | everyone | none | Logs out the current character and returns to selection. Only when Config.Relog = true. Rate limited. |
/setslots | admin | identifier (string), slots (number) | Sets a custom slot count. |
/remslots | admin | identifier (string) | Removes the custom slot count, so the player falls back to Config.Slots. |
/enablechar | admin | identifier (string), charslot (number) | Re-enables a disabled character. |
/disablechar | admin | identifier (string), charslot (number) | Locks a character so it cannot be selected. |
The admin commands are allowed from the server console. The database change is applied, but the confirmation notification then throws a script error because there is no xPlayer, so prefer running them in game. identifier is the raw license (without char1:), for example:
/setslots 1a2b3c4d5e6f7a8b9c0d 5
/disablechar 1a2b3c4d5e6f7a8b9c0d 2The slot count is clamped between 1 and 100.
Events and callbacks
Server
| Name | Type | Description |
|---|---|---|
esx_multicharacter:SetupCharacters | Net event (client to server) | Loads the player's characters and sends esx_multicharacter:SetupUI. Rate limited to one request per 5 seconds. |
esx_multicharacter:CharacterChosen | Net event | (charid, isNew). Selects an existing slot or reserves an empty one for registration. |
esx_multicharacter:DeleteCharacter | Net event | (charid). Deletes a character if Config.CanDelete is on. |
esx_multicharacter:relog | Net event | Starts a relog. |
esx_multicharacter:chooseCharacter | xLib callback | Same as CharacterChosen, returns { success, error? }. |
esx_multicharacter:deleteCharacter | xLib callback | Returns { success, error? }. |
esx_multicharacter:relog | xLib callback | Returns { success, error? }. Used by /relog. |
The resource listens to esx_identity:completedRegistration to create the new character and then fires esx:onPlayerJoined with the charN prefix. For relog it triggers esx:playerLogout, which saves and unloads the xPlayer.
Possible error values: delete_disabled, invalid_character, busy, rate_limited, stale_session, database_error, refresh_failed, already_loaded, disabled, not_loaded.
Client
| Name | Description |
|---|---|
esx_multicharacter:SetupUI | Secure net event from the server with (characters, slots). Opens the selection UI. |
esx:onPlayerLogout | Fades out and reopens the selection after a relog. |
Reacting to a character switch
Use the ESX events instead of multicharacter internals. They fire for both first spawn and relog:
RegisterNetEvent('esx:playerLoaded', function(xPlayer, isNew, skin)
ESX.PlayerData = xPlayer
-- build blips, jobs, UI for the selected character
end)
RegisterNetEvent('esx:onPlayerLogout', function()
-- clean up anything tied to the previous character
end)Common issues
- "ESX Requires Onesync Infinity to work". Add
set onesync ontoserver.cfg. - "Cannot Find the servers mysql_connection_string". The resource parses the database name from
mysql_connection_string. Use themysql://user:pass@host/databaseordatabase=...;form. - "identifier-active" when joining. Another connected player (or a stale session) uses the same license. The resource cleans stale entries automatically if the old player no longer has a ping. With
EnableDebugon in es_extended, the duplicate check is skipped for testing. - Black screen after selecting a character. Usually a failed schema migration or a resource that errors in
esx:playerLoaded. Check the server console. - Players see the default slot count after
/setslots. Make sure you passed the license without thechar1:prefix.
Related
Frequently asked questions
Independent documentation
Last updated on
esx_menu_list
esx_menu_list reference for ESX Legacy. Show table menus with clickable row buttons via ESX.UI.Menu.Open('list'), the head/rows format, callbacks and pitfalls.
esx_notify
esx_notify reference for ESX Legacy. Show NUI notifications with ESX.ShowNotification, the Notify export or server events, plus types, positions and config.