Koja Scripts

Configuration

Every option in shared/config.lua of Koja Spawn Selector, the spawn definition with job, gang and ACE locks, categories and the editable files.

Configuration

Everything lives in shared/config.lua. Restart the resource after a change.

General

OptionDefaultWhat it does
Config.Locale'pl'Language, a file name from shared/locales/
Config.DebugfalsePrints selections and failing checks to the console
Config.ServerName'KOJA ROLEPLAY'Shown in the panel header
Config.Theme.accent'#FF9B00'Accent colour of buttons, pins, the beacon and the glow
Config.Theme.background'#121212'Panel background, mixed with a warm brown like Koja Appearance
Config.FallbackLegion SquareWhere a player spawns when no location is available

Opening

shared/config.lua
Config.Open = {
    OnPlayerLoaded = true,
    Delay = 250,
    CanCancel = false,
    ShowLocked = true,
    RememberChoice = true,
}
Config.QbSpawnCompat = true
OptionWhat it does
OnPlayerLoadedESX: open on esx:playerLoaded. Skipped while Koja Multicharacter runs
Delayms to wait after esx:playerLoaded before opening
CanCancelDefault for ESC / the exit button. Every Open call can override it with canCancel
ShowLockedtrue shows locked spots with their lock label, false hides them
RememberChoicePreselect the location the player picked last time
Config.QbSpawnCompatListen to the qb-spawn events from qb-multicharacter

Admin

shared/config.lua
Config.Command = { Enabled = true, Name = 'spawnselector' }
Config.Admin = { Groups = { 'admin', 'superadmin', 'god' }, Ace = 'command' }

The check goes through KOJA.Server.IsAdmin; change it in ServerEditable.IsAdmin.

Last location

shared/config.lua
Config.LastLocation = {
    Enabled = true,
    SaveInterval = 60,
    FrameworkFallback = true,
    IgnoreBuckets = true,
}
OptionWhat it does
EnabledShow "Last location" and save positions
SaveIntervalSeconds between saves of every spawned player (minimum 10). Positions are also saved on logout, disconnect and resource stop
FrameworkFallbackNo saved row yet: use users.position (ESX) or players.position (QBCore)
IgnoreBucketsDo not save players in a routing bucket other than 0 (interiors, instances)

New characters

shared/config.lua
Config.NewCharacter = {
    UseSelector = false,
    Spawns = {
        { id = 'start_airport', label = 'Los Santos International', description = 'Arrivals', category = 'start', coords = vec4(-1037.74, -2737.89, 20.17, 327.9) },
    },
}

UseSelector = false leaves new ESX characters to your character creator. When a new character opens the selector (isNew = true), only these spawns are listed.

Camera flight

shared/config.lua
Config.Cinematic = {
    Enabled = true,
    Height = 650.0,
    TopFov = 45.0,
    HoldTime = 900,
    DescendTime = 3200,
    ApproachDistance = 22.0,
    ApproachHeight = 14.0,
    SettleTime = 1800,
    FinalDistance = 3.4,
    FinalHeight = 0.85,
    BlendOut = 1100,
    LoadTimeout = 6000,
}
OptionWhat it does
Enabledfalse = a plain fade and teleport
Height, TopFov, HoldTimeThe top-down shot: metres above the spot, field of view, how long it holds (ms)
DescendTimems of the descent to the street
ApproachDistance, ApproachHeightWhere the descent ends: metres behind and above the ped
SettleTime, FinalDistance, FinalHeightThe last move to an over-the-shoulder shot
BlendOutms of the blend into the gameplay camera
LoadTimeoutLongest wait (ms) for collision and streaming at the spot

Map

shared/config.lua
Config.Map = {
    FocusDistance = 2600,
    OnlineDetail = true,
}
OptionWhat it does
FocusDistanceCamera distance in metres when a location is selected
OnlineDetailUp close, stream the sharper zoom 7 tiles from the Rockstar map CDN. Offline the shipped zoom 6 tiles are used

Categories

shared/config.lua
Config.Categories = {
    { id = 'last', icon = 'footprints', order = 1 },
    { id = 'start', icon = 'plane', order = 2 },
    { id = 'property', icon = 'home', order = 3 },
    { id = 'job', icon = 'briefcase', order = 4 },
    { id = 'gang', icon = 'skull', order = 5 },
    { id = 'city', icon = 'map-pin', order = 6 },
}

The label comes from the locale key category_<id>, or set label yourself. Other resources can add categories with RegisterCategory.

Icons: anchor, briefcase, building, car, footprints, home, hospital, lock, map-pin, mountain, plane, shield, skull, star, tent, trees, waves. Unknown names show a map pin.

Spawns

Config.Spawns is the list everyone can see. A spawn is a table:

Spawn definition
{
    id = 'mrpd',
    label = 'Mission Row',
    description = 'Police Department',
    category = 'job',
    coords = vec4(428.23, -984.28, 29.76, 3.5),
    icon = 'shield',
    image = 'https://example.com/mrpd.webp',
    jobs = { police = 0, sheriff = 2 },
    onDuty = false,
    gangs = { ballas = 0 },
    ace = 'group.vip',
    lockedLabel = 'VIP only',
    hideLocked = false,
    cinematic = true,
    order = 0,
    data = {},
}
FieldRequiredDescription
idYesUnique string or number. last is reserved for the last location
labelYesName in the list and on the map
coordsYesvec4, vec3 or { x, y, z, w } (also h / heading)
descriptionNoSecond line
categoryNoCategory id, default city
iconNoOverrides the category icon
imageNoPicture for the card. Without one, the card shows the map around the spot
jobsNo'police', { 'police', 'sheriff' } or { police = minGrade }
onDutyNoThe job must be on duty
gangsNoSame format as jobs, QBCore gangs
aceNoACE permission the player needs
lockedLabelNoText when locked. Default: "Police only" from the job label
hideLockedNoHide instead of showing it locked
cinematicNoTurns the camera flight on or off for this spot
orderNoOrder inside its category
dataNoAnything. You get it back in onSpawn and the events

Editable files

These two files are yours to change and keep their names between updates.

client/editable.lua

FunctionCalled when
ClientEditable.Notify(desc, type)The selector shows a message
ClientEditable.OnOpen(options)The map opens. Hide your HUD here
ClientEditable.OnClose(spawn, options)The map closes (spawn is nil when cancelled). Show your HUD again
ClientEditable.OnSpawned(spawn, options)The player landed
ClientEditable.CanOpen(options)Return false to block opening

server/editable.lua

FunctionWhat it does
ServerEditable.GetJob(source)Job used for locks: { name, label, grade, onDuty }
ServerEditable.GetGang(source)Gang used for locks (QBCore by default)
ServerEditable.CanAccess(source, spawn, job)Return false, 'Reason' to lock a spot
ServerEditable.GetSpawns(source, identifier)Return extra spawns for this player
ServerEditable.IsAdmin(source)Who can use the admin command
ServerEditable.OnSpawned(source, spawn, isNew)The player landed