API, hooks and bridges
Multicharacter server and client exports, commands, client and server hooks, and the functions to write to plug in another framework or appearance system.
Server exports
exports.mrpoulpi_multicharacter:Logout(source) Logs the loaded character out (saved by the framework, OnLogout hook) and reopens the selection for that player. Returns false if the resource is starting, if an action is running for that player or if no character is loaded. Works even with Features.Relog = false.
Returnsboolean
exports.mrpoulpi_multicharacter:AddSlots(sourceOrLicense, amount) Adds amount bonus slots in the database. sourceOrLicense: server ID of a connected player, or Rockstar licence (license:xxx or xxx alone). A negative amount removes some. The bonus is bounded from 0 to 255.
Returnsnew bonus (number) or false
exports.mrpoulpi_multicharacter:SetSlots(sourceOrLicense, amount) Sets the database bonus to amount (0 removes every bonus). Does not affect Slots.Default, ACE bonuses or per-identifier totals.
Returnsnew bonus (number) or false
exports.mrpoulpi_multicharacter:GetSlots(source) Number of unlocked slots of a connected player: Slots.Default + ACE bonuses + database bonus, at least the Slots.Identifiers total, at most Config.Slots.Max.
Returnsnumber
Client exports
exports.mrpoulpi_multicharacter:IsOpen() true while the selection screen is displayed. Useful to hide a HUD or block a menu during selection.
Returnsboolean
Commands
| Command | Usable | Effect |
|---|---|---|
/relog | in game, every player | Back to character selection. Name set by Config.Features.RelogCommand, disabled by Config.Features.Relog. |
multichar_slots <id | license:xxx> <amount> [set] | server console only | Adds <amount> bonus slots to the player (or removes some with a negative amount). With set, sets the bonus to <amount>. Name set by ServerConfig.Slots.Command. |
Example: switching character from a menu
/relog is open to everyone. To add your own conditions (not cuffed, not in a fight…), disable the command with Config.Features.Relog = false and call the export:
RegisterNetEvent('my_menu:switchCharacter', function()
local src = source
if Player(src).state.isCuffed then
return
end
exports.mrpoulpi_multicharacter:Logout(src)
end)
The character is saved by the framework, as on a normal disconnection.
Server hooks
In config/server.lua:
| Hook | Called | Error in the hook |
|---|---|---|
ServerHooks.OnCharacterCreated(source, charId, identity) | After the character is created and loaded. identity holds firstname, lastname, birthdate (YYYY-MM-DD), sex (m or f), nationality and height. | Caught and printed in the console; the script continues. |
ServerHooks.OnCharacterLoaded(source, charId) | After an existing character is loaded (Play or Appearance button). | Caught and printed in the console; the script continues. |
ServerHooks.OnCharacterDeleted(source, charId) | After a character is deleted, once its data is erased. | Caught and printed in the console; the script continues. |
ServerHooks.OnLogout(source, charId) | After /relog or the Logout export, before the selection reopens. charId may be nil if the session was not tracked. | Caught and printed in the console; the script continues. |
function ServerHooks.OnCharacterCreated(source, charId, identity)
print(('%s created %s %s'):format(GetPlayerName(source), identity.firstname, identity.lastname))
end
Client hooks
In config/client.lua:
| Hook | Called | Error in the hook |
|---|---|---|
ClientHooks.OnSelectionOpen() | When the selection opens, before the scene is set up. Shipped: pauses qb-weathersync and cd_easytime weather sync. | Not caught: it stops what follows (opening, closing or end of creation). |
ClientHooks.OnSelectionClose() | When the selection closes, before spawning. Shipped: restores weather sync. | Not caught: it stops what follows (opening, closing or end of creation). |
ClientHooks.OnSpawned(isNew) | After spawning and the fade-in. isNew is true for a newly created character (before the appearance editor opens). | Caught and printed in the console; the script continues. |
ClientHooks.OnCreatorFinished() | When the player has confirmed the appearance editor of a new character. Not called for the Appearance button of an existing character. | Not caught: it stops what follows (opening, closing or end of creation). |
Limits
The same action repeated too fast is refused with “Please wait a moment”: 1 s to open the list, 1.5 s to play, 2 s to create, delete or save the appearance. Only one action at a time is processed per player.
Bridges
A bridge links the resource to a framework or an appearance system. Each bridge declares a name, a priority and a detection function:
local Framework = { Name = 'custom', Priority = 0 }
Bridge.Framework.custom = Framework
function Framework.Detect()
return false
end
Framework, server side
| Function | Returns | Role |
|---|---|---|
Init() |
— | Get the framework object. |
CheckSetup() |
nil or a text key |
Optional. Reports a wrong installation. |
GetIdentifier(source) |
string | Identifier owning the characters. |
GetCharacters(source, owner) |
table | List of characters (format below). |
CreateCharacter(source, owner, slot, identity) |
string or nil |
Create and load the character, return its identifier. |
LoadCharacter(source, owner, charId) |
boolean | Load an existing character. |
IsLoaded(source) |
boolean | Does the player have a loaded character? |
GetCharId(source) |
string or nil |
Identifier of the loaded character. |
Logout(source) |
— | Save and unload the character. |
DeleteCharacter(source, owner, charId) |
boolean | Delete the character and its data. |
SaveSkin(source, model, skin) |
boolean | Save the appearance. |
Each character returned by GetCharacters holds: id, slot, firstname, lastname, birthdate (YYYY-MM-DD), sex (m or f), job ({ name, label, grade }), cash, bank, position ({ x, y, z, w }), model and skin. nationality and height are optional.
CreateCharacter receives identity with firstname, lastname, birthdate, sex, nationality and height, already checked.
Framework, client side
| Function | Returns | Role |
|---|---|---|
Init() |
— | Get the framework object. |
WaitLoaded(timeout) |
boolean | Wait until the client has received the character data. |
OnSpawned(isNew) |
— | Fire the framework’s spawn events. |
Appearance
| Function | Returns | Role |
|---|---|---|
Apply(model, skin, sex) |
boolean | Apply a saved appearance. false shows the default ped. |
Create(sex, done) |
— | Open the editor at creation; call done(true) once saved. |
Edit(done) |
— | Open the editor for an existing character. |
To save the appearance, call Callback('saveSkin', 15000, model, skin) from the bridge.