SleepyCode
Home
AboutBlogSubscriptionDocs
Cart0
SleepyCode
Cart0
  • πŸ’£Documentation

Scripts

  • Multicharacter
    • Features
    • Installation
    • Framework Setup
    • Core Settings
    • Characters and Slots
    • Identity
    • Spawn Selector
    • Camera and Scene
    • Arrival and Welcome
    • Starting Items
    • Loading Screen
    • Discord
    • Logs
    • Theme and Branding
    • Translations
    • Commands and Permissions
    • Database
    • Integrations
    • Hooks
    • Exports and Events
    • Examples
    • Security
    • Troubleshooting
  • DevTool
  • Fishing
  • πŸ—ƒοΈGarages V2
  • 🚌Bus Job
  • πŸš—Vehicle Shop V1
  • πŸ—ƒοΈGarages V1
  • 🍁Selldrugs
  • πŸŽ…Advent Calendar
  1. Docs
  2. /Multicharacter
  3. /Hooks

Multicharacter

Hooks

Editable server and client hooks for adding your own code to the escrow protected resource.

On this page5 sections
  • Your code cannot break loading
  • Hooks or exports
  • Call order
  • Server hooks
  • Client hooks

The resource code is encrypted, but your server often needs its own logic at a specific moment: starting items, a phone number, a jail spawn, or pausing the anticheat while loading.

Two open files are for that:

FileUse for
bridge/server/editable.luaStarting items, character create and delete, custom spawn and bucket, select veto
bridge/client/editable.luaAnticheat, HUD, anything that depends on the player's stage

Implement a hook by filling the function already in the file:

Lua
function SC.Editable.GiveStartingItems(src, citizenid)    exports.ox_inventory:AddItem(src, 'phone', 1)end

Your code cannot break loadingLink copied

  • Every hook has a safe default in the encrypted part, so a deleted function still exists.
  • Every call is wrapped in pcall. An error is printed with the hook name, and the character still spawns.
Text
[sc_multicharacter] error in editable hook "GiveStartingItems": ...

Hooks or exportsLink copied

You write code...Use
in this resource, in the editable filesHooks on this page
in another resource that reacts to this oneExports and Events

Call orderLink copied

Text
Player creates a character  OnCharacterCreated(src, character, isFirst)  OnStartingItemsPicked(src, citizenid, lines, total)Player selects a character  CanSelectCharacter(src, character)  ResolveSpawn(src, character, spawnKey)  OnCharacterLoaded(src, character)  ResolveBucket(src, character)  GiveStartingItems(src, citizenid)  OnStartingItemsGranted(src, citizenid, lines, total)Player gets control  OnPlayerSpawned(character)                clientRelog or disconnect  OnCharacterLogout(src, citizenid)Character deleted  OnCharacterDeleted(src, citizenid)Stage changes, all the time  OnStateChanged(state)                     client  OnSelectOpened()                          client

Server hooksLink copied

File: bridge/server/editable.lua.

HookWhenReturns
OnCharacterCreated(src, character, isFirst)The character row exists in the databasenothing
OnStartingItemsPicked(src, citizenid, lines, total)The player paid for the starter basketnothing
GiveStartingItems(src, citizenid)The selected character's inventory existsnothing
OnStartingItemsGranted(src, citizenid, lines, total)The basket was grantednothing
OnCharacterDeleted(src, citizenid)The character was deletednothing
OnCharacterLoaded(src, character)Selected and handed to the frameworknothing
OnCharacterLogout(src, citizenid)Relog or disconnectnothing
ResolveSpawn(src, character, spawnKey)Before the spawn point is resolvedvector4, table, or nil
ResolveBucket(src, character)When leaving the private worldbucket id or nil
CanSelectCharacter(src, character)Before the character loadsboolean, reason

OnCharacterCreated

Lua
function SC.Editable.OnCharacterCreated(src, character, isFirst)end

The new character row exists, but the character has nothing yet: no items, phone number, or licenses.

  • character has citizenid, firstname, lastname, gender, dateofbirth, nationality, and height.
  • isFirst is true only for the player's first character.

Do not grant items here. The character is not selected yet, so it has no inventory.

Use GiveStartingItems for items. This hook is for rows in your own tables.

GiveStartingItems

Lua
function SC.Editable.GiveStartingItems(src, citizenid)end

Runs when the selected character's inventory exists, on every login, not only the first. To grant items once, track it yourself. See Examples.

OnStartingItemsPicked

Lua
function SC.Editable.OnStartingItemsPicked(src, citizenid, lines, total)end

