# Starter Apartments

{% hint style="success" %}
Starter apartments let you automatically **assign a default apartment** to newly created characters and (optionally) **teleport** them inside right after creation.

This guide shows:

* how to configure starter apartments in `config.lua`
* where to call the server export to assign the apartment
* how to teleport the player after character creation (client export)
* examples for **ESX**, **qb-multicharacter**, and **qbx\_core**

✅ Works with **any framework** — you only need a place in your character creation flow where you can run the exports.
{% endhint %}

{% stepper %}
{% step %}

### Configure Starter Apartments (config.lua)

#### Create an Apartment Complex (required)

Starter apartments require an **apartment complex / building** (a “container” for starter units).

* Open the **Property Creator** (`/propertycreator`)
* Create an **Apartment Complex / Building**
* Save it
* Open your database and copy the **houseId / id** of the created complex
* Paste that value into `Config.StarterApartments.complexid`

{% hint style="info" %}
The complex ID is used as the parent building for the starter apartments.
{% endhint %}

#### Set your Starter Apartment configuration

```lua
Config.StarterApartments = { -- Instructions for implementing starter apartments in your multicharacter system can be found in [Dev Tools - Docs]/STARTER APARTMENTS.txt
    complexid = "509507963", -- You must create an apartment complex and enter the complex ID (houseId) from the database here
    apartmenttype = "SHELL", -- Apartment type: SHELL or IPL
    apartmentid = "rtx_housing_shell_1", -- Index from Config.HouseShells or Config.HouseIpls
    apartmenttheme = "modern", -- Theme used for IPL apartments only
    furnitureinside = true, -- Enable if players are allowed to place furniture inside the apartment
    wardrobe = true, -- Enable if the apartment includes a wardrobe
    storage = true, -- Enable if the apartment includes storage
    storagedata = {
        slots = 40,       -- Number of storage slots
        weight = 100000, -- Maximum storage weight (depends on your inventory system)
    },
    cantransfer = false, -- Enable if players are allowed to transfer the starter apartment
    cansell = false, -- Enable if players are allowed to sell the starter apartment
    sellprice = 0, -- Sell price (usually 0 for starter apartments)
    canlist = false, -- Enable if players are allowed to list the apartment on the market
}
```

**Quick notes**

* **SHELL:** `apartmentid` must exist in `shells.lua` (`Config.HouseShells`)
* **IPL:** `apartmentid` must exist in `ipls.lua` (`Config.HouseIpls`) and you can set `apartmenttheme`
* If you change/remove the interior later, do it carefully to avoid orphaned properties
  {% endstep %}

{% step %}

### Give Starter Apartment (server-side)

This is the **server export** you call once — right after a new character is created:

```lua
exports["rtx_housing"]:GiveStarterApartment(source)
```

#### When should I call it?

Call it only for **new characters** (first time creation). Most frameworks provide an `isNew` flag or similar logic.

#### ESX (es\_extended)

**File:** `es_extended/server/main.lua`\
**Function:** `loadESXPlayer` (or `LoadESXPlayer`, depends on version)

1. Find the function that loads the player
2. At the end of the function, after the player is fully loaded, add:

```lua
if isNew then
    exports["rtx_housing"]:GiveStarterApartment(playerId)
end
```

<details>

<summary><strong>Example code (ESX) — expanded snippet</strong></summary>

```lua
-- ... inside loadESXPlayer(...)

TriggerEvent("esx:playerLoaded", playerId, xPlayer, isNew)
xPlayer.triggerEvent("esx:playerLoaded", userData, isNew, userData.skin)

-- Give starter apartment only to new characters
if isNew then
    exports["rtx_housing"]:GiveStarterApartment(playerId)

    -- Optional: teleport after a short delay (recommended)
    Citizen.Wait(1500)
    exports["rtx_housing"]:TeleportPlayerToStartingApartment(playerId)
end
```

</details>

#### QBCore (qb-multicharacter)

**File:** `qb-multicharacter/server/main.lua`\
**Function:** `GiveStarterItems`

1. Find `GiveStarterItems`
2. Add the export at the end:

```lua
exports["rtx_housing"]:GiveStarterApartment(src)
```

<details>

<summary><strong>Example code (qb-multicharacter) — expanded snippet</strong></summary>

```lua
local function GiveStarterItems(source)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)

    for _, v in pairs(QBCore.Shared.StarterItems) do
        local info = {}
        -- ... existing starter items logic ...
        exports['qb-inventory']:AddItem(src, v.item, v.amount, false, info, 'qb-multicharacter:GiveStarterItems')
    end

    -- Give starter apartment
    exports["rtx_housing"]:GiveStarterApartment(src)
end
```

</details>

#### QBox / qbx\_core

**File:** `qbx_core/server/character.lua`\
**Function:** `giveStarterItems`

Add at the end of the function:

```lua
exports["rtx_housing"]:GiveStarterApartment(source)
```

<details>

<summary><strong>Example code (qbx_core) — expanded snippet</strong></summary>

```lua
local function giveStarterItems(source)
    if GetResourceState('ox_inventory') == 'missing' then return end

    while not exports.ox_inventory:GetInventory(source) do
        Wait(100)
    end

    for i = 1, #starterItems do
        local item = starterItems[i]
        if item.metadata and type(item.metadata) == 'function' then
            exports.ox_inventory:AddItem(source, item.name, item.amount, item.metadata(source))
        else
            exports.ox_inventory:AddItem(source, item.name, item.amount, item.metadata)
        end
    end

    -- Give starter apartment
    exports["rtx_housing"]:GiveStarterApartment(source)
end
```

</details>
{% endstep %}

{% step %}

### Teleport player to Starter Apartment (client-side)

This is the **client export** you can call after character creation / skin creation:

```lua
exports["rtx_housing"]:TeleportPlayerToStartingApartment()
```

#### Recommended usage

* Call it **after** the character is created and spawned
* If you call teleport too early, the player may not be fully initialized

#### ESX Multicharacter (example)

<details>

<summary><strong>Example code (esx_multicharacter) — teleport after skin creator</strong></summary>

```lua
function Multicharacter:LoadSkinCreator(skin)
    TriggerEvent("skinchanger:loadSkin", skin, function()
        exports["rtx_housing"]:TeleportPlayerToStartingApartment()

        DoScreenFadeIn(600)
        SetPedAoBlobRendering(self.playerPed, true)
        ResetEntityAlpha(self.playerPed)

        TriggerEvent("esx_skin:openSaveableMenu", function()
            Multicharacter.finishedCreation = true
        end, function()
            Multicharacter.finishedCreation = true
        end)
    end)
end
```

</details>

#### qb-multicharacter (example)

**File:** `qb-multicharacter/client/main.lua`

<details>

<summary><strong>Example code (qb-multicharacter) — teleport on spawn event</strong></summary>

```lua
RegisterNetEvent('qb-multicharacter:client:closeNUIdefault', function()
    -- ... existing spawn logic ...

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

    -- Teleport to starter apartment
    exports["rtx_housing"]:TeleportPlayerToStartingApartment()
end)
```

</details>

#### qbx\_core (example)

<details>

<summary><strong>Example code (qbx_core) — teleport on spawn event</strong></summary>

```lua
RegisterNetEvent('qbx_core:client:spawnNoApartments', function()
    -- ... existing spawn logic ...

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

    -- Teleport to starter apartment
    exports["rtx_housing"]:TeleportPlayerToStartingApartment()
end)
```

</details>
{% endstep %}

{% step %}

### Global explanation (for any framework)

You only need two things:

#### Give the apartment (server-side)

Call once for new characters:

```lua
exports["rtx_housing"]:GiveStarterApartment(source)
```

#### Teleport (client-side)

Call after character/spawn is finished:

```lua
exports["rtx_housing"]:TeleportPlayerToStartingApartment()
```

✅ This works for **any framework**.\
Just place these calls into the correct “new character created” and “player spawned” moments.

***

### Need help?

If you want, **we can implement the integration for you**.\
Contact us on Discord: <https://discord.gg/rtxdev>
{% endstep %}
{% endstepper %}


---

# 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://rtx-dev.gitbook.io/rtxdev/rtx-housing-system/guides/starter-apartments.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.
