Standalone mode (no framework)
lumo-multicharacter and lumo-spawn run on a server with no QBCore, Qbox or ESX. They switch to standalone on their own when no core is started (forced with Framework = 'standalone' in bridge/config.lua).
Who does what
| Installed | Behaviour |
|---|---|
| lumo-multicharacter + lumo-spawn | Pick a character, then the spawn map. Last location is per character. |
| lumo-multicharacter only | Pick a character, spawn at the last location (new characters: Config.DefaultSpawn). |
| lumo-spawn only | The spawn map opens when the player joins. Last location is per Rockstar licence (stored in resource KVP, no table). Turn off with Config.Standalone.OpenOnJoin = false. |
lumo-multicharacter is the owner of characters (Standalone.OwnsCharacters = true in its bridge/config.lua); lumo-spawn reads from it. Keep those two values as shipped.
What is stored
lumo_characters (created automatically, also in lumo-multicharacter/sql/install.sql):
| Column | Content |
|---|---|
citizenid | 8-character id, e.g. ABC12345 |
license | Rockstar licence (license:…) |
cid | Slot, 1..N |
charinfo | JSON: firstname, lastname, birthdate, gender (0/1), nationality, height, phone, account |
metadata | JSON, free for your scripts (SetMetaData export) |
position | JSON {x,y,z,w}, saved every SaveInterval ms (default 60 s), on logout, disconnect and resource stop. Only after the player has actually spawned. |
Money, jobs, gangs and items are framework features: they read as 0 / Civilian / none. Starter items are given only when an inventory resource such as ox_inventory is running.
Permissions
Admin checks use ACE groups. /logout needs admin, /spawneditor needs god or admin (Config.SpawnEditor.AdminGroups):
cfg
add_principal identifier.license:110000xxxxxxxxx group.adminPed and appearance
On login the player becomes the freemode ped matching the character's gender (mp_m_freemode_01 / mp_f_freemode_01). Turn off with Standalone.SetPedModel = false. If an appearance script runs (illenium-appearance, fivem-appearance, …), new characters get its creator through the standard qb-clothes:client:CreateFirstCharacter event, and it dresses existing characters as it normally does.
For developers: events
Server (local, AddEventHandler):
| Event | Arguments | When |
|---|---|---|
lumo:server:characterLoaded | player (player.PlayerData, player.source) | A character was chosen or created |
lumo:server:characterUnloaded | source, reason | Logout or disconnect |
Client (RegisterNetEvent / AddEventHandler):
| Event | Arguments | When |
|---|---|---|
lumo:client:playerDataChanged | PlayerData or nil | On login, metadata change, logout |
lumo:client:characterLoaded | PlayerData | The ped is placed in the world |
lumo:client:characterUnloaded | – | Logout |
For developers: exports (lumo-multicharacter)
Server:
lua
local pd = exports['lumo-multicharacter']:GetPlayerData(source) -- QB-shaped PlayerData or nil
exports['lumo-multicharacter']:GetCitizenId(source)
exports['lumo-multicharacter']:IsLoggedIn(source)
exports['lumo-multicharacter']:GetPlayerByCitizenId('ABC12345') -- PlayerData or nil
exports['lumo-multicharacter']:GetLoggedInPlayers() -- { [source] = PlayerData }
exports['lumo-multicharacter']:SetMetaData(source, 'hunger', 80) -- saved with the positionClient:
lua
local pd = exports['lumo-multicharacter']:GetPlayerData()
exports['lumo-multicharacter']:IsLoggedIn()PlayerData has the QBCore shape (citizenid, cid, charinfo, money, job, gang, metadata, position), so most QB-style code reads it unchanged. These exports exist only in standalone mode; with a framework, use the framework.