Skip to the content
Docs

Character Selectors

On this page5
lua
Config.MulticharSystem = 'auto'

The selector is used for three small things:

  1. Sending a player back to the selector after a face implant — off by default (Config.Implant.ReturnToSelector).
  2. Knowing the selector is open, so our HUD stays hidden.
  3. The install note that makes character deletion clean up our data.

Every listed selector logs characters in through the framework, so the framework events cover all of them. If your selector is not listed, nothing breaks.

Support

SystemSupportAuto orderReturn to selector
17mov Character SystemSupported1framework logout
Quasar MulticharacterStub2framework logout
0R-Multicharacter v3Supported3framework logout
UM Multi CharacterSupported4framework logout
CodeM MulticharSupported5exports['codem-multicharacter']:Logout(src)
OP Multicharacter V2Stub6stub
ak47_multicharacterStub7stub
VMS MulticharsStub8stub
qb-multicharacterSupported9QBCore.Player.Logout(src) then its chooseChar event — the same as qb's own /logout.
esx_multicharacterSupported10TriggerEvent('esx:playerLogout', src).
qbx_core built-inSupported11exports.qbx_core:Logout(src). Used only when no external selector was found.

"Framework logout" means qb QBCore.Player.Logout(src), qbx exports.qbx_core:Logout(src), esx TriggerEvent('esx:playerLogout', src).

Character deletion — the one thing that needs setting up

When a character is deleted, our identity row should go with it. How that happens depends on the selector.

Qbox

Add one entry to qbx_core/config/server.lua:

lua
characterDataTables = {
    -- ... keep every existing entry ...
    {'recognition_identities', 'identifier'},
},

Only the identity row is listed. Memories, familiarity and introductions that point at a deleted identity are removed by our own prune job.

ESX

esx_multicharacter builds its clean-up list when it starts — every table with a VARCHAR column named identifier or owner. Our table has to exist by then.

Pick one:

  1. Recommended: import sql/install.sql once by hand before the next start. It is idempotent.
  2. Or ensure 5code-recognition before ensure esx_multicharacter (oxmysql and es_extended still first), then restart the server once after the very first start.

Check it: create a test character, delete it, confirm its row in recognition_identities is gone.

Our column is VARCHAR(64), longer than the 46 characters esx_multicharacter widens short columns to, so it is never altered. No other column of ours is named identifier or owner.

A new ESX character in a reused slot always starts clean — the framework reports isNew, and we act on it.

0R Multicharacter v3

Add our character-keyed tables to config/database.lua → Database.List, in each framework section you use, in the same entry format as the rows already there.

TableColumns
recognition_identitiesidentifier
recognition_memoriesobserver_key, target_key
recognition_familiarityobserver_key, target_key
recognition_introductionsobserver_key, target_key
recognition_devicesowner_key
recognition_reportsauthor_key, holder_key
recognition_death_sessionschar_key

On ESX this list is also used to re-number character slots after a delete (char3 becomes char2), which is why every column holding a character key has to be listed — not just the identity row.

Verify the folder name and the entry format against the version you actually run.

QBCore, UM, 17mov, CodeM, OP, ak47, VMS

Nothing to install.

These delete characters from a fixed list of tables and fire no event, so our own character prune job cleans up:

lua
ServerConfig.CharacterPrune = {
    Enabled = true,
    IntervalHours = 6,
    PageSize = 200,
    DeleteHints = true,
    DeleteHintDelaySeconds = 10,
}

With DeleteHints on, a delete the script notices is checked 10 seconds later instead of waiting for the next 6-hour run.

Per-selector notes

17mov Character System

Its Skin module replaces the appearance scripts unless Skin.Enabled = false. If you run it alongside illenium-appearance or similar, decide which one owns appearance and pin Config.AppearanceSystem accordingly — otherwise 'auto' may resolve to the one that is not actually driving the ped.

Quasar Multicharacter

Its documentation says useExternalCharacters = false on Qbox. Set it to true anyway, or Qbox keeps using its built-in selector and the delete list never sees Quasar's deletions.

0R Multicharacter v3

Re-indexes ESX character slots after a delete, which is why the install step lists every character-keyed column rather than just the identity.

OP Multicharacter V2

Exposes isPlayerInsideMulticharacter() on both sides, which is what we use to know the selector is open and keep our HUD hidden.

CodeM Multichar

Also registers qb-multicharacter:client:chooseChar, so a qb server running CodeM will look like both. We check CodeM first.

Returning to the selector after a face implant

Off by default:

lua
Config.Implant.ReturnToSelector = false

Where the selector has no supported way to reopen, the player simply stays in the world with their new face.

Custom selectors

Set Config.MulticharSystem = 'custom' and fill the 'custom' branch in bridge/framework_server.lua. Two functions: return the player to the selector, and say whether the selector is currently open.

See Writing a Custom Adapter.