Skip to content

Garages

Property garages are stored in world_housing_garages and opened through a detected garage script. Housing owns the world interaction (ox_lib zones). External garage resources are only used for open / store / backend via their public events or exports.

Feature flag: Config.Features.garages.

Architecture

  1. Player places (or re-places) access + spawn points near the house.
  2. Housing writes one row per property in world_housing_garages.
  3. The active provider registers backend identity if needed (housing_{housingId}).
  4. Housing creates a client sphere zone at the access coords (InteractDistance).
  5. [E] on foot opens the garage; [E] in a vehicle stores it — forwarded to the provider.
Place / replace → DB (one garage per housing_id)
               → Provider Register / Update (backend only)
               → Housing ox_lib zone (world interact)
               → Open / store via provider export or event

qbx_garages is not supported: it has no safe unregister / replace API for client zones without patching that resource.

Flow

  1. Owner buys the GARAGE upgrade in Housing Central (requires a compatible provider).
  2. Placement starts automatically (or via Create garage action).
  3. Step 1 — Stand at the interaction point → [E] (access marker, Z offset −0.9).
  4. Step 2 — Stand where vehicles should spawn, face exit → [E] (preview vehicle).
  5. [ENTER] confirms · [BACKSPACE] cancels.
  6. Stay within Config.Garage.MaxDistanceFromHouse of the house exterior.

TextUI stays visible for the whole placement (including after leaving the interior).

Replacing a garage

Placing again on the same property updates the existing garage (it does not stack a second one):

  • DB row for that housing_id is updated; duplicates are removed.
  • Housing removes the old zone and creates one at the new access coords.
  • Provider Update runs (backend sync only — no second world interact from housing).

Shared garage

SHARED_GARAGE unlocks shared vehicle access for keyholders with the GARAGE privilege. It only appears when the active provider supports shared garages (cd_garage, RxGarages).

Supported providers

Detection order when Config.Garage.System = "auto" (first started resource wins):

ResourceSharedClient zonesRegister / UpdateOpen / store
qb-garagesnoyesSyncs house garage data (addHouseGarage)setHouseGarage + OpenHouseGarage / store bridge
jg-advancedgaragesnoyesValidation onlyopen-garage / store-vehicle events
cd_garageyesyesPropertyGarage:Create once per property; update does not re-CreatePropertyGarage:Open / PropertyGarage:StoreVehicle
okokGaragenoyesDB row replace by garagenameOpenPrivateGarageMenu / StoreVehiclePrivate
rcore_garagenoyesValidation onlyOpenGarageOnSpot / StoreMyVehicle
zerio-garagenoyesValidation onlyServer open/store → Zerio exports
RxGaragesyesyesValidation onlyOpenGarage / ParkVehicle exports
vms_garagesv2noyesregisterHousingGarageenterHouseGarage

All kept providers use housing client zones (needsClientZones = true). Players interact with the housing zone, not a second marker owned by the garage script (when the provider allows that).

Force a provider (or leave auto detection):

lua
Config.Garage.System = "auto" -- or a provider name from the table above

Config

lua
Config.Garage = {
    System = "auto",
    MaxDistanceFromHouse = 40.0,
    InteractDistance = 5.0,
    DetectOrder = {
        "qb-garages",
        "jg-advancedgarages",
        "cd_garage",
        "okokGarage",
        "rcore_garage",
        "zerio-garage",
        "RxGarages",
        "vms_garagesv2",
    },
}
OptionDescription
System"auto" or a resource name from the table above
MaxDistanceFromHouseMax distance from house while placing
InteractDistanceHousing zone radius for open / park after creation
DetectOrderPriority list for auto detection

Parking / opening

  • Walk to the housing access zone → ox_lib TextUI (GARAGE_ZONE_HINT) → E to open or park.
  • Garage id / name pattern: housing_{housingId}.
  • Access check: HasHousingAccess(stateId, housingId, "GARAGE") (owners always pass); also requires the GARAGE upgrade.

Garage limit (VEHICLES)

Property creator stores a Garage Limit in property_settings.VEHICLES. That value is property metadata only; the housing garage adapters do not currently enforce a max vehicle count when parking. Limits, if any, come from the active garage script itself.

Export

lua
local garage = exports["prp-housing-v2"]:GetClosestGarage()
-- or exports["prp-housing-v2"]:GetClosestGarage(coords)

Returns the nearest garage the player may use (or closest without access check when skip flag is used internally). Integrate from vehicle scripts as needed.

Editable providers

Adapter files live in server/garage/providers/*.lua. Client zone + open/store routing: client/garage/zones.lua. Shared detection meta: shared/garage/provider.lua. All are covered by escrow_ignore — see Editable files.