Installation
This guide will walk you through installing prp-housing-v2 on your FiveM server.
Installation steps
prp-housing-v2 from the CFX portal and place it in your resources folder. You also need the Housing Pack shells (prp-housing-loader, prp-housing-main, prp-housing) for interior assets.ensure ox_lib
ensure oxmysql
ensure ox_doorlock
ensure prp-bridge
ensure prp-housing-loader
ensure prp-housing-main
ensure prp-housing
ensure prp-housing-v2 ox_doorlock must start before prp-housing-v2.ox_doorlock automatically on first start — see ox_doorlock below.Housing shells
The housing script does not include MLO interiors. Install the Housing Pack separately and ensure shell resources start before prp-housing-v2.
Garages
Start one supported garage resource before or with housing. Detection and placement: Garages. Almost all Lua is editable — Editable files.
Items
Add all required items to your inventory resource. HousingBridge.registerItem is a no-op in the bridge adapter — items must be defined manually.
lockpick
If your inventory already ships with a default lockpick item (common with ox_inventory), remove that entry before using the definitions below. The default item registers its own use handler (e.g. vehicle lockpicking) and will conflict with housing door lockpicking.
Add the items below to your ox_inventory into data/items.lua.
["placeable_furniture_item"] = {
label = "Placeable Furniture",
weight = 1000,
stack = false,
close = true,
consume = 0,
},
["collectable_furniture_item"] = {
label = "Collectable Furniture",
weight = 1000,
stack = false,
close = true,
consume = 0,
},
["master_key"] = {
label = "Master Key",
weight = 200,
stack = false,
},
["lockpick"] = {
label = "Lockpick",
weight = 160,
},
["improved_lockpick"] = {
label = "Improved Lockpick",
weight = 160,
},
["expert_lockpick"] = {
label = "Expert Lockpick",
weight = 160,
},Real estate tablet
If you enable the real estate panel (Config.RealEstate), add the usable item that opens it (default name realtor_tablet). Example for ox_inventory (data/items.lua):
["realtor_tablet"] = {
label = "Realtor Tablet",
weight = 1000,
stack = false,
close = true,
},Only players allowed by Config.HousingStaff (mode + jobs) and admins (when mode permits) can open the panel — using the item without permission shows an error. Staff can also use the real estate radial when enabled. See Real estate.
Furniture item metadata
When a player receives a placeable_furniture_item or collectable_furniture_item, the item metadata must include:
| Field | Type | Description |
|---|---|---|
model | string | Prop model name (e.g. pr_furniture_chair_01) |
category | string | Furniture category from the catalog |
Using the item from inventory opens the placement mode for that model.
ox_doorlock
Exterior property doors use ox_doorlock (same pattern as prp-outposts). Doors are locked by default (state: 1). Lock/unlock from housing target options calls ToggleHousingDoor in server/editable.lua.
Automatic registration
On first start (and when new locations are created), prp-housing-v2 inserts missing rows into ox_doorlock:
| Field | Value |
|---|---|
| Name | housing_loc_{locationId}_door_{doorIndex} |
| Data | model, coords, heading, state: 1, hideUi: true, lockpick: false |
Example for location 403:
INSERT INTO `ox_doorlock` (`name`, `data`) VALUES (
'housing_loc_403_door_1',
'{"model":-514036887,"coords":{"x":960.0,"y":-669.0,"z":58.0},"heading":0.0,"state":1,"maxDistance":2,"hideUi":true,"doors":false,"lockpick":false,"autolock":false}'
);A reference file is included at sql/housing_doorlock.sql. After bulk inserts on first boot, the script reloads ox_doorlock once so clients receive all doors.
Configuration
In config/sh_config.lua:
Config.Doorlock = {
enabled = true,
openOnAccess = true,
namePrefix = "housing_loc",
maxDistance = 2.0,
hideUi = true,
holdOpen = true,
defaultHeading = 0.0,
autolock = false,
}| Option | Default | Description |
|---|---|---|
enabled | true | Sync exterior doors to ox_doorlock |
openOnAccess | true | With access, door interact opens the door |
Set enabled = false only if you use a custom lock handler in server/editable.lua without ox_doorlock.
Custom lock resource
Swap only ToggleHousingDoor(doorName, doorState) in server/editable.lua — doorState is true locked / false unlocked.
Database
The required tables are created automatically on first server start:
CREATE TABLE IF NOT EXISTS `world_housing_locations` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`property_name` VARCHAR(100) NULL,
`property_price` INT DEFAULT 0 NULL,
`property_zone` LONGTEXT NULL,
`property_settings` LONGTEXT NULL,
`interior_type` VARCHAR(16) DEFAULT 'mlo' NOT NULL,
`shell_id` VARCHAR(128) NULL,
`exterior_coords` LONGTEXT NULL,
`interior_location` LONGTEXT DEFAULT '{}' NULL,
`doors` LONGTEXT NULL,
`property_seller` VARCHAR(50) NULL,
`property_sale_data` LONGTEXT NULL,
`time_added` TIMESTAMP DEFAULT CURRENT_TIMESTAMP() NULL
) CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `world_housing` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`location_id` INT NOT NULL,
`owner` VARCHAR(50) NOT NULL,
`upgrades` LONGTEXT DEFAULT '{}' NOT NULL,
`settings` LONGTEXT DEFAULT '{}' NULL,
`time_bought` TIMESTAMP DEFAULT CURRENT_TIMESTAMP() NULL
) CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `world_housing_access` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`housing_id` INT NOT NULL,
`stateId` VARCHAR(50) NOT NULL,
`character_privileges` LONGTEXT DEFAULT '{}' NOT NULL,
`access_gained` TIMESTAMP DEFAULT CURRENT_TIMESTAMP() NULL,
FOREIGN KEY (`housing_id`) REFERENCES `world_housing` (`id`) ON DELETE CASCADE
) CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `world_housing_furniture` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`housing_id` INT NULL,
`placer_id` VARCHAR(50) NULL,
`furniture_data` LONGTEXT NOT NULL,
`furniture_health` INT DEFAULT 100 NOT NULL,
`furniture_placed` TIMESTAMP DEFAULT CURRENT_TIMESTAMP() NULL,
FOREIGN KEY (`housing_id`) REFERENCES `world_housing` (`id`) ON DELETE CASCADE
) CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `world_housing_garages` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`housing_id` INT NULL,
`access_location` LONGTEXT NOT NULL,
`vehicle_location` LONGTEXT NULL,
`time_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP() NULL,
FOREIGN KEY (`housing_id`) REFERENCES `world_housing` (`id`) ON DELETE CASCADE
) CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;Additional tables (world_housing_mdt, world_housing_rent, etc.) are created on first start. A full reference schema is in sql/housing_schema.sql.
The interior_type, shell_id, and exterior_coords columns drive shell properties (interior_type = 'shell'). MLO properties keep the default 'mlo'.
Fresh install only
prp-housing-v2 creates its tables from scratch and ships no migrations. The schema is treated as greenfield: if you change it during setup, drop and recreate the housing tables rather than expecting an in-place upgrade.