Installation
← README · Configuration · Developer API · FAQ
1. Download
- Escrow edition: open Cfx.re Portal › Granted assets with the Cfx.re account that bought it, and download
lumo-battleroyale. It only runs on servers whose licence key belongs to that account. - Open-source edition: download the zip from your Tebex purchase email or the Portal.
Unzip it and put the lumo-battleroyale folder anywhere under resources/, for example resources/[lumo]/lumo-battleroyale. Don't rename the folder.
2. server.cfg
Start it after oxmysql, your framework and (if you use them) your target, inventory and pma-voice:
cfg
ensure oxmysql
ensure qb-core # or qbx_core / es_extended / nothing
# … your inventory, target, pma-voice …
ensure lumo-battleroyaleFor Cayo Perico (one of the five maps) the server needs game build 2189 or newer:
cfg
sv_enforceGameBuild 3095On an older build, remove the cayo entry from config/maps.lua so it can't be voted for.
3. Database
Nothing to import. On start the resource runs CREATE TABLE IF NOT EXISTS lumo_br_stats. If your database user can't create tables, run sql/install.sql by hand once.
4. Admin access
Admins can use /bradmin, /brtest, /brstart, /brstop, /brbots and the lobby's Admin tab. A player is an admin when either of these is true:
- they are in one of the framework groups in
Config.Admin.permissions(defaultadmin,god), or - they have the ACE
lumo.battleroyale.admin.
The ACE works on every framework, including standalone:
cfg
add_ace group.admin lumo.battleroyale.admin allow
add_principal identifier.license:YOUR_LICENSE group.admin| Framework | Group check used |
|---|---|
| QBCore | QBCore.Functions.HasPermission(src, group) (the admin/god permissions from qb-core) |
| Qbox | the ACE group.<name>, so group.admin |
| ESX | xPlayer.getGroup() equals one of the names (admin, superadmin …) |
| Standalone | ACE only |
On ESX the default group names are admin and superadmin, so set Config.Admin.permissions = { 'admin', 'superadmin' }.
5. First run
- Restart the server and watch the console for
[lumo-battleroyale] framework: qb(orqbx,esx,standalone). If the wrong framework shows, setConfig.Frameworkinconfig.lua. - Join, and run
/brtestfor a solo match against bots on the first map. Try/brtest squad paletofor bot teammates. - Find the hub: the Lumo Royale parachute blip at Fort Zancudo. Walk to a desktop terminal and use it with your target (or E when no target resource runs).
- Move the hub anywhere you like: stand on the spot, open
/bradminand press Move hub here. It's saved indata/hub.json. Delete that file to go back toConfig.Hub.coords.
Framework notes
QBCore
- Works with qb-inventory, lumo-inventory, ps-/lj-inventory and ox_inventory. Weapons are inventory items, so the match never touches them. The inventory and hotbar are locked during a match (
inv_busy). - qb-ambulancejob never sees a death in a match (the ped is kept above a hidden health floor).
- qb-vehiclekeys gets keys for match vehicles. qb-weathersync is paused during the match.
Qbox
Nothing to install beyond the steps above; the match handles these on its own:
- ox_inventory:
invBusy/invHotkeysare set during the match and the city weapon is holstered first. ox's weapon-mismatch check (inventory:weaponmismatch), which strips any weapon ox didn't hand out, is switched off for the match throughexports.ox_inventory:weaponWheel(true)and back on when you leave. Without that, match weapons were pulled out of your hands within a fraction of a second. - qbx_medical: bleeding and damage effects are disabled for the match (
DisableBleeding/DisableDamageEffects) and enabled again on exit. Its injury tracker (limp walk, no sprint, "your leg feels…" pain messages, stagger) has no switch, so the match wipes the hit record it reads every frame, and a watchdog heals any wound that still gets through and resets your walk. For a 100 % guarantee, add the guard under Medical scripts. Its revive only fires after a lethal fall, and the inventory lock is put back right after it. - Hunger, thirst, stress: noted on entry, held at 100 / 100 / 0 during the match and written back on exit, so qbx_core can't take match HP at 0 and shooting can't blur your screen with stress.
- qbx_vehiclekeys is handled on the server.
One thing does need a manual edit: qbx_hud has no off switch, so its status bars stay on screen in a match unless you add the one-line guard under City HUD. The minimap is turned on for the match even if qbx_hud hides it on foot.
qbx_smallresources/qbx_hudcomponents hides GTA's aim dot. The match draws its own crosshair while you aim (Config.Hud.crosshair), so nothing to change there.
ESX
- Works with ESX Legacy, and with older 1.x through the
esx:getSharedObjectevent. - With ox_inventory: the same as Qbox.
- Without ox_inventory: ESX keeps weapons on the ped. The match clears them, notes each weapon's ammo when the match starts and writes it back when you leave (match gunfire would otherwise drain your city ammo), then gives the city loadout back (
esx:restoreLoadout). - Cash rewards go to the
moneyaccount (Config.Rewards.account = 'cash'is translated). Use'bank'for the bank.
Standalone
- No framework: stats use the Rockstar licence, rewards give XP only, and notifications use ox_lib or the GTA feed. Admin is ACE only.
City HUD
The match has its own HUD. Your city HUD (hunger, thirst, stress, money, street name) should hide while a player is in a match. Every player in a match carries the lumo_quiet statebag, and Lumo's own HUD already reads it. Most other HUDs have no export to turn them off, so give them one guard in their main loop:
qbx_hud (client/main.lua), qb-hud (client.lua) and ps-hud (client.lua): find the player-HUD loop, the if LocalPlayer.state.isLoggedIn then that is followed by local show = true, and change that line to:
lua
if LocalPlayer.state.isLoggedIn and not LocalPlayer.state.lumo_quiet thenThe loop's else branch already hides the HUD. Only change that one line; the other isLoggedIn checks in the file can stay. Restart the HUD (or the server).
Any other HUD: if it has an export or event to show/hide it, call it from Config.CityHud in config.lua:
lua
Config.CityHud = function(show)
exports['my-hud']:toggleHud(show) -- false when the match starts, true when you're home
endThe client event lumo-battleroyale:cityHud (one argument, show) fires at the same moments, if you'd rather listen from the HUD's side.
Medical scripts
The match keeps the ped above a hidden health floor and runs its own damage model, so a medical script should not build wounds, limps or pain messages from match hits. The match already wipes the hit record those scripts read, which stops nearly all of it. To make it airtight, add lumo_quiet to their damage check:
qbx_medical (client/damage/damage.lua, in checkForDamage):
lua
if (isArmorDamaged or isHealthDamaged) and not LocalPlayer.state.lumo_quiet thenqb-ambulancejob (client/main.lua, the damage-check loop):
lua
if (armorDamaged or healthDamaged) and not LocalPlayer.state.lumo_quiet thenesx_ambulancejob has no wound system, so ESX needs nothing here.
Optional resources
| Resource | What it adds |
|---|---|
ox_target / qb-target | terminals as target zones (otherwise walk up and press E) |
ox_lib | prompts and notifications on standalone |
pma-voice | a private radio channel for each Duo/Squad team (channels Config.Match.radioBase+) |
qb-weathersync / cd_easytime | paused during the match so each map keeps its own sky |
qb-vehiclekeys / qbx_vehiclekeys / wasabi_carlock | keys for match vehicles |
Updating
- Back up your
config.lua,config/folder anddata/hub.json. - Replace the folder with the new version.
- Compare your old config with the new one (Changelog lists new options) and copy your values across.
Uninstall
Remove the ensure line and the folder. The stats live in one table: DROP TABLE lumo_br_stats;.