# SLEEK SPAWN SELECTOR

{% embed url="<https://youtu.be/Bit975iFYCc?si=s-JTqxQzSebcGJ9Z>" %}

{% hint style="success" %}
This script is compatible with **ESX and** **QB.**&#x20;
{% endhint %}

{% hint style="success" %}
This script is compatible with **QB-Apartments, QB-Houses, Quasar Housing and PS-Housing.**
{% endhint %}

**INSTALLATION GUIDE**

{% tabs %}
{% tab title="ESX" %}
**Installation Guide - forge-spawn**

**1️⃣ Download & Extract**

* Download **forge-spawn.pack.zip** from **KEYMASTER**.
* Unzip it and place the **forge-spawn** folder inside your server's `resources` directory.

***

**2️⃣ Add to Server Startup**

* Open your **server.cfg** and add the following line:

  ```plaintext
  ensure forge-spawn
  ```
* **Do not rename the folder**—it must remain as `forge-spawn`, or the resource will not function correctly.
* Ensure it is placed **just below your core resources** for proper loading.

***

**3️⃣ Remove Conflicting Scripts**

* **Delete or remove** any other Spawn Selector you previously installed, such as **qb-spawn**.

***

**4️⃣ Clear Cache & Restart Server**

* **Clear the cache** of both your server and your FiveM client.
* **Restart your entire server** with `forge-spawn` **properly ensured** in your `server.cfg`.

🚀 Once installed, your spawn system should work seamlessly
{% endtab %}

{% tab title="QB and QBOX" %}

#### **1️⃣ Download & Extract**

* Download **forge-spawn.pack.zip** from **KEYMASTER**.
* Unzip it and place the **forge-spawn** folder inside your server's `resources` directory.

***

**2️⃣ Add to Server Startup**

* Open your **server.cfg** and add the following line:

  ```plaintext
  ensure forge-spawn
  ```
* **Do not rename the folder**—it must remain as `forge-spawn`, or the resource will not function correctly.
* Ensure it is placed **just below your core resources** for proper loading.

***

**3️⃣ Remove Conflicting Scripts**

* **Delete or remove** any other Spawn Selector you previously installed, such as **qb-spawn**.

***

**4️⃣ Prevent Roleplay Evasion with /relog (QB-Ambulancejob Users Only)**

If you use **/relog**, and want the system to prevent dead players from respawning anywhere except in their **LAST LOCATION** (to avoid roleplay evasion), you must **delete the following lines** from **qb-ambulancejob**:

