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-property"]:GetClosestGarage()
-- or exports["prp-property"]: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.

Provider scripts ​

Adapter files live in server/garage/providers/*.lua. Client zone + open/store routing: client/garage/zones.lua. Both are escrowed. The only open garage file is shared detection meta: shared/garage/provider.lua. Pick providers and detection order in Config.Garage — see Editable files.