FearlessStudios

Mileage & integrations

Understand live odometers, saved mileage, state bags, and developer exports.

Mileage is always enabled and stored internally in kilometers. Each player chooses miles or kilometers for display under Settings → Vehicle Hub.

When distance counts

Vehicle Hub tracks vehicles spawned through it and vehicles enrolled by opening Current vehicle or capturing them. Another resource can also enroll a vehicle with the server export below. It does not automatically track every world vehicle.

The server samples distance once per second while a player drives the tracked vehicle. Unoccupied movement and movements rejected by the internal distance/speed checks do not count. A tracked, unsaved vehicle can show a live odometer; it gets a persistent personal history only when attached to a personal save.

Other players driving a tracked copy add mileage to that copy, even without its owner inside. Client-written mileage values are not used to calculate or save mileage.

When mileage saves

Personal mileage checkpoints to server KVP every 30 seconds, with a final checkpoint attempt when the resource stops. A sudden server/process failure can lose distance since the last successful checkpoint. If storage fails while the process remains running, pending mileage is retained for retry.

Capturing a tracked vehicle keeps that copy's server-observed mileage. If you are still driving it when the save completes, future checkpoints are attached to that saved entry. Moving or renaming an entry preserves its mileage. Updating an existing preset never reduces its odometer. Duplicating or importing creates a new identity with fresh mileage.

Multiple copies of one save

Live instances are tracked separately using the entity handle, network ID, and a model sanity check. Model names and number plates are not unique vehicle identities.

A personal saved entry keeps the highest reading reported by its copies, not the sum of all copies' travel:

InstanceStarting readingDistance drivenLive reading
Copy A100 km5 km105 km
Copy B100 km3 km103 km

The saved entry retains 105 km. A later spawn starts from that saved reading. Save vehicles as separate entries when they need separate persistent histories.

State bag

Tracked entities expose a replicated live reading:

local kilometers = Entity(vehicle).state.vehicleMileage
local miles = kilometers and kilometers * 0.62137119223733

vehicle is an entity handle on the side where this code runs. The value is in kilometers and can be nil before tracking/replication reaches that client. It is published on enrollment and as the reading changes. vehiclehubMileageKM remains synchronized for older integrations.

State bags are visible to clients with the entity in scope. They are not the persistent storage record. Use the server exports when your resource needs Vehicle Hub's authoritative reading.

GetVehicleMileage

Client and server:

local kilometers = exports["FS-VehicleHub"]:GetVehicleMileage(vehicle, "km")
local miles = exports["FS-VehicleHub"]:GetVehicleMileage(vehicle, "mi")

Pass a local entity handle on the client or a server entity handle on the server, never a network ID. The optional unit is km or mi; omitting it returns kilometers regardless of player display settings. Returns a number, or 0 for an untracked vehicle.

TrackVehicle

Server only:

exports["FS-VehicleHub"]:TrackVehicle(serverVehicleEntity)

Enrolls an externally created vehicle for a session odometer. This does not create a personal saved entry or infer ownership from a plate.

GetSavedVehicleMileage

Server only:

local ok, kilometers = pcall(function()
    return exports["FS-VehicleHub"]:GetSavedVehicleMileage(playerSource, savedEntryId, "km")
end)

Uses the player's FiveM license to read an entry from their personal library, even if its vehicle is not currently spawned. Returns its highest recorded reading in the requested unit, defaulting to kilometers. Invalid or missing entries raise an error, so handle failure when the ID may be stale.

Persistent identity is the owner's license plus saved entry ID. A network ID is temporary and may be reused after a vehicle despawns.