> For the complete documentation index, see [llms.txt](https://arctic-development.gitbook.io/arctic-development/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://arctic-development.gitbook.io/arctic-development/scripts/spawn-selector.md).

# Spawn Selector

The **Spawn Selector Script** for FiveM is the one-stop solution for spawn selection In-Game!

***

<figure><img src="/files/SpMscVNMZqsjkgvXax7q" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/Cs9O2mU7CjExbI5gseSI" alt=""><figcaption><p>Spawn Selection UI [None Selected]</p></figcaption></figure>

<figure><img src="/files/rXpzORFlJjYQ4Kqjk99Q" alt=""><figcaption><p>Spawn Selection Preview [Last Location]</p></figcaption></figure>

<figure><img src="/files/a3Gi1zLSFsRTwPIFjaPq" alt=""><figcaption><p>Spawn Selection Preview [Civilian]</p></figcaption></figure>

***

```lua
Config = {}

Config.Debug = false

Config.UI = {
    title = 'Spawn Selector',
    subtitle = 'Choose where your story begins',
    accent = '#5bc0de',
    welcomeTitle = 'Welcome Text',
    welcomeHeading = 'Hello and welcome to Arctic Development!',
    welcomeLines = {
        'We are thrilled to have you join our community.',
        'For all vehicles, scripts, and other important details, please press the **F5** button.',
        'If you need assistance, you can contact us via Discord at discord.gg/arcticdev'
    }
}

-- If true, players only see this automatically on first join for this session.
-- They can still reopen it with the command if AllowReopenCommand is true.
Config.OpenOnlyFirstJoin = true

-- Recommended: true. This prevents default random spawnmanager spawning before your menu selection.
Config.DisableAutoSpawn = true

-- Command for staff/testing/player reopen.
Config.AllowReopenCommand = true
Config.Command = 'spawnselector'

-- Hides radar/HUD while the spawn menu is open.
Config.HideRadarWhileOpen = true

-- Freezes/invincibles the player while selecting.
Config.ProtectPlayerWhileSelecting = true

-- When the menu opens, the player is spawned high in the air, frozen, invisible, and hidden behind the NUI.
-- This prevents the ugly “player standing behind the UI” issue even if another resource tries to spawn them early.
Config.Holding = {
    enabled = true,
    coords = vector4(0.0, 0.0, 1250.0, 0.0),
    fadeOutMs = 0
}

-- Stores each player's real last location server-side in data/last_locations.json.
-- This survives disconnects/reconnects and is keyed to the player's license/identifier.
Config.LastLocation = {
    enabled = true,
    label = 'Last Location',
    category = 'Recent Location',
    icon = 'LAST',
    description = 'Return to your most recently saved location.',

    -- Server-side JSON persistence.
    -- Keep this as server_json if you want Last Location to work after a player leaves and rejoins.
    storage = 'server_json',
    jsonFile = 'data/last_locations.json',
    serverRequestTimeoutMs = 2500,

    -- Identifier priority used by the server JSON save system.
    -- license is best for most FiveM servers.
    identifierPriority = { 'license', 'license2', 'fivem', 'steam', 'discord' },

    -- Saves the player's real position every few seconds after they spawn.
    -- This is what makes Last Location follow where the player actually was, not only the spawn they selected.
    saveIntervalMs = 15000,
    minimumSaveDistance = 2.0,
    maxSaveZ = 900.0,

    -- Used only for placing the Last Location marker on the included atlas map.
    -- You can tune these bounds if you replace the map image with a custom one.
    mapBounds = {
        minX = -4200.0,
        maxX = 4500.0,
        minY = -4300.0,
        maxY = 8200.0
    },

    defaultMap = { x = 50.0, y = 50.0 }
}

-- Startup timing / polish.
Config.OpenDelayMs = 0
Config.PreSpawnOverlayMs = 0
Config.CollisionTimeoutMs = 9000

-- Uses the included GTA V atlas-style map image at html/assets/map.png.
-- Replace that file with your own custom server map if needed.
Config.Map = {
    useImageMap = true,
    image = 'assets/map.png'
}

-- Category buttons shown on the UI.
-- Civilian is the default public category. There is intentionally no "All Spawns" tab.
-- LEO / Fire-EMS / DOT are hidden by default until you enable them and connect your own logic.
--
-- To enable a department later:
--   1. Set enabled = true on the category.
--   2. Add your permission/export logic in Config.Access.CanUseCategory below.
--
-- hideWhenLocked = true means players who fail the permission check will not see the category at all.
-- Set hideWhenLocked = false if you would rather show a locked category button.
Config.Categories = {
    { id = 'civilian', label = 'Civilian', icon = 'CIV', description = 'Default public spawn locations.', enabled = true, hideWhenLocked = true },
    { id = 'last', label = 'Last Location', icon = 'LAST', description = 'Return to your previously saved location.', enabled = true, hideWhenLocked = true },

    -- Department categories are OFF by default so they do not show until you wire the logic yourself.
    { id = 'leo', label = 'LEO', icon = 'LEO', description = 'Law enforcement spawn points.', enabled = false, hideWhenLocked = true },
    { id = 'fireems', label = 'Fire / EMS', icon = 'EMS', description = 'Fire and medical spawn points.', enabled = false, hideWhenLocked = true },
    { id = 'dot', label = 'DOT', icon = 'DOT', description = 'Department of Transportation spawn points.', enabled = false, hideWhenLocked = true }
}

-- Access hooks. Civilian and Last Location are allowed by default.
-- Department categories return false by default so they stay hidden unless you enable the category
-- and replace the examples with your own role/duty/export logic.
Config.Access = {}

Config.Access.CanUseCategory = function(categoryId)
    if categoryId == 'civilian' or categoryId == 'last' then
        return true
    end

    -- Examples for later:
    -- if categoryId == 'leo' then return exports['your-duty-script']:IsLeo() end
    -- if categoryId == 'fireems' then return exports['your-duty-script']:IsFireOrEMS() end
    -- if categoryId == 'dot' then return exports['your-duty-script']:IsDOT() end

    return false, 'This department category has not been connected yet.'
end

Config.Access.CanUseSpawn = function(spawn)
    -- Optional per-spawn logic for later:
    -- if spawn.id == 'mission_row_pd' then return exports['your-perms-script']:HasSpawn('mission_row_pd') end
    return true
end

Config.Access.DefaultDeniedMessage = 'You do not have access to this spawn yet.'

-- Cinematic drop-in animation settings.
Config.Animation = {
    fadeOutMs = 650,
    fadeInMs = 900,
    cameraDurationMs = 4200,
    airSpawnHeight = 185.0,
    cameraStartHeight = 245.0,
    cameraEndHeight = 24.0,
    cameraStartDistance = 42.0,
    cameraEndDistance = 12.0,
    cameraSideOffset = 32.0,
    cameraFov = 48.0,
    finalFadeOutMs = 420,
    finalFadeInMs = 850,
    freezeAfterSpawnMs = 300,
    makePedVisibleAfterDrop = true
}

-- Marker x/y are percentages on the NUI map.
-- coords = vector4(x, y, z, heading)
Config.Spawns = {
    -- CIVILIAN
    {
        id = 'legion_square',
        title = 'Legion Square',
        category = 'Civilian',
        categoryKey = 'civilian',
        description = 'Start in the heart of Los Santos with fast access to city streets, shops, and downtown roleplay.',
        coords = vector4(195.17, -933.77, 30.69, 144.50),
        map = { x = 52.0, y = 61.0 },
        icon = 'CITY'
    },
    {
        id = 'vespucci_beach',
        title = 'Vespucci Beach',
        category = 'Civilian',
        categoryKey = 'civilian',
        description = 'Spawn near the beach, boardwalk, rental spots, and west-side civilian roleplay.',
        coords = vector4(-1184.34, -1509.92, 4.65, 124.72),
        map = { x = 36.0, y = 67.0 },
        icon = 'BEACH'
    },
    {
        id = 'sandy_shores',
        title = 'Sandy Shores',
        category = 'Civilian',
        categoryKey = 'civilian',
        description = 'Perfect for county life, desert businesses, towing, mechanics, and northern adventures.',
        coords = vector4(1850.66, 3683.11, 34.27, 212.35),
        map = { x = 62.0, y = 37.0 },
        icon = 'SANDY'
    },
    {
        id = 'paleto_bay',
        title = 'Paleto Bay',
        category = 'Civilian',
        categoryKey = 'civilian',
        description = 'Begin in the quiet northern town with access to highways, forests, and rural roleplay.',
        coords = vector4(-105.81, 6327.84, 31.58, 314.85),
        map = { x = 44.0, y = 14.0 },
        icon = 'PALETO'
    },
    {
        id = 'airport',
        title = 'Los Santos Airport',
        category = 'Civilian',
        categoryKey = 'civilian',
        description = 'Arrive at LSIA for airport roleplay, travel scenes, and quick highway access.',
        coords = vector4(-1037.72, -2737.68, 20.17, 329.78),
        map = { x = 42.0, y = 82.0 },
        icon = 'AIR'
    },

    -- LEO PLACEHOLDERS
    {
        id = 'mission_row_pd',
        title = 'Mission Row PD',
        category = 'LEO',
        categoryKey = 'leo',
        description = 'Law enforcement spawn point placeholder. Connect this category to your own department/duty script when ready.',
        coords = vector4(428.23, -984.28, 30.71, 90.0),
        map = { x = 55.0, y = 61.5 },
        icon = 'LSPD'
    },
    {
        id = 'sandy_so_pd',
        title = 'Sandy Sheriff Office',
        category = 'LEO',
        categoryKey = 'leo',
        description = 'County law enforcement spawn point placeholder for BCSO or similar departments.',
        coords = vector4(1853.63, 3686.52, 34.27, 212.0),
        map = { x = 62.0, y = 37.0 },
        icon = 'SO'
    },

    -- FIRE / EMS PLACEHOLDERS
    {
        id = 'davis_fire_station',
        title = 'Davis Fire Station',
        category = 'Fire / EMS',
        categoryKey = 'fireems',
        description = 'Fire and medical spawn point placeholder. Connect this to your Fire/EMS logic later.',
        coords = vector4(201.05, -1644.72, 29.80, 318.0),
        map = { x = 54.0, y = 67.0 },
        icon = 'FIRE'
    },
    {
        id = 'pillbox_medical',
        title = 'Pillbox Medical',
        category = 'Fire / EMS',
        categoryKey = 'fireems',
        description = 'Hospital/EMS spawn point placeholder for medical roleplay.',
        coords = vector4(298.59, -584.39, 43.26, 70.0),
        map = { x = 54.2, y = 59.0 },
        icon = 'EMS'
    },

    -- DOT PLACEHOLDERS
    {
        id = 'la_mesa_dot',
        title = 'La Mesa DOT Yard',
        category = 'DOT',
        categoryKey = 'dot',
        description = 'Department of Transportation spawn point placeholder. Hook this into your DOT script when ready.',
        coords = vector4(846.72, -902.15, 25.25, 91.0),
        map = { x = 59.0, y = 62.5 },
        icon = 'DOT'
    }
}

```

{% hint style="success" %}
Downloads

\[PAID | Open Source] [Official Store Link](https://arcticdevlabs.com/package/Script/Spawn-Selector)
{% endhint %}