* **File:** `qb-ambulancejob/client/main.lua`
* **Lines:** **700-702** *(this may vary depending on your version, so it's best to search for these functions and comment them out)*
* **Remove or comment out:**

  ```lua
  TriggerServerEvent('hospital:server:SetDeathStatus', false)
  TriggerServerEvent('hospital:server:SetLaststandStatus', false)
  TriggerServerEvent('hospital:server:SetArmor', GetPedArmour(ped))
  ```

***

**5️⃣ If Using QB-Apartments**

* You **must delete** a specific line from **qb-interior** to prevent conflicts:
  * **File:** `qb-interior/client/main.lua`
  * **Line:** **71** *(this may vary depending on your version, so it's best to search for these functions and comment them out)*
  * **What to remove/comment out:**

    ```lua
    TriggerEvent('qb-clothes:client:CreateFirstCharacter')
    ```

**If You Use QBOX with qbx\_properties**

You must also delete a line from **qbx\_properties** to prevent conflicts:

* **File**: `qbx_properties/server/apartmentsselect.lua`
* **Remove/Comment out**:

```lua
-- TriggerClientEvent('qb-clothes:client:CreateFirstCharacter', playerSource)
```

***

**6️⃣ Clear Cache & Restart Server**

* **Clear the cache** of both your server and your FiveM client.
* **Restart your entire server** with `forge-spawn` **properly ensured** in your `server.cfg`.

🚀 Once installed, your spawn system should work seamlessly!
{% endtab %}
{% endtabs %}

{% hint style="success" %}
If you are ESX or QB you will only have to put the script forge-spawn ensured in your server and configure it to your liking.
{% endhint %}

{% hint style="warning" %}
If you use another Multicharacter that you need to add an export that opens the Spawn System, this is the export that opens it:

* &#x20;<mark style="background-color:orange;">**CLIENT SIDE ONLY:**</mark>&#x20;

```lua
exports["forge-spawn"]:open() -- this will open the spawn menu
```

{% endhint %}

**CONFIG**

The following will explain all the settings, one of the most important things that I recommend you spend a few minutes to understand in order to offer your users the best possible experience.

{% tabs %}
{% tab title="CONFIG" %}
{% hint style="warning" %}
If you use the latest update of the script it **will automatically detect everything regarding Framework, Skin Manager and Identifier**. <mark style="color:red;">Don't touch anything where it says</mark> <mark style="color:red;"></mark><mark style="color:red;">**"You don't need to touch this".**</mark>
{% endhint %}

{% code lineNumbers="true" %}

```lua
Config = {}

--  ██████╗ ██████╗ ███╗   ██╗███████╗██╗ ██████╗ ██╗   ██╗██████╗  █████╗ ██████╗ ██╗ ██████╗ ███╗   ██╗
-- ██╔════╝██╔═══██╗████╗  ██║██╔════╝██║██╔════╝ ██║   ██║██╔══██╗██╔══██╗██╔══██╗██║██╔═══██╗████╗  ██║
-- ██║     ██║   ██║██╔██╗ ██║█████╗  ██║██║  ███╗██║   ██║██████╔╝███████║██████╔╝██║██║   ██║██╔██╗ ██║
-- ██║     ██║   ██║██║╚██╗██║██╔══╝  ██║██║   ██║██║   ██║██╔══██╗██╔══██║██╔══██╗██║██║   ██║██║╚██╗██║
-- ╚██████╗╚██████╔╝██║ ╚████║██║     ██║╚██████╔╝╚██████╔╝██║  ██║██║  ██║██║  ██║██║╚██████╔╝██║ ╚████║
--  ╚═════╝ ╚═════╝ ╚═╝  ╚═══╝╚═╝     ╚═╝ ╚═════╝  ╚═════╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝ ╚═════╝ ╚═╝  ╚═══╝
-- GENERAL                                 
---@type 'ESX'|'QBCore'|'none'                                                                    
Config.framework = GetResourceState('es_extended') == "started" and "ESX" or GetResourceState('qb-core') == "started" and "QBCore" or "none" -- You don't have to touch this

---@type string? a replacement for the default resource name
Config.resourceName = nil -- set the resource name of ESX or QB here, in case you changed it, if not you can set it to nil

---@type boolean
Config.ignoreOnFirstSpawn = true -- This will make the first SPAWN your character does when you create it, not bring up the SPAWN menu

---@type boolean
Config.useApartments = (GetResourceState("qb-apartments") == "started")
    or (GetResourceState("ps-housing") == "started")
    or false -- You don't have to touch this

---@type vector3 where the player will spawn if they created a new character. This will only be used, if Config.ignoreOnFirstSpawn is set to true
Config.firstSpawn = vector3(-1037.5580, -2737.6663, 20.1693)

---@type 'qb-houses'|'qs-housing'|'ps-housing'|'none'?
Config.housing =
    (GetResourceState('qb-houses') == "started" and "qb-houses")
or  (GetResourceState('qs-housing') == "started" and "qs-housing")
or  (GetResourceState('ps-housing') == "started" and "ps-housing")
or  "none" -- You don't have to touch this

-- INTERFACE
Config.color = "#00c5ff" -- color of the ui
Config.volume_hover = 20 -- sound on button hover; set to 0 if there should be no sound (between 0 and 100)
Config.volume_teleport = 20 -- sound on button hover; set to 0 if there should be no sound (between 0 and 100)

---@type Dictionary<string, string> translations
Config.translations = {
    ["teleport_to_last_location"] = "TELEPORT TO LAST LOCATION",
    ["teleport"] = "TELEPORT",
    ["top_description"] = "Welcome to the Spawn Selector where you can choose where you want to spawn",
    ['house_description_text'] = "Your house / appartment"
}

---@type Dictionary<string, string> images
---used for images for the appartments
---['address'] = 'path/to/image.png' ('address') can be found in database
---['default'] is the image that should be used in case the address was not yet added to this list and shold not be removed
Config.images = {
    ["default"] = "./assets/images/north-city.png"
}

---@type 'zooming_stars'|'sky_cam'
Config.transitionType = "sky_cam" -- "zooming_stars" / "sky_cam" the tpye of transition you want to use
Config.skyCamWaitTime = 2500 -- time in ms the sky cam will wait before transitioning back to the player view
Config.skyCamTransitionTime = 2000 -- time in ms the sky cam transition into the player view will take
Config.UseAntiEvasion = true -- If true, while you are dead you will not be able to choose a location other than "LAST LOCATION"
Config.lowPerformanceMode = false -- If you put true here. All UI animations will be removed, so there's no possible LAG. This lowers the aesthetics and beauty of the system
Config.particles = true -- If you put false here, it means there will be no particles or dark background. If you think it looks too dark when creating a character, set it to false here. This lowers the aesthetics and beauty of the system
-- SPAWN SETTINGS
---@type Dictionary<string, NAMESPACE.META.SpawnPoint[]>
Config.spawnPoints = {

    ["unemployed"] = { -- will be visible to everyone
        {
            name = "North Station", -- name of the spawn 
            description = "Visit the North and its charms",-- a desctiption of the spawn
            image = "./assets/images/north-station.png", -- image of the spawn
            position = vector3(-427.65, 6029.05, 31.49) -- vector3 / table{x: number, y: number, z: number}
        },
        {
            name = "Airport", -- name of the spawn
            description = "Nothing special, just the airport of the city",-- a desctiption of the spawn
            image = "./assets/images/airport.png", -- image of the spawn
            position = { -- postion (can be reiceived over tx-admin ingame menu)
                x = -1037.5580,
                y = -2737.6663, 
                z = 20.1693
            }
        },
        {
            name = "North of City", -- name of the spawn 
            description = "Visit the north of the city. There are some trendy venues and bars",-- a desctiption of the spawn
            image = "./assets/images/north-city.png", -- image of the spawn
            position = { -- postion (can be reiceived over tx-admin ingame menu)
                x = -191.69,  
                y = 283.76, 
                z = 92.82
            }
        },
        {
            name = "Military Base", -- name of the spawn 
            description = "A little weird stop... who am I to judge you",-- a desctiption of the spawn
            image = "./assets/images/military-base.png", -- image of the spawn
            position = { -- postion (can be reiceived over tx-admin ingame menu)
                x = -2573.58, 
                y = 2320.38, 
                z = 33.06
            }
        },
        {
            name = "Harmony Motel", -- name of the spawn 
            description = "What better than a night in a motel?",-- a desctiption of the spawn
            image = "./assets/images/harmony-motel.png", -- image of the spawn
            position = { -- postion (can be reiceived over tx-admin ingame menu)
                x = 1111.94, 
                y = 2650.22, 
                z = 38.0
            }
        }
    },

    --[[
    ["taxi"] = { -- will only be visible to players with the 'taxi' job
        {
            name = "Taxi Station",
            description = "Get your taxi and make some money.",
            image = "./assets/images/taxi-station.png",
            position = {
                x = 900.3630, 
                y = -171.6680,
                z = 74.0756
            }
        }
    },
    
    ["police"] = { -- will only be visible to players with the 'police' job
        {
            name = "Central Police Station",
            description = "Go to work as a policeman and earn money",
            image = "./assets/images/police-station.png",
            position = { 
                x = 413.83, 
                y = -988.85,
                z = 29.42
            }
        }
    },
    ]]

-- Add more, as many as you want, just copy and paste

}
```

{% endcode %}
{% endtab %}

{% tab title="OPEN" %}

```lua
--[[
    OPEN FUNCTIONS
    FOR MORE INFORMATION ABOUT RETURN TYPES, CHECK THE META.LUA FILE
]]

OpenFunc = {}

OpenFunc.client = {}


---loads the houses of the player in case a custom housing system is used.
---@nodiscard
---@return boolean used true if this function should be used, and not the default function 
---@return NAMESPACE.META.House[] houses a list of houses of this player
function OpenFunc.client.loadHouses()
    --- return:
    ---     used: true if this function should be used, and not the default function
    ---     houses: the houses that the player has or an empty array / table if the player has no houses
    --- houses format: { {label: string, name: string, house: string}, {label: string, name: string, house: string} } 
    return false, {}
end

---Called when the player wants to spawn at a house
---@param house NAMESPACE.META.House the house to spawn at
---@return boolean used true if this function should be used, and not the default
function OpenFunc.client.spawnAtHouse(house)
    --- return:
    ---     used: true if this function should be used, and not the default
    return false
end

---loads the apartments of the player in case a custom housing system is used.
---@nodiscard
---@return boolean used true if this function should be used, and not the default function
---@return NAMESPACE.META.Apartment[] apartments a list of apartments of this player
function OpenFunc.client.loadApartments()
    return false, {}
end

---Called when the player wants to spawn at an apartment
---@param apartment NAMESPACE.META.Apartment the apartment to spawn at
function OpenFunc.client.spawnAtApartment(apartment)
    return false
end

---Called when the UI gets activated / dactivated and should hide the hud
---with UI, map, etc.
---@param bool boolean if set to true, the UI should be hidden, if not the UI should be visible
function OpenFunc.client.hideHud(bool) end

OpenFunc.server = {}


---Forces the UI to stay hidden or not<br>
---can be used with `exports["forge-spawn"]:forceHide(true)` or `exports["forge-spawn"]:forceHide(false)`
---@param hide boolean if set to true the UI will be hidden, if not the UI will be visible, IF the UI would be visibile in the current situation
exports("forceHide", function(hide)
    CLIENT.UI.ForceHide(hide)
end)
```

{% endtab %}
{% endtabs %}

{% hint style="success" %}
**If you want to edit the aesthetics or design. You have the HTML open so you can modify the style and everything as you want.**

The script is **RESPONSIVE** for all resolutions as well.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://codeforge.gitbook.io/codeforge/sleek-series/sleek-spawn-selector.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
