How Integrations Work#
Nothing inside Apartments is tied to one framework, inventory or clothing script. Each one is reached through a small, open bridge file under client/custom/ or server/custom/, and the right one is picked at start-up by looking at what is already running.
Layer | Supported | Without it |
|---|---|---|
Framework |
| Nothing works, and |
Inventory |
| Stashes cannot open. |
Clothing |
| A fallback wardrobe: qb-clothing's outfit menu on QBCore and Qbox. On ESX, install one of the supported scripts. |
Target |
| Floating prompts and a keypress. |
Text UI |
| Plain drawn 3D text. |
Spawn |
| No apartment at spawn; players use |
Phone | A phone that handles | The Charge point does nothing. |
Quests |
| No apartment quests. |
Weather sync |
| Nothing to pause. |
HUD |
| Only the radar is hidden while decorating. |
Sounds |
| Doors, doorbell, stash and wardrobe are silent. |
Anti-cheat | FiveGuard, with | Nothing to tell — or an anti-cheat may flag the decoration camera. |
Database |
| Required. The only one. |
Run one resource per layer. Detection checks which resources are started, not an order of preference, so with two inventories or two clothing scripts running the pick is not guaranteed. Set it by hand instead, as below.
Overriding Detection#
Each layer is one line in config/main.lua. Replace the detection with the name of the bridge you want — the file name under client/custom/inventory/ or client/custom/wardrobe/, without .lua:
-- Auto, the default
Config.Inventory = DependencyCheck(inventories) or 'default'
Config.Wardrobe = DependencyCheck(wardrobes) or 'default'
-- Manual: skip detection
Config.Inventory = 'ox_inventory'
Config.Wardrobe = 'illenium-appearance'This is also how to use a bridge that ships without detection: client/custom/wardrobe/mAppearance.lua works with Config.Wardrobe = 'mAppearance'.
Inventories and Stashes#
Every stash — the apartment's own and each piece of storage furniture — is opened through the inventory bridge, with its name and size:
Inventory | Notes |
|---|---|
| The stash is registered on the server the first time it is opened, with its slots and weight. |
| Opened with its slots and weight. |
| The bridge sends |
| The size comes from core_inventory's own stash settings. |
| Stashes are named |
| Opened with its weight; slots follow Chezza's settings. |
qb-inventory without Quasar Housing — open the stash through Apartments' own server event, which calls qb-inventory's export:
-- client/custom/inventory/qb-inventory.lua
function OpenStash(customData, uniq)
local house = CurrentApartmentId
uniq = (uniq or house):gsub('-', '_')
TriggerServerEvent('apartments:server:openStash', uniq)
endFor an old qb-inventory (before 2.0), the bridge already holds the two lines to uncomment instead.
Clothing and the Wardrobe#
The wardrobe point and wardrobe furniture call one function, openWardrobe(), from the detected bridge in client/custom/wardrobe/. Each bridge is a few lines that open that script's own outfit menu — adjust it there if your version renamed an export or event.
A new character's first spawn opens the character creator through TriggerCharacterCreation() in config/main.lua. It fires qb-clothing's first-character event; point it at your clothing script's own:
function TriggerCharacterCreation()
TriggerEvent('qb-clothes:client:CreateFirstCharacter')
endTargets#
With Config.UseTarget = true, prompts become target entries:
Where | Entries |
|---|---|
A building's door | Enter Apartment for the owner; Move Apartment and Ring Doorbell for everybody else. |
The apartment door | Exit Apartment; Doorbell after a ring; Locations with |
The stash and wardrobe points | Stash and Set Vault Code; Wardrobe. |
Interactive furniture | Interact with object and Set Vault Code. |
The cleaning robot | Start Cleaning Robot, Stop Cleaning Robot, Return to Dock. |
Doors, points and furniture are added through the qtarget API, which ox_target answers out of the box; the robot is registered with ox_target or qb-target directly. The bridge is client/custom/target/main.lua, and Config.ZoneDebug = true draws the boxes.
Spawn Selectors and Starter Apartments#
Quasar Multicharacter reads your buildings from Apartments' export and shows them in its spawn selector to new characters, on any framework. Choosing one creates the apartment and walks the character in. Start Apartments before Multicharacter so it is found.
With qb-multicharacter and qb-spawn, choosing a character fires apartments:client:setupSpawnUI:
A character with an apartment gets qb-spawn's normal list and their home blip.
A new character gets qb-spawn with your buildings when
Config.InitialSpawnEnabledistrue, or the normal list when it isfalse.
Apartments shows an Apartment Menu of your buildings to a new character. Picking one creates the apartment, spawns the character inside and fires the player-loaded events, so the clothing menu opens. A returning character goes to the spawn selector as usual. Remove qbx_properties first.
Any spawn or character script can hand out a starter apartment with the event the built-in menus use — see Commands and Exports. Without one, players claim theirs with /Apartment.
Phone Charger#
When an owner places the Charge point, Apartments fires the server event phone:CreateChargeLocation on the server, with the apartment ID and the position, for your phone script to put a charging spot there. A phone that does not handle that event ignores the point.
-- server side, in your phone resource
AddEventHandler('phone:CreateChargeLocation', function(apartmentId, coords)
-- coords = { x = ..., y = ..., z = ... }
end)Advanced Inventory Quests#
With qs-inventory running, every player is given two quests when they load in:
Quest | Goal | Progress | Reward |
|---|---|---|---|
First Apartment Setup | Buy at least 5 furniture items. | +20 per piece bought | 200 |
New Place, New Vibes | Move to a different apartment location. | Complete on the first apartment paid for | 250 |
Their titles, descriptions and rewards are in server/custom/missions.lua. Without qs-inventory the file does nothing.
Weather, HUD, Sounds and Anti-cheat#
Hook | Where | What it does |
|---|---|---|
Weather sync |
| Pauses qb-weathersync, cd_easytime and vSync on the way in and resumes them on the way out. Add your own sync's events to the same function. |
HUD |
| Hides the radar and qs-interface while decorating and in the Furniture Creator. Add your HUD's own hide call there. |
Sounds |
| Plays |
FiveGuard |
| Set it to your FiveGuard resource name: while a player decorates, they get FiveGuard's temporary free-camera and noclip bypass, so the camera is not flagged. |
Notifications#
Messages are shown in Apartments' own notification style, inside its interface. To send them through another system, edit Notification(msg, type) in client/custom/framework/esx.lua or qb.lua — commented examples for qs-interface and ox_lib are already there. type is info, success or error.
Adding a Backend#
Supporting an inventory or clothing script that is not on the list takes one file plus one line.
Copy the closest bridge
Every bridge is a small, unencrypted file. Copy the one nearest to yours —
client/custom/inventory/ox_inventory.lua, say — and name it after your resource.Change the guard and the call
The first line makes the file run only when it is the chosen bridge; the function underneath calls your resource:
lua if Config.Inventory ~= 'my_inventory' then return end function OpenStash(customData, uniq) local data = customData or Config.DefaultStashData uniq = (uniq or CurrentApartmentId):gsub('-', '_') -- call your inventory's own stash export or event here, -- with uniq, data.slots and data.maxweight endRegister it for detection
Add one entry to the
inventorieslist inconfig/main.lua—['my_inventory'] = 'my_inventory'— or setConfig.Inventoryto it by hand.
A clothing bridge is the same with one function, openWardrobe(), and the wardrobes list. The framework bridges in server/custom/framework/ and client/custom/framework/ hold identifiers, money, metadata, routing buckets and the admin check.
Languages#
41 translations ship in locales/: ar, bg, bn, ca, cs, da, de, el, en, es, et, fa, fi, fr, he, hi, hr, hu, id, it, ja, ko, lt, lv, ms, nl, no, pl, pt, ro, ru, sk, sl, sv, sw, th, tr, uk, ur, vi, zh. Set Config.Locale in config/main.lua. To add another, copy en.json to the new code, translate it and set the locale to that code — anything left untranslated falls back to English, and the console names each missing key.



