Apartments replaces qb-apartments rather than running beside it. It answers the same events and reads the same table, so the scripts around it — character menus, spawn selectors, phones — keep working. This page covers removing the old script, keeping the apartments your players already own, and updating an older Apartments without losing anything.
What Apartments Takes Over#
From qb-apartments or Qbox | In Apartments |
|---|---|
The resource names | Provided by |
| Handled. On QBCore it opens qb-spawn with your buildings; on Qbox it shows a menu of buildings. |
| Same arguments: building, label, and whether it is the first spawn. |
The | Kept, so a player who logs out at home logs back in at home. |
The | Same core columns, plus the stash, wardrobe and charger points and the vault codes. |
|
|
Removing the Old Script#
Stop and delete it
Remove
qb-apartments— orqbx_properties/qbx_apartmentson Qbox — from your resources folder, and itsensureline fromserver.cfg. Apartments prints a repeating error for as long as a resource namedqbx_propertyis started.Keep the table
Do not import
database.sqlas a whole — its first line dropsplayer_apartments. Run the block in Updating an Existing Database below instead.Point the rows at your buildings
Follow Keeping Your Players' Apartments so every existing apartment belongs to a building Apartments knows.
Keeping Your Players' Apartments#
Each row in player_apartments points at a building through its type column, and that value must be a key of Config.ApartmentCatalog. qb-apartments calls its five buildings apartment1 to apartment5; Apartments ships the same five buildings under new keys:
qb-apartments | Apartments | Building |
|---|---|---|
|
| South Rockford Drive |
|
| Morningwood Blvd |
|
| Integrity Way |
|
| Tinsel Towers |
|
| Fantastic Plaza |
Pick one of two ways to line them up:
Rewrite the old keys to the new ones once, then use the shipped catalogue as it is:
UPDATE player_apartments SET type = 'sr_drive_a' WHERE type = 'apartment1';
UPDATE player_apartments SET type = 'morningwood_blvd_b' WHERE type = 'apartment2';
UPDATE player_apartments SET type = 'integrity_way_c' WHERE type = 'apartment3';
UPDATE player_apartments SET type = 'tinsel_towers_d' WHERE type = 'apartment4';
UPDATE player_apartments SET type = 'fantastic_plaza_e' WHERE type = 'apartment5';Rename the catalogue entries in config/main.lua instead. Change the key and its name together:
Config.ApartmentCatalog = {
['apartment1'] = {
name = 'apartment1',
label = 'South Rockford Drive',
-- ...the rest of the entry unchanged
},
}The apartment's ID — the name column, such as apartment14821 — does not change. Apartments opens the stash under that same ID, so with the same inventory as before, what players kept in their apartment is still there.
A row whose
typeis not in the catalogue cannot be entered. Check what you have withSELECT type, COUNT(*) FROM player_apartments GROUP BY type;before your first start.
Updating an Existing Database#
Whether you come from qb-apartments or from an older Apartments, run this instead of the whole file. It only adds what is missing and never removes a row:
ALTER TABLE player_apartments ADD COLUMN IF NOT EXISTS `stash` TEXT NULL DEFAULT NULL;
ALTER TABLE player_apartments ADD COLUMN IF NOT EXISTS `wardrobe` TEXT NULL DEFAULT NULL;
ALTER TABLE player_apartments ADD COLUMN IF NOT EXISTS `charge` TEXT NULL DEFAULT NULL;
ALTER TABLE player_apartments ADD COLUMN IF NOT EXISTS `vaultCodes` LONGTEXT NULL DEFAULT NULL;
CREATE TABLE IF NOT EXISTS `apartment_decorations` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`apartmentId` VARCHAR(50) NULL DEFAULT NULL,
`creator` VARCHAR(70) NOT NULL DEFAULT '0',
`modelName` VARCHAR(50) NOT NULL DEFAULT '0',
`coords` TEXT NULL DEFAULT NULL,
`rotation` TEXT NOT NULL DEFAULT '',
`inStash` TINYINT(1) NOT NULL DEFAULT '0',
`created` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `id` (`id`, `apartmentId`) USING BTREE
) COLLATE='utf8mb3_general_ci' ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `qs_apartment_furnitures` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`creator` VARCHAR(80) NULL DEFAULT NULL,
`category_key` VARCHAR(100) NOT NULL,
`object` VARCHAR(200) NOT NULL,
`label` VARCHAR(255) NOT NULL,
`description` TEXT NULL DEFAULT NULL,
`price` INT(11) NOT NULL DEFAULT '0',
`img` TEXT NULL DEFAULT NULL,
`colorlabel` VARCHAR(255) NULL DEFAULT NULL,
`type` VARCHAR(50) NULL DEFAULT NULL,
`stash` LONGTEXT NULL DEFAULT NULL,
`offset` LONGTEXT NULL DEFAULT NULL,
`colors` LONGTEXT NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `creator` (`creator`) USING BTREE,
INDEX `category_key` (`category_key`) USING BTREE
) COLLATE='utf8mb4_unicode_ci' ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `qs_apartment_junk` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`house` VARCHAR(255) NOT NULL,
`model` VARCHAR(255) NOT NULL,
`coords` LONGTEXT NULL DEFAULT NULL,
`created_at` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP(),
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_house` (`house`) USING BTREE
) COLLATE='utf8mb4_unicode_ci' ENGINE=InnoDB;Updating Apartments#
Back up what you changed
Copy
config/, any bridge you edited underclient/custom/orserver/custom/, your locale edits, andshell_offsets.json— it holds every exit door you placed.Replace the folder
Swap in the new
qs-apartments, then carry your values over by comparing files rather than overwriting them: a new version can add settings your old file does not have.Update the database and restart
Run the block above, start the server and read the console for the
Furniture Creator initializedline.
Your players' data lives in the database, not in the folder. Replacing
qs-apartmentsnever touches apartments, furniture, vault codes or the pieces added with the Furniture Creator. The only file the game itself writes into the folder isshell_offsets.json.