The basket at payment time, before the appearance editor and arrival. The character has no session or inventory yet. Use it for logs, webhooks, or saving the choice in your own table.

OnStartingItemsGranted

Lua
function SC.Editable.OnStartingItemsGranted(src, citizenid, lines, total)end

The basket at grant time. Normal items are already in the inventory. Anything with a kind other than 'item', such as 'vehicle', was not granted and waits here for your code. Runs once per basket, a relog does not run it again.

lines is a list of:

Lua
{ key = 'car', item = 'blista', kind = 'vehicle', count = 1, price = 2000 }

total is the total cost from the budget.

OnCharacterDeleted

Lua
function SC.Editable.OnCharacterDeleted(src, citizenid)end

The character was deleted. The only moment to clean up records in your tables, such as phone, vehicles, or properties.

OnCharacterLoaded

Lua
function SC.Editable.OnCharacterLoaded(src, character)end

The character was selected and handed to the framework. The player is still watching the camera flight.

OnCharacterLogout

Lua
function SC.Editable.OnCharacterLogout(src, citizenid)end

The character was released by a relog or disconnect.

ResolveSpawn

Lua
function SC.Editable.ResolveSpawn(src, character, spawnKey)    return nilend

You decide where the character spawns. Runs before all resource rules, and what you return wins:

  • vector4(x, y, z, heading)
  • a table { x, y, z, heading }, or w instead of heading
  • nil for the normal rules: player choice, last position, Config.Spawn.default

spawnKey is the key of the location the player picked, or nil.

Use it when jail or hospital must override the player's choice. Only your jail resource knows who is jailed.

ResolveBucket

Lua
function SC.Editable.ResolveBucket(src, character)    return nilend

The routing bucket the character joins after leaving the private world. nil means the main world (0). Use it for instanced apartments, a jail bucket, or a running event.

Runs only while the player is still in the bucket this resource put them in. If something else already moved them, they stay there.

CanSelectCharacter

Lua
function SC.Editable.CanSelectCharacter(src, character)    return trueend

Veto on character selection. Return false and a reason, and the player sees the reason as an error on the select screen. Use it for suspended characters, a whitelist, or a full gang.

Client hooksLink copied

File: bridge/client/editable.lua.

HookWhen
OnStateChanged(state)The player's stage changed
OnPlayerSpawned(character)The whole flow ended and the player has control
OnSelectOpened()Character select opened, on join and every relog

OnStateChanged

Lua
function SC.Editable.OnStateChanged(state)end
FieldTypeMeaning
busybooleantrue from the loading screen until the player has control
spawnedbooleanThe opposite of busy
openbooleanThe resource UI is on screen
citizenidstring/nilCitizen id of the character being played

Runs only on a real change, so you do not need to filter it.

busy is the field for anticheats. During the first half minute, the character is frozen, invisible, teleported twice across the map, and driven by a scripted camera. It looks exactly like a cheater.

busy covers all of it: loading screen, select, appearance editor, spawn selector, arrival, and spawn animation.

OnPlayerSpawned

Lua
function SC.Editable.OnPlayerSpawned(character)end

The camera is back on the player and they have control. Turn your HUD or phone back on here.

OnSelectOpened

Lua
function SC.Editable.OnSelectOpened()end

Character select just opened, on join and on every /relog. A good place to hide the HUD.

← PreviousIntegrationsMulticharacterNext β†’Exports and EventsMulticharacter

On this page

  • Your code cannot break loading
  • Hooks or exports
  • Call order
  • Server hooks
  • Client hooks
↑ Back to top
Ready when you are

Put your server on something that holds up

150+ servers run our resources - ESX, QBCore and standalone. Once the payment clears, the package is waiting in Keymaster.

Browse the catalogueAsk on Discord β†—
  • Delivered instantly
  • Support with no expiry
  • 100+ reviews
  • Payment via Tebex

SleepyCode

FiveM Scripts

Checkout is run by Tebex Limited- they handle payment, invoicing and refunds. Β© 2026

Community

  • Discord
  • YouTube
  • X (Twitter)

Navigation

  • Home
  • All Scripts
  • ESX Scripts
  • QBCore Scripts
  • Free Scripts
  • About
  • Blog
  • Documentation
  • Support

Legal

  • Privacy Policy
  • Tebex Privacy Policy
  • Terms of Service
  • Impressum

Β© 2026 SleepyCode. Not affiliated with Rockstar Games or Take-Two Interactive.

Powered byTebex