Nord Garages v2.0.0 — Documentation

Nord Garages v2.0.0 documentation.

Getting Started

Getting Started

Nord Garages v2.0.0

Nord Garages v2.0.0

Nord Garages is a complete vehicle storage and lifecycle system for FiveM. Version 2.0.0 combines public/job/fleet/house garages, dedicated impounds, native showrooms, vehicle transfers, real/persistent parking, framework ownership synchronization and the Vehicle OS layer.

Main capabilities

Supported frameworks

Config.Framework = 'auto' detects Qbox/QBX, QBCore, ESX, Nord Core, then falls back to standalone operation.

Important design rule

Framework vehicle tables remain the ownership source where applicable, while Nord Garages is authoritative for its runtime garage/impound/Vehicle OS state. Avoid editing nord_garage_vehicles manually while the server is live unless you fully understand the state model.

Getting Started

Requirements

Requirements

Required

Frameworks

The resource can run with:

Optional integrations

ensure oxmysql
# framework/core resources
# inventory/fuel/keys resources
ensure nord_vehiclekeys   # when used
ensure nord_garages
# integrations such as nord_staff / nord_phone

Starting the key/inventory/fuel providers before Nord Garages allows auto-detection to resolve them immediately.

Getting Started

Installation

Installation

  1. Copy the nord_garages folder into your server resources directory.
  2. Ensure oxmysql is installed and connected to the same database used by your framework.
  3. Review shared/config.lua before first start.
  4. Add ensure nord_garages to server.cfg after its dependencies.
  5. Restart the server or start the resource.

Database installation

Nord Garages includes AutoSQL. On normal installations you do not need to manually import the SQL file. The resource creates and migrates its own tables on startup.

The included sql/nord_garages.sql is a manual fallback for environments where you explicitly prefer manual SQL setup.

First validation

After first start:

Existing installations

Do not drop old Nord Garages tables when upgrading. AutoSQL migrations are designed to upgrade the current schema in place while preserving data.

Getting Started

Quick Start

Quick Start

1. Give yourself admin access

Default permission:

add_ace group.admin nord.garages.admin allow

The permission node can be changed using Config.AdminAce.

2. Open the creator

Default command:

/garageadmin

3. Create a garage

Use New Garage and choose the correct vehicle categories. Configure at minimum:

4. Test the player flow

Enter the garage interaction area, open the garage, spawn an owned vehicle, then return it through a compatible store point.

5. Create impounds separately

Impound yards have their own management flow. Keep land, boat and air impounds separated unless the configuration deliberately supports the matching vehicle classes.

Configuration

Configuration

Core Configuration

Core Configuration

The main configuration file is shared/config.lua.

Config.Locale = 'en'
Config.Framework = 'auto'
Config.Debug = false

Config.AdminCommand = 'garageadmin'
Config.AdminAce = 'nord.garages.admin'
Config.RealParkingCommand = 'parkvehicle'

Config.InteractionKey = 38
Config.InteractionDistance = 4.0
Config.ScanDistance = 70.0

Framework

Config.Framework accepts:

Use auto unless you need to force a specific bridge.

Debug

Keep Config.Debug = false in production. Enable it temporarily while diagnosing integration or placement issues.

World interaction

Config.WorldInteraction = {
    enabled = true,
    refreshSeconds = 10,
}

The built-in interaction does not require a target resource. The default flow uses the map blip plus Nord TextUI when the player enters interaction range.

Spawn/return safety

Configuration

Blips & Vehicle Types

Blips & Vehicle Types

Blip presets

Config.Blips.useTypePresets = true applies deterministic blip presets based on garage category.

Default groups include:

With lockTypeSprite = true, old/custom sprite values stored in SQL are ignored for the sprite itself, while per-location colour/scale may still be used.

GTA class → Nord type

Config.VehicleTypes maps GTA vehicle classes to Nord categories such as:

Spawn groups

Config.SpawnGroups = {
    car = { 'car', 'motorcycle', 'bicycle', 'service', 'emergency', 'industrial', 'special' },
    boat = { 'boat' },
    air = { 'helicopter', 'plane' }
}

These groups are important for store/spawn compatibility and strict impound routing.

Configuration

Bridges Configuration

Bridges Configuration

Config.Bridges = {
    notify = 'auto',
    textui = 'custom',
    keys = 'auto',
    fuel = 'auto',
    inventory = 'auto',
}

Notify

Supported modes include auto, ox_lib, qb, esx and custom.

TextUI

Default is Nord's internal NUI TextUI using custom. You may switch to supported external providers in the bridge configuration.

Keys

auto prefers nord_vehiclekeys when available, then compatible alternatives. Use none only when no key lifecycle integration is desired.

Fuel

Auto-detection supports ox_fuel, lc_fuel and LegacyFuel.

Inventory

Auto-detection supports Nord Inventory and multiple common FiveM inventories. Inventory code is isolated from the core so integrations can be replaced without rewriting garage logic.

Configuration

Vehicle OS Configuration

Vehicle OS Configuration

The Vehicle OS layer is controlled by Config.VehicleOS.

Config.VehicleOS = {
    enabled = true,
    vinPrefix = 'NRD',
    stateEngine = true,
    duplicateGuard = true,
    plateAliases = true,
    snapshots = true,
    analytics = true,
    collections = true,
    reservations = true,
    advancedAccess = true,
    maintenance = true,
    insurance = true,
    stolenState = true,
    evSupport = true,
    providerRegistry = true,
}

Maintenance thresholds

Defaults:

These values are advisory metadata thresholds for systems integrating with the maintenance API.

Dynamic transfer defaults

Dynamic transfer calculation uses a base fee/time plus distance-based additions, capped by maxSeconds.

Access roles

Default advanced access roles:

Temporary access is limited by Config.VehicleAccess.maxTemporaryHours.

Configuration

Persistent Parking, Delivery & Valet

Persistent Parking, Delivery & Valet

VIP Persistent Parking

Persistent parking requires both:

  1. The feature enabled in Config.PersistentParkingVIP.
  2. The garage itself allowing real parking where applicable.
  3. The player passing a VIP provider, ACE, configured identifier, or admin bypass.

Default ACE:

add_ace group.vip nord.garages.vip allow

Important defaults:

Vehicle Delivery

Default configuration is VIP-only with a 90 second cooldown and configured fee.

Valet

Default configuration is VIP-only with its own fee and cooldown.

External VIP systems should integrate through RegisterVIPProvider instead of modifying core logic.

Garage Creator and Management

Garage Creator and Management

Admin Access & Creator

Admin Access & Creator

Command

Default:

/garageadmin

Configured through Config.AdminCommand.

Permission

Default ACE node:

nord.garages.admin

Example:

add_ace group.admin nord.garages.admin allow

Nord Garages also provides runtime access exports for trusted resources:

exports['nord_garages']:AddAdmin(value)
exports['nord_garages']:RemoveAdmin(value)
exports['nord_garages']:IsAdmin(value)
exports['nord_garages']:GetRuntimeAdmins()

Compatibility aliases are also available:

GiveGaragesAccess
RemoveGaragesAccess
HasGaragesAccess

UI structure

Garage Creator and Management

Garage Types & Access

Garage Types & Access

Nord Garages supports several logical garage profiles, including templates for:

Each garage stores its own categories, access data, settings, blip data and published state.

Access patterns

Common access modes include public/player access and job-restricted access. Job integrations should always validate access server-side; do not rely on hiding UI elements as a security mechanism.

Capacity

capacity = 0 means unlimited capacity. Positive values limit the number of vehicles assigned according to the garage capacity rules.

Publishing

An unpublished garage is retained in the database/admin tools but should not act as a normal public gameplay location. Publish only after points and access rules are verified.

Garage Creator and Management

Points & Placement

Points & Placement

Garage world configuration is stored in nord_garage_points.

Common point types include:

Showroom/camera world points from older versions are removed by migration because v2 uses native interior presets.

Placement configuration

The placement editor supports:

Default step sizes:

{ 0.01, 0.05, 0.10, 0.25, 0.50, 1.00 }

Best practices

Garage Creator and Management

Garage Templates

Garage Templates

Config.GarageTemplates provides reusable defaults for integrations or creator flows.

Default templates include:

Public

Cars/motorcycles, unlimited capacity, transfers/sharing/real parking/showroom enabled.

Job

Similar to public but intended for job access policies.

Marina

Boat-only template.

Airport

Plane/helicopter template.

House

Small default capacity with showroom disabled.

Fleet

Cars/motorcycles/service/emergency categories with sharing disabled by default.

Templates are configuration defaults only. A registered garage can override its stored categories/settings.

Player Vehicle Workflows

Player Vehicle Workflows

Store & Spawn Flow

Store & Spawn Flow

Storing

The server validates ownership/access, garage compatibility, capacity and current authoritative vehicle state before committing the store operation.

When storing succeeds:

A failed store validation does not intentionally detach a still-active vehicle from runtime tracking.

Spawning

Spawning uses a short server lock to prevent concurrent duplicate requests. The state can temporarily enter spawning, then transitions after the client/server confirm flow.

On resource/server restart, stale spawning rows are repaired back to stored by migration/startup safety logic.

Duplicate guard

Vehicle OS duplicate protection checks authoritative identity/state before restoration or spawn operations. Do not bypass the spawn APIs by creating a second owned entity manually with the same plate.

Player Vehicle Workflows

Vehicle Transfers

Vehicle Transfers

Transfers can be enabled globally and per garage.

Legacy/default transfer values:

Config.Transfer = {
    enabled = true,
    defaultFee = 500,
    defaultSeconds = 300,
}

Vehicle OS can also use dynamic distance-based pricing/timing:

Config.DynamicTransfer = {
    enabled = true,
    baseFee = 150,
    feePerKm = 45,
    baseSeconds = 30,
    secondsPerKm = 18,
    maxSeconds = 1800,
}

During transfer, the vehicle enters a non-stored transit state and should not be spawned from another garage until the transfer resolves.

For integrations, always request the current state from Nord Garages rather than assuming the framework garage column alone describes live transfer status.

Player Vehicle Workflows

Showroom

Showroom

Nord Garages v2 uses native GTA interior presets. No shell resource is required for the included showroom system.

Default group presets:

Isolation

Each showroom session is isolated using routing buckets based on Config.Showroom.routingBucketBase.

Vehicle behaviour

Showroom vehicles are preview/display entities. They must not be treated as normal spawned owned vehicles by inventory, target or garage logic.

Useful client exports:

exports['nord_garages']:IsInShowroom()
exports['nord_garages']:IsShowroomVehicle(vehicle)
exports['nord_garages']:GetShowroomVehicleData(vehicle)

Temporary keys

When Nord Vehicle Keys is active, showroom access can grant session-only temporary key access without creating a permanent physical key item. Existing owner/shared keys are preserved.

Player Vehicle Workflows

Vehicle States

Vehicle States

Core integrations should understand the Nord state machine.

Common states include:

Detached

detached is intentionally used when an owned vehicle is removed from all garages without a valid live entity. It prevents the row from appearing as a phantom active/stored vehicle.

State safety

External scripts should prefer SetVehicleState or dedicated exports instead of direct SQL updates. The resource records normal state changes in nord_garage_history and notifies live integrations.

Impound System

Impound System

Impound Overview

Impound Overview

Impounds are deliberately separate from normal garage locations.

GetGarages() does not include impound yards. Use GetImpounds() for impound-specific integrations.

Core features

Default configuration

Important values under Config.Impound include default fine, recovery fee, release time, missing-entity grace periods and optional preferred default impound.

Impound System

Impound Vehicle Type Safety

Impound Vehicle Type Safety

Nord Garages validates vehicle type server-side before assigning an impound.

Expected routing:

The resolver prioritizes reliable runtime/model information and framework metadata, then repairs known legacy type values where possible.

Existing incorrect impound assignments can be reconciled automatically through the impound reconciliation system.

Useful exports:

exports['nord_garages']:ResolveVehicleType(model, fallback, netId, secondaryModel)
exports['nord_garages']:AuditVehicleTypes()
exports['nord_garages']:ReconcileImpounds(options)
Impound System

Job Impounds

Job Impounds

Job impound locations and permissions are created in-game from the admin interface.

Authorised employees can use the configured field command/key while near a vehicle.

Defaults:

jobFieldCommand = 'impoundvehicle'
jobFieldKey = 'F7'
jobFieldDistance = 6.0
jobFieldServerDistance = 10.0

The player may rebind the FiveM keybind through game settings.

Server exports

exports['nord_garages']:GetJobImpounds(source)
exports['nord_garages']:CanJobManageImpound(source, identifier)
exports['nord_garages']:JobImpoundVehicle(source, plate, impoundIdentifier, reason, fine, releaseSeconds)
exports['nord_garages']:JobReleaseImpound(source, plate)

Job/grade/category validation remains server-side.

Impound System

Automatic Recovery

Automatic Recovery

When enabled, vehicles that were active/parked but whose OneSync entity disappears may be routed to recovery/impound instead of silently returning for free.

Important grace values distinguish normal missing entities from disconnect/migration races.

Defaults include:

Why the delays exist

OneSync ownership migration and player disconnects can briefly remove or move an entity. Immediate impound on every removal can create false positives, so Nord Garages uses short context-specific grace windows plus a slower fallback scan.

Explicit deletion

Server-side entity removal is monitored. Trusted staff integrations should use the dedicated staff exports so the desired garage state is explicit rather than relying only on entity disappearance detection.

Vehicle OS

Vehicle OS

VIN & Plate Identity

VIN & Plate Identity

Vehicle OS adds a permanent VIN identity that is independent of the current plate.

Why VIN exists

Plates can be changed. A VIN provides a stable identity for history, snapshots, access and service metadata even after a plate replacement.

Plate aliases

Old plates can be retained as aliases/history so integrations can resolve previous identities.

Useful exports:

exports['nord_garages']:GetVehicleIdentity(plateOrVin)
exports['nord_garages']:ChangeVehiclePlate(plateOrVin, newPlate, actor)
exports['nord_garages']:CompareVehicles({ valueA, valueB })

Do not change a framework plate directly without also reconciling Nord Garages; use the supported export for integrated workflows.

Vehicle OS

Snapshots & History

Snapshots & History

Vehicle snapshots provide recoverable copies of vehicle state such as properties, health, fuel and position.

local snapshots = exports['nord_garages']:GetVehicleSnapshots(plateOrVin, 20)
local history = exports['nord_garages']:GetVehicleHistory(plateOrVin, 50)

exports['nord_garages']:RestoreVehicleSnapshot(plateOrVin, snapshotId, actor)

Use cases

Restores should be treated as administrative/integration operations and should be auditable via the actor value.

Vehicle OS

Advanced Access & Collections

Advanced Access & Collections

Vehicle access

Vehicle OS supports additional access roles such as co-owner, family, employee, temporary and valet.

exports['nord_garages']:GrantVehicleAccess(vehicle, identifier, role, expiresAt, actor)
exports['nord_garages']:RevokeVehicleAccess(vehicle, identifier, actor)

Temporary access may be constrained by the configured maximum duration.

Collections / favourites

exports['nord_garages']:SetVehicleCollection(source, vehicle, 'Daily', true)

Collections organize vehicles without changing ownership or garage state.

Vehicle OS

Reservations & Physical Slots

Reservations & Physical Slots

Reservations

Garage reservations can reserve capacity for a vehicle/user for a limited period.

exports['nord_garages']:CreateGarageReservation(source, garageIdentifier, vehicleId, minutes)
exports['nord_garages']:GetGarageReservations(garageIdentifier)

Expired/invalid reservations are ignored or cleaned by the database/runtime safety logic.

Physical slots

Vehicle OS includes a backend for named physical parking slots/floors.

exports['nord_garages']:GetGarageSlots(identifier)
exports['nord_garages']:UpsertGarageSlot(identifier, slot)

Slot data can include label, floor, position, allowed vehicle types, enabled state and sort order.

Vehicle OS

Service, Insurance, Stolen & EV Data

Service, Insurance, Stolen & EV Data

Vehicle OS exposes provider-neutral metadata APIs.

exports['nord_garages']:SetVehicleServiceData(vehicle, data, actor)
exports['nord_garages']:SetVehicleInsurance(vehicle, data, actor)
exports['nord_garages']:SetVehicleStolen(vehicle, true, actor, details)
exports['nord_garages']:SetVehicleEVData(vehicle, data, actor)
exports['nord_garages']:GetMaintenanceStatus(vehicle)

These APIs allow mechanic, insurance, police and EV resources to integrate without directly coupling to Nord Garages internal SQL schema.

The exact metadata object structure can be defined by the integrating provider; keep payloads JSON-serializable and avoid storing huge binary data.

Vehicle OS

Recovery Center & Analytics

Recovery Center & Analytics

Recovery Center

local issues = exports['nord_garages']:GetRecoveryCenter()
exports['nord_garages']:RepairVehicleState(vehicle, action, garageIdentifier, actor)

The recovery system can repair stale spawning/transit states, missing garage assignments and incompatible impound assignments using normal synchronization paths.

Intentional detached records are not treated as recovery errors.

Analytics

local analytics = exports['nord_garages']:GetGarageAnalytics(days)

Analytics data is stored separately from ownership state and is intended for operational dashboards/diagnostics.

Integrations and API

Integrations and API

Framework Bridge

Framework Bridge

Framework-specific code is isolated under client/bridge/ and server/bridge/.

Auto-detection order is:

  1. Qbox / QBX
  2. QBCore
  3. ESX
  4. Nord Core
  5. Standalone

Framework ownership/economy is bridged while Nord Garages keeps its own authoritative runtime state.

Framework table mapping

The configuration contains default table mappings for ESX and QB/QBX. If your server uses a heavily customized ownership schema, adjust only the bridge/table mapping instead of rewriting the garage core.

Nord Core

The included bridge expects a GetPlayer(source) style export. If your local Nord Core API differs, adapt the Nord bridge file while preserving the core API contract.

Integrations and API

Keys, Fuel & Inventory

Keys, Fuel & Inventory

Nord Vehicle Keys

When nord_vehiclekeys is used, Nord Garages integrates server-authoritatively.

Typical API usage includes registering the owned network entity, checking keys/physical key items and granting keys only when needed.

With Config.Keys.keepOwnerKeysOnStore = false, storing/impounding removes the physical vehicle key lifecycle where appropriate, and spawning recreates valid owner access without duplicating physical key items.

Fuel

The fuel bridge restores the saved fuel value during entity initialization, then stops writing so the active fuel resource controls normal consumption.

lc_fuel receives extra initialization safety to avoid persisting an uninitialized decorator as a false 0% tank.

Inventory bridge API

Internally normalized operations include:

NordInventory.GetCount(source, item, metadata)
NordInventory.HasItem(source, item, amount, metadata)
NordInventory.GetItem(source, item, metadata)
NordInventory.AddItem(source, item, amount, metadata, slot, reason)
NordInventory.RemoveItem(source, item, amount, metadata, slot, reason)
NordInventory.RegisterStash(id, label, slots, weight, owner, groups, coords)
NordInventory.OpenStash(source, id, owner)
Integrations and API

Client Exports

Client Exports

Garage UI

exports['nord_garages']:OpenGarage(identifier)
exports['nord_garages']:CloseGarage()
local garages = exports['nord_garages']:GetGarages()

Impounds

exports['nord_garages']:OpenImpound(identifier)
local impounds = exports['nord_garages']:GetImpounds()
exports['nord_garages']:OpenImpoundManager()
exports['nord_garages']:OpenJobImpoundManager()

Admin permission for management remains server-side.

Showroom helpers

exports['nord_garages']:IsInShowroom()
exports['nord_garages']:IsShowroomVehicle(vehicle)
exports['nord_garages']:GetShowroomVehicleData(vehicle)

Use these to ensure target/inventory resources ignore preview entities where appropriate.

Integrations and API

Server Exports — Garages & Vehicles

Server Exports — Garages & Vehicles

Garage lookup/registration

exports['nord_garages']:GetGarage(identifier)
exports['nord_garages']:GetGarages(true)
exports['nord_garages']:GetImpounds(true)
exports['nord_garages']:GetGarageTemplates()
exports['nord_garages']:RegisterGarage(data)

Fleet

exports['nord_garages']:RegisterFleetVehicle(job, garageIdentifier, vehicleData)

Vehicle state

exports['nord_garages']:SetVehicleState(plate, state, garageIdentifier, details)
exports['nord_garages']:ImpoundVehicle(plate, garageIdentifier, reason, releaseAt, fine)
exports['nord_garages']:ReleaseVehicle(plate, garageIdentifier)

Staff-safe garage mutations

exports['nord_garages']:AddVehicleToGarage(plate, garageIdentifier, options)
exports['nord_garages']:ForceStoreVehicle(plate, garageIdentifier, options)
exports['nord_garages']:RemoveVehicleFromGarage(plate, options)
exports['nord_garages']:DetachVehicleFromGarages(plate, options)
exports['nord_garages']:StaffDeleteWorldVehicle(plate, garageIdentifier, options)
exports['nord_garages']:GetVehicleGarageState(plate)

All trusted mutation integrations should check the returned ok/error fields.

Integrations and API

Server Exports — Admin, Staff & Sync

Server Exports — Admin, Staff & Sync

Admin access

AddAdmin(value)
RemoveAdmin(value)
IsAdmin(value)
GetRuntimeAdmins()

Compatibility aliases:

GiveGaragesAccess(value)
RemoveGaragesAccess(value)
HasGaragesAccess(value)

Staff snapshots

local rows = exports['nord_garages']:GetStaffVehicleSnapshot(limit)

The helper is designed for bulk authoritative reads instead of one export call per vehicle.

Framework reconciliation

exports['nord_garages']:ReconcileOwnedVehicleByPlate(plate, options)
exports['nord_garages']:SyncAllFrameworkVehicles(limit, force)
exports['nord_garages']:ReconcileImpounds(options)

Use these after trusted staff/ownership operations when another resource has changed the framework ownership table.

Ownership deletion

DeleteOwnedVehicleRecord is intended for explicit staff ownership deletion. Do not confuse this with StaffDeleteWorldVehicle, which is world-only and does not delete framework ownership.

Integrations and API

Server Exports — Vehicle OS

Server Exports — Vehicle OS

Main exports include:

RegisterVIPProvider(name, handler)
RegisterProvider(kind, name, handler)
GetProviders()
IsPersistentParkingVIP(source)
GetVehicleIdentity(value)
ChangeVehiclePlate(value, newPlate, actor)
CompareVehicles(values)
SearchVehicles(source, query, limit)
GetVehicleHistory(value, limit)
GetVehicleSnapshots(value, limit)
RestoreVehicleSnapshot(value, snapshotId, actor)
GrantVehicleAccess(value, identifier, role, expiresAt, actor)
RevokeVehicleAccess(value, identifier, actor)
SetVehicleCollection(source, value, collection, favorite)
CreateGarageReservation(source, garage, vehicleId, minutes)
GetGarageReservations(garage)
GetGarageSlots(identifier)
UpsertGarageSlot(identifier, slot)
SetVehicleServiceData(value, patch, actor)
SetVehicleInsurance(value, patch, actor)
SetVehicleStolen(value, stolen, actor, details)
SetVehicleEVData(value, patch, actor)
GetMaintenanceStatus(value)
TowVehicleToImpound(value, garage, reason, actor, fine)
GetRecoveryCenter()
RepairVehicleState(value, action, garage, actor)
GetGarageAnalytics(days)
RestorePersistentParking()
RequestVehicleDelivery(source, plate, mode)

External resources should use these contracts rather than querying auxiliary Vehicle OS tables directly.

Integrations and API

Events & Live Sync

Events & Live Sync

Nord Garages emits events so Staff, Phone and other integrations can refresh without polling the full database continuously.

Vehicle changed

AddEventHandler('nord_garages:server:vehicleChanged', function(payload)
    -- refresh local integration cache
end)

Vehicle OS event bus

AddEventHandler('nord_garages:server:event', function(eventName, payload)
end)

AddEventHandler('nord_garages:server:vehicleChangedV2', function(payload)
end)

Garage changes

Garage create/update/delete operations emit the garage change flow used by live admin/staff integrations.

Integration recommendation

Prefer event-driven cache invalidation plus occasional reconciliation. Avoid high-frequency SQL polling for every player/vehicle.

Integrations and API

Nord Phone Integration

Nord Phone Integration

Server-side phone exports provide UI-safe normalized vehicle data.

local vehicles = exports['nord_garages']:GetPhoneVehicles(source)
local vehicle = exports['nord_garages']:GetPhoneVehicle(source, plate)
local garages = exports['nord_garages']:GetPhoneGarages()

The normalized vehicle snapshot can include plate, model/label, state, garage or impound identity, location, fuel and impound metadata.

A notification helper is also available:

exports['nord_garages']:NotifyPhoneVehicleChanged(ownerIdentifier, plate, action, garageIdentifier)

Vehicle history/state changes invalidate the live phone cache so store, spawn, transfer, impound, release and reconciliation operations can refresh without a resource restart.

Integrations and API

Nord Staff Integration

Nord Staff Integration

Nord Staff should use the trusted server exports instead of directly manipulating Nord Garages rows.

Give/store vehicle

After creating framework ownership, call ReconcileOwnedVehicleByPlate or AddVehicleToGarage so the new vehicle appears immediately without restart.

DV / remove from world

Use:

exports['nord_garages']:StaffDeleteWorldVehicle(plate, nil, {
    source = source,
    netId = netId,
})

This reconciles world tracking/garage state without deleting ownership.

Delete ownership

Use the explicit ownership deletion export only when the staff action genuinely removes the vehicle from the player's ownership database.

Global list

Use GetStaffVehicleSnapshot(limit) for bulk state and SyncAllFrameworkVehicles(limit, force) when a full framework sync is required.

Database and AutoSQL

Database and AutoSQL

AutoSQL & Schema

AutoSQL & Schema

Nord Garages automatically creates and migrates its schema during resource startup.

The stabilization line includes a schema migration that also verifies the Vehicle OS auxiliary tables/columns/indexes, which helps repair older or partially upgraded installations.

Core tables

Vehicle OS tables

Normal users should let AutoSQL manage these tables.

Database and AutoSQL

Core Tables Explained

Core Tables Explained

nord_garages

Stores garage definition data: identifier, name, garage type, categories, access, settings, blip/NPC data and published state.

nord_garage_points

Stores world points linked to a garage identifier, including position, point type and metadata.

nord_garage_vehicles

Stores Nord's normalized vehicle state including owner, plate, model/type, garage assignment, state, properties, health, fuel, mileage, last position, sharing/metadata and current tracking identifiers.

Vehicle OS extends this table with VIN, slot, service, insurance, EV and stolen-state fields.

nord_garage_history

Append-style operational history for vehicle state/actions.

nord_garage_schema

Tracks migration/schema version. Do not manually reduce the version number on a live database.

Database and AutoSQL

Database Safety

Database Safety

Do not edit active state casually

Directly changing a vehicle row while the resource is running can desynchronize:

Use server exports wherever possible.

Backups

Before a major upgrade, back up both:

  1. Your framework ownership table (owned_vehicles or player_vehicles).
  2. All nord_garage_* tables.

Stale spawning state

Startup SQL repairs stale spawning rows back to stored so a crash/restart does not permanently lock a vehicle.

Legacy showroom points

Older showroom and camera point types are removed because v2 uses the native showroom implementation.

Troubleshooting and Production

Troubleshooting and Production

Common Problems

Common Problems

Admin command does nothing

Check:

Garage is not visible

Check that the garage is published, has valid points, correct access rules and compatible categories.

Vehicle does not appear

Check framework ownership first, then run the trusted reconciliation path. For staff-created vehicles, ensure Nord Garages is notified after the ownership row is created.

Vehicle appears in wrong impound

Use the impound reconciliation/type audit exports and verify the vehicle model/class is correct. Separate plane and helicopter yards must match their configured categories.

Fuel restores as 0

Confirm the configured fuel provider is actually running before Nord Garages and that no second resource overwrites fuel immediately after spawn.

Keys duplicate or disappear

Start your key resource before Nord Garages. With Nord Vehicle Keys, avoid granting/removing permanent physical keys client-side from a second integration.

UI opens but data is stale

Check live sync events between Staff/Phone/custom integrations rather than forcing constant UI reopen/restart behaviour.

Troubleshooting and Production

Diagnostics & Recovery

Diagnostics & Recovery

Useful server-side diagnostic exports:

AuditVehicleTypes()
ReconcileImpounds(options)
GetRecoveryCenter()
RepairVehicleState(value, action, garage, actor)
GetVehicleGarageState(plate)
GetStaffVehicleSnapshot(limit)
SyncAllFrameworkVehicles(limit, force)
GetProviders()

Recovery Center examples

Recovery can address stale transient states and missing/incompatible garage assignments through the normal state synchronization flow.

Production logging

Keep Config.Debug = false normally. Enable it only while reproducing a problem, collect the relevant console output, then disable it again.

What runtime testing must cover

Static validation cannot reproduce every combination of framework build, MLO geometry, OneSync ownership migration, fuel/key version or existing database contents. Always perform a staging smoke test before replacing a busy live resource.

Troubleshooting and Production

Production Checklist

Production Checklist

Before release to players:

Changelog

Changelog

v2.0.0 — Vehicle OS

v2.0.0 — Vehicle OS

Nord Garages 2.0 preserves ESX/QB/QBX ownership compatibility while adding the Vehicle OS layer.

Added

Changelog

v2.0.0 Stabilization Pass

v2.0.0 Stabilization Pass

The stabilization pass keeps existing gameplay logic while hardening failure paths.

Hardened

Validation performed

Runtime-specific framework/MLO behaviour still requires staging-server validation.