Skip to content

Housing: config files ​

These files stay readable in every build (escrow too), so you can change them. Shown as shipped in version 1.2.2.

config.lua ​

lua
-- ============================================================================
--  Lumo Housing · configuration
--  Everything a server owner normally changes is in this file. Shell models
--  are in data/shells.lua, base-game interiors in data/interiors.lua, texts in
--  locales/. Houses themselves are made in game with /housecreator.
-- ============================================================================
Config = {}

-- 'auto' detects Qbox, QBCore, ESX or none (standalone).
Config.Framework = 'auto'      -- 'auto' | 'qbx' | 'qb' | 'esx' | 'standalone'
-- Interaction: 'auto' = lumo-interact, then a real qb-target, then ox_target, else a built-in [E] prompt.
Config.Target = 'auto'         -- doors: 'auto' | 'lumo-interact' | 'qb' | 'ox' | 'none' (key prompts)
Config.TargetObjects = 'auto'  -- pets, furniture (storage, wardrobe, bed…), the realtor: 'auto' = lumo-interact, else a qb-target / ox_target eye menu
-- House storage. 'auto' = lumo-inventory, ox_inventory, qb-inventory, then the older
-- qb-style inventory events (ps-inventory, lj-inventory). 'custom' = Config.Hooks.openStash.
Config.Inventory = 'auto'      -- 'auto' | 'lumo-inventory' | 'ox_inventory' | 'qb-inventory' | 'qb-legacy' | 'custom'
-- Wardrobe. 'auto' = lumo-clothing, illenium-appearance, qb-clothing. 'custom' = Config.Hooks.openWardrobe.
Config.Wardrobe = 'auto'       -- 'auto' | 'lumo-clothing' | 'illenium-appearance' | 'qb-clothing' | 'custom'

Config.Locale = 'en'
Config.Debug = false           -- true: /housecoords and extra console output

-- NUI look: 'auto' follows lumo-ui's HUD preset (Classic = lime, Circle = white),
-- or pin 'classic' / 'circle'.
Config.Theme = 'auto'
Config.HideHud = true          -- hide the HUD and minimap while a housing panel is open

-- House tours: anyone may look round a shell / interior home on the market before buying
-- ("Take a tour" at the door or on the deed). The tour ends at the front door.
Config.Tour = {
    enabled = true,
    minutes = 3,               -- 0 = no time limit
    key = 'BACK',              -- ends the tour early; players can rebind it (Settings → Key Bindings → FiveM)
}

-- Who counts as an admin (/housecreator). Framework groups, or the ACE below.
Config.Admin = {
    permissions = { 'admin', 'god' },
    ace = 'lumohousing.admin',
}

-- Realtors: players with one of these jobs may open the house creator (/housecreator) to list
-- new houses and edit existing ones, without admin rights. Deleting houses, evicting owners
-- and teleporting stay with admins unless switched on here.
Config.Realtor = {
    jobs = { realestate = 0 },  -- job = lowest grade allowed; {} = admins only
    onDuty = true,              -- must be on duty
    canDelete = false,
    canEvict = false,
    maxPrice = 0,               -- highest price / rent a realtor may set (0 = no limit)
    -- Commission on a sale: paid to the realtor who showed the buyer round (a showing in the
    -- last showingHours), else to the realtor who listed the house (bank sales only).
    commissionPercent = 3,      -- of the sale price; 0 = off
    commissionFromSeller = false, -- player sales: true = taken from the seller's money, false = paid by the agency
    showingHours = 24,
    showingMinutes = 20,        -- a showing stays open this long; anyone at the door may join it
    desk = 'realtor',           -- command for the realtor desk (requests, market, auctions, earnings); '' = off
}

-- Open house: the owner (or a realtor) opens a listed home to everyone for a while.
-- Visitors walk in without a tour timer; the browser and map show it.
Config.OpenHouse = { enabled = true, hours = 2, blip = { sprite = 492, colour = 5, scale = 0.7 } }

-- For Sale / Sold signs by the entrance of houses on the market (client props, nobody else's).
Config.Signs = {
    enabled = true,
    model = 'prop_forsale_sign_01',
    distance = 80.0,            -- shown this close
    offset = 2.5,               -- metres in front of the door
    soldDays = 2,               -- "SOLD" shows this long after a sale
}

-- ── Bills and insurance ─────────────────────────────────────────────────────
-- Utilities fall due every periodDays and are taken from the owner's account when online.
-- Left unpaid graceDays: the power is cut (no rest, cooking, TV, music or party) until paid.
Config.Bills = {
    enabled = true,
    periodDays = 7,
    graceDays = 4,
    base = { shell = 120, ipl = 220, mlo = 350 },  -- per period
    perPiece = 2,               -- plus this per placed piece of furniture
    perUpgrade = 25,            -- plus this per security upgrade (alarm, camera, smart lock)
}

-- Home insurance: a premium every periodDays; a break-in pays out once per cooldown.
Config.Insurance = {
    enabled = true,
    premiumPercent = 0.4,       -- of the market value, per period
    periodDays = 7,
    payoutPercent = 4,          -- of the market value
    cooldownHours = 24,
}

-- ── People ──────────────────────────────────────────────────────────────────
-- Rent out a room: the roomer gets a key and pays the owner every periodDays.
Config.Roomers = { enabled = true, max = 3, periodDays = 7, graceDays = 2, maxRent = 100000 }
-- Co-owners: share a home. They manage keys, bills and security and decorate; only the owner sells.
Config.CoOwners = { enabled = true, max = 2 }

-- Market value (Manage → Home): the house price plus what was put into it.
Config.Valuation = {
    furniturePercent = 50,      -- of what the placed furniture cost
    upgradePercent = 60,        -- of what upgrades cost
    garagePercent = 5,          -- of the house price, when it has a garage
    listingPercent = 110,       -- suggested listing price, of the market value
}

-- Auctions: repossessed homes (mortgage unpaid) go to auction; realtors may auction bank houses.
-- Bids are held: an outbid player gets the money back at once.
Config.Auction = {
    enabled = true,
    hours = 24,
    startPercent = 60,          -- opening bid, of the list price
    stepPercent = 5,            -- each bid at least this much over the last one
    repossessed = true,         -- mortgage defaults go to auction instead of straight back to the bank
    extendMinutes = 5,          -- a bid in the last minutes pushes the end back this far
}

-- ── Security (Manage → Security; stays with the home when sold) ─────────────
Config.Security = {
    alarm = { price = 15000 },      -- break-ins call the police and tell the owner
    camera = { price = 9000 },      -- a camera on every door, watched at a placed monitor; logs who comes to the door
    safe = { price = 22000, slots = 20, weight = 100000 }, -- the safe is a placed piece (kind 'safe'); price is unused
    smartlock = { price = 12000, maxCodes = 6, maxHours = 72 }, -- keypad with guest codes
    breakIn = {
        enabled = true,
        items = { 'lockpick', 'advancedlockpick' }, -- needs one of these
        breakChance = 35,           -- % the pick breaks on a failed attempt
        cooldownMinutes = 30,       -- per home
        policeJobs = { police = 0, sheriff = 0, bcso = 0 },
        dispatchCode = '10-31',
        safeCrack = true,           -- burglars may try the safe (dial minigame)
    },
}

-- ── Living ──────────────────────────────────────────────────────────────────
-- Rest at home (in-home menu): takes stress off and heals a little.
-- Resting happens in a placed bed (kind 'bed': E rest, G sleep / log out).
Config.Rest = { enabled = true, seconds = 12, stress = 25, health = 30, cooldownMinutes = 20 }

-- Cooking at a cooker piece of furniture (kind 'cooker').
Config.Cooking = {
    enabled = true,
    recipes = {
        { key = 'sandwich', label = 'Sandwich', give = 'sandwich', count = 1, seconds = 6, needs = { bread = 1, cheese = 1 } },
        { key = 'tosti', label = 'Toastie', give = 'tosti', count = 1, seconds = 8, needs = { bread = 1, cheese = 1 } },
        { key = 'burger', label = 'Burger', give = 'burger', count = 1, seconds = 12, needs = { bread = 1, meat = 1, lettuce = 1 } },
        { key = 'steak', label = 'Steak', give = 'steak', count = 1, seconds = 14, needs = { meat = 1, potato = 1 } },
        { key = 'chicken_meal', label = 'Chicken dinner', give = 'chicken_meal', count = 1, seconds = 14, needs = { chicken = 1, rice = 1 } },
        { key = 'chickenwrap', label = 'Chicken wrap', give = 'chickenwrap', count = 1, seconds = 10, needs = { chicken = 1, lettuce = 1, flour = 1 } },
        { key = 'pizza', label = 'Pizza', give = 'pizza', count = 1, seconds = 18, needs = { flour = 1, tomato = 1, cheese = 1 } },
        { key = 'fish_chips', label = 'Fish and chips', give = 'fish_chips', count = 1, seconds = 14, needs = { fish = 1, potato = 1 } },
    },
}

-- TV and music (furniture kinds 'tv' and 'speaker'). Links from these hosts only.
-- YouTube links play on TVs (on the screen) and speakers; mp3/mp4/ogg/webm links play directly.
Config.Media = {
    enabled = true,
    hosts = { 'www.youtube.com', 'youtube.com', 'youtu.be', 'm.youtube.com', 'cdn.discordapp.com', 'files.catbox.moe' },
    range = 18.0,               -- heard this far away
    maxVolume = 100,
}

-- Mailbox at the door: anyone may leave a letter; residents read them in Manage → Mail.
Config.Mail = { enabled = true, max = 30, maxLength = 600, phone = true }

-- Pets live in the home: hunger and happiness fall over time, a placed bowl (kind
-- 'petbowl') feeds them and a pet house or bed (kind 'pethouse') is where they sleep
-- (happiness falls half as fast with one). Residents can take them for a walk; a
-- following pet rides along in the car. `anims` picks the trick set (big/retriever/small/cat).
Config.Pets = {
    enabled = true,
    hungerHours = 24,          -- a full pet is empty after this long
    happyHours = 12,           -- happiness from full to empty
    runAwayDays = 3,           -- starving this long and the pet leaves (0 = never)
    minHunger = 15,            -- below this a pet will not walk, play or do tricks
    food = { price = 60, portions = 4, item = nil }, -- one bowl fill: money, or one `item` when set
    loveStress = 8, loveCooldownMinutes = 10,        -- petting a happy pet relieves stress
    playCooldownMinutes = 2,
    list = {
        { key = 'husky', label = 'Husky', model = 'a_c_husky', price = 2500, anims = 'big' },
        { key = 'retriever', label = 'Retriever', model = 'a_c_retriever', price = 2500, anims = 'retriever' },
        { key = 'shepherd', label = 'Shepherd', model = 'a_c_shepherd', price = 2500, anims = 'big' },
        { key = 'pug', label = 'Pug', model = 'a_c_pug', price = 1800, anims = 'small' },
        { key = 'poodle', label = 'Poodle', model = 'a_c_poodle', price = 1800, anims = 'small' },
        { key = 'westy', label = 'Westie', model = 'a_c_westy', price = 1800, anims = 'small' },
        { key = 'cat', label = 'Cat', model = 'a_c_cat_01', price = 1200, anims = 'cat' },
    },
}

-- Party mode: the door opens to everyone, the map shows the party, lights go wild.
Config.Party = { enabled = true, hours = 2, blip = { sprite = 614, colour = 27, scale = 0.8 } }

-- Garden: planters (furniture kind 'planter') grow crops from seeds.
Config.Garden = {
    enabled = true,
    minutes = 45,               -- real minutes to grow
    waterItem = 'farm_water_can', -- needed (not used up) to water; nil = no watering
    waterEvery = 20,            -- minutes; a dry plant stops growing
    seeds = {
        seeds_lettuce = { give = 'farm_lettuce', count = 3 },
        seeds_tomato = { give = 'farm_tomato', count = 3 },
        seeds_potato = { give = 'farm_potato', count = 3 },
        seeds_strawberry = { give = 'farm_strawberry', count = 4 },
        seeds_eggplant = { give = 'farm_eggplant', count = 2 },
        seeds_watermelon = { give = 'farm_watermelon', count = 1 },
        seeds_apple = { give = 'farm_apple', count = 3 },
        seeds_wheat = { give = 'farm_wheat', count = 4 },
    },
}

-- ── Showing off ─────────────────────────────────────────────────────────────
-- Home of the week: guests vote for the home they are visiting (one vote a week each).
-- Last week's winner shows in the browser; its owner gets the prize once.
Config.Showcase = { enabled = true, prize = 10000 }
Config.Gallery = { max = 12 }       -- photos per home (Manage → Gallery), shown in the browser
Config.Layouts = { max = 10 }       -- saved decor layouts per player

-- Audit log: creator edits, deletes, evictions, sales, commissions, auctions.
-- Discord webhook: set the convar lumo_housing_webhook (server.cfg) or webhook here.
Config.Audit = { enabled = true, days = 90, webhook = '' }

Config.Commands = {
    browser = 'houses',        -- open the realestate browser anywhere ('' = off)
    creator = 'housecreator',  -- admins: create and edit houses
    decorate = 'decorate',     -- residents: furnish the home you are in ('' = off)
}

-- Housing radial: manage near your entrance or inside; decorate, home menu, lock and leave inside.
-- resource: anything that exports qb-radialmenu's AddOption / RemoveOption.
Config.Radial = {
    enabled = true,
    resource = 'qb-radialmenu',
}

-- The home menu: everything about a home you live in, from anywhere (nearest home,
-- or a picker when you have several). Players can rebind the key in FiveM settings.
Config.Menu = {
    command = 'housemenu',
    key = 'F6',                -- '' = command only
}

-- Money is taken from these accounts, in this order. Standalone servers have no
-- money: every price is free there.
Config.Payment = { 'bank', 'cash' }

-- ── Buying ──────────────────────────────────────────────────────────────────
-- Added on top of the list price when buying from the bank. Percentages.
Config.Purchase = {
    taxPercent = 2,
    brokerPercent = 1,
}

-- ── Selling ─────────────────────────────────────────────────────────────────
Config.Sale = {
    bankPercent = 60,          -- selling back to the bank pays this share of the list price
    playerListings = true,     -- owners may list their house for sale to other players
    minPricePercent = 25,      -- a player listing may not go below this share of the list price
}

-- ── Renting (houses the creator marks as rentable) ──────────────────────────
Config.Rent = {
    periodDays = 7,            -- rent is due every this many days (real time)
    graceDays = 3,             -- unpaid this long past due: the tenancy ends
    autoPay = true,            -- take the rent from the tenant's account when it falls due (online)
}

-- ── Mortgages (buying from the bank or a player on credit) ─────────────────
-- The deed offers "Finance": pay the deposit plus tax and fees today, the rest
-- (plus interest, added once) in equal instalments taken from the owner's account.
-- An instalment unpaid graceDays after it falls due: the bank takes the home back.
-- A home with a mortgage cannot be listed or handed over until it is paid off.
Config.Mortgage = {
    enabled = true,
    depositPercent = 20,       -- of the price, paid at signing
    interestPercent = 10,      -- added once to the financed amount
    payments = 8,              -- instalments
    periodDays = 7,            -- one instalment every this many days (real time)
    graceDays = 3,
}

Config.Keys = { max = 10 }     -- key holders per home

-- Every door locks itself so nobody walks into a home its people left open.
Config.AutoLock = {
    onRestart = true,          -- all homes start locked after a server / resource restart
    whenResidentsLeave = true, -- the last owner / key holder online logs out or drops: lock it
}

-- Home storage. Owners can buy the upgrades in order (Manage → Home); an upgrade
-- stays with the home when it is sold to another player.
Config.Stash = {
    slots = 60, weight = 500000,
    upgrades = {
        { label = 'Extended', slots = 90, weight = 1000000, price = 35000 },
        { label = 'Vault', slots = 140, weight = 2000000, price = 90000 },
    },
}

-- ── Police raids ────────────────────────────────────────────────────────────
-- Officers break a locked home's door open. The owner is told, the door stays
-- unlocked until a resident locks it again, and it shows in the home's activity log.
Config.Raid = {
    enabled = true,
    jobs = { police = 2, sheriff = 2, bcso = 2 }, -- job name = lowest grade allowed
    requireDuty = true,
    seconds = 8,               -- time to breach
    item = nil,                -- e.g. 'police_ram': needed (not used up); nil = none
    searchStorage = true,      -- officers inside may open the home's storage
}

-- ── Activity log (Manage → Activity, residents only) ─────────────────────────
Config.Log = {
    enabled = true,
    days = 14,                 -- entries older than this are deleted
    show = 25,                 -- entries shown in the panel
}

-- ── Interiors ───────────────────────────────────────────────────────────────
-- Shells and base-game interiors are private copies (routing buckets): a home
-- lives in bucket bucketBase + house id * 100 + unit.
Config.Instance = {
    bucketBase = 40000,        -- lumo-apartments uses 20000+; keep the ranges apart
    shellOrigin = vector3(-1250.0, -3200.0, 650.0), -- where shells are spawned (above the sea)
}

Config.Doorbell = { seconds = 60 }

-- ── Furniture ───────────────────────────────────────────────────────────────
-- Residents buy and place furniture (catalog: data/furniture.lua). Also used by
-- lumo-apartments for its flats. A piece's storage / wardrobe / bed works like the
-- home's own. Furniture stays with a home that is sold to another player or handed
-- over; when the bank takes a home back, the owner gets sellBackPercent of it back.
Config.Furniture = {
    enabled = true,
    maxPieces = 150,           -- per home
    sellBackPercent = 50,      -- selling a piece (or the bank taking the home) pays this share
    reach = 10.0,              -- metres from you a piece may be placed
    keyHolders = false,        -- true: key holders may decorate as well
    mloRange = 40.0,           -- MLO homes: furniture shows to anyone this close to the door
}

-- Poses from the radial (Housing / Apartment → Poses): sit, sleep, shower, work out…
-- A ghost of you shows the pose first. The list lives in data/poses.lua.
Config.Poses = {
    enabled = true,
    reach = 6.0,               -- metres from you the ghost may go
    -- Poses marked `undress` (the shower) strip a freemode ped to underwear while they
    -- play; the outfit comes back exactly as it was. Looks only: the saved skin is untouched.
    undress = true,
    -- Relaxing poses (and the toilet) ease stress: this event, `amount` every `every` seconds.
    -- QBCore's contract (lumo-ui and qb-hud listen to it); false = off.
    stress = { event = 'hud:server:RelieveStress', amount = 2, every = 30 },
}

-- Decorating extras (Studio tab, piece editor and Room tools in the decorate panel).
Config.Decor = {
    tilt = true,               -- pieces may tilt (pitch / roll), not only turn: slabs become walls, ramps…
    lights = true,             -- lamps cast real light; colour, brightness and range per lamp
    pictures = true,           -- picture frames and signs show photos, links or text
    photos = true,             -- residents take in-game photos for their walls (needs screenshot-basic)
    -- Image links are allowed from these hosts only ({} = no links, photos only).
    imageHosts = { 'i.imgur.com', 'cdn.discordapp.com', 'media.discordapp.net', 'i.ibb.co' },
    surfaces = true,           -- paint, wallpaper and flooring (data/materials.lua)
    effects = true,            -- fire, steam, fog and water effects (data/effects.lua)
    maxEffects = 6,            -- effects running at once near the player
    surfacePrice = 40,         -- per square metre of a new surface
    maxSurfaceArea = 60,       -- m² per surface
    hideMapObjects = true,     -- residents may take a furnished flat's own furniture out of the room
    maxHidden = 200,           -- map objects taken out, per home
    drawDistance = 25.0,       -- lights, pictures and surfaces draw this close
    maxPictures = 8,           -- pictures shown at once (each one is a small browser)
}

-- ── Blips ───────────────────────────────────────────────────────────────────
Config.Blips = {
    forSale = { enabled = true, sprite = 374, colour = 2, scale = 0.55 },  -- for sale or rent
    owned = { enabled = true, sprite = 40, colour = 3, scale = 0.75 },     -- your homes
    keyed = { enabled = true, sprite = 40, colour = 0, scale = 0.65 },     -- homes you hold a key to
}

-- ── Realestate office (opens the browser) ───────────────────────────────────
-- Stand on the spot with Config.Debug = true and run /housecoords to get a vector4.
-- ped (optional): an agent stands on the spot, facing the heading; E talks to them.
-- scenario (optional): what they do, default 'WORLD_HUMAN_CLIPBOARD'.
Config.Offices = {
    -- { coords = vector4(x, y, z, heading), label = 'Realestate', blip = true, ped = 'a_f_y_business_02' },
    { coords = vector4(-269.48, -955.31, 31.22, 203.6), label = 'Realestate', blip = true, ped = 'a_f_y_business_02' },
}

-- ── Garages ─────────────────────────────────────────────────────────────────
-- A house with a garage point registers it with the garage resource.
Config.Garage = 'auto'         -- 'auto' (qb-garages) | 'qb-garages' | 'custom' | 'none'

-- ── Compatibility ───────────────────────────────────────────────────────────
-- Spawn menus and phones that read the qb-houses tables (houselocations,
-- player_houses) see the homes made here when this is on.
Config.Compat = {
    qbHousesTables = true,
}

-- ── Custom hooks ────────────────────────────────────────────────────────────
Config.Hooks = {
    -- Server side (Config.Inventory = 'custom'). Open stash `id` for player `src`. Access is already checked.
    openStash = function(src, id, label, slots, weight) end,
    -- Client side (Config.Wardrobe = 'custom'). Open the outfit wardrobe for home `id`.
    openWardrobe = function(id) end,
    -- Client side (Config.Garage = 'custom'). A house garage the player can use (`allowed`) or not.
    garage = function(house, coords, allowed) end,
}