fivem icon indicating copy to clipboard operation
fivem copied to clipboard

Theres no way to reliable edit vehicle top speed

Open mcNuggets1 opened this issue 2 months ago • 7 comments

What happened?

I tried every fucking handling var, i tried SetVehicleCheatPowerIncrease, ModifyVehicleTopSpeed. They all have issues with custom vehicles and make them slower.

Is there a way to just increase the damn speed? The documentation is disgustingly bad.

Expected result

A foking function to reduce or increase vehicle speed instead of a non working one

Reproduction steps

ModifyVehicleTopSpeed(vehicle, 1.5) on a modded vehicle.

Importancy

Slight inconvenience

Area(s)

Natives

Specific version(s)

FiveM

Additional information

No response

mcNuggets1 avatar Oct 03 '25 08:10 mcNuggets1

Currently most appropriate way to modify a car top speed and acceleration is to edit his handling parameters. You can either change this parameters in the handling.meta file, or do it at runtime with SetVehicleHandlingFloat.

The most important handling parameters to edit vehicle speed are fInitialDriveMaxFlatVel and fInitialDriveForce. This wiki resource give you useful informations about handling parameters behavior https://gtamods.com/wiki/Handling.meta.

You can also put an hard speed limit on vehicles at runtime using SetVehicleMaxSpeed but it will obviously feel less natural.

william-des avatar Oct 03 '25 08:10 william-des

I did test with both fInitialDriveMaxFlatVel , fInitialDriveForce and both didnt decrease my speed, no matter what value I used. I tested most of the handling paramters related to speed or drag.

Clamping physical speed is not an ideal solution, as you said, it doesn' feel natural to the player.

mcNuggets1 avatar Oct 03 '25 08:10 mcNuggets1

local vehicle = GetVehiclePedIsIn(ESX.PlayerData.ped)

print(GetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveForce'))
print(GetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveMaxFlatVel'))

SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveForce', 0.1)
SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveMaxFlatVel', 0.1)

Does absolutely nothing. The vehicle will move at the same speed.

mcNuggets1 avatar Oct 03 '25 08:10 mcNuggets1

IIRC you sometimes have to use a different native: For example:

SetVehicleHandlingField over SetVehicleHandlingFloat for some values. That might be something you can try out. @mcNuggets1

There is also

SetHandlingFloat SetHandlingField etc. just checkout the docs. https://docs.fivem.net/natives/?_0x90DD01C

xalva98 avatar Oct 03 '25 08:10 xalva98

SetHandling* is global for the vehicle model. Thats not something I would be looking for. I'm just doing an offroad script that doesnt suck.

I gave SetVehicleHandlingField a try. Doesn't work at all.

mcNuggets1 avatar Oct 03 '25 10:10 mcNuggets1

Your issue isn’t that the natives are “broken”; modded vehicles often have:

  • A per-entity speed limiter still active
  • Handling caps like low fInitialDriveMaxFlatVel, high fInitialDragCoeff, very short gearing
  • Changes applied too early or without network ownership (so they’re ignored/reset)
  • Wrong values (e.g., setting fInitialDriveForce to 0.1 is a nerf, not a buff)

Do this, in this order, per vehicle (not model-wide), after you’re in the driver seat and own the entity:

  1. Disable the per-entity limiter
  • SetVehicleMaxSpeed(vehicle, 0.0) removes the entity clamp. Without this, your changes feel like “nothing happened.”
  1. Raise the speed ceiling per entity
  • Use a large value so handling doesn’t clamp top speed early:
  • SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveMaxFlatVel', 1000.0)
  • Don’t set it to 0.1; that clamps speed massively.
  1. Add engine shove
  • Torque multiplier is multiplicative: SetVehicleEngineTorqueMultiplier(vehicle, 1.3–1.6)
  • Power multiplier is additive: SetVehicleEnginePowerMultiplier(vehicle, 10.0–40.0)
  1. Optional for modded cars that brickwall early
  • Slightly reduce drag if aero is too strong:
  • -- SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDragCoeff', 5.0)
  • Help the gearbox reach higher gears faster (short-geared metas):
  • -- SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fClutchChangeRateScaleUpShift', 4.0)
  • -- SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fClutchChangeRateScaleDownShift', 4.0)
  1. Reapply when needed
  • Re-run after entering the vehicle, after repairs/upgrades, or when network ownership changes.

Copy-paste version that fixes your repro

-- Call this after you're in the driver seat; reapply occasionally (e.g., every 1–2s)
local function fixSpeedOnModdedVehicle(vehicle)
  if vehicle == 0 or not DoesEntityExist(vehicle) then return end

  -- If in MP, request control so changes stick
  if not NetworkHasControlOfEntity(vehicle) then
    NetworkRequestControlOfEntity(vehicle)
  end

  -- 1) Remove per-entity limiter
  SetVehicleMaxSpeed(vehicle, 0.0)

  -- 2) Raise top-speed ceiling (m/s). 1000 is a safe “no clamp” ceiling.
  SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveMaxFlatVel', 1000.0)

  -- 3) Add shove (pick sane values; don’t go extreme or it gets arcadey)
  SetVehicleEngineTorqueMultiplier(vehicle, 1.5)  -- 1.0 = stock, 1.5 = +50% torque
  SetVehicleEnginePowerMultiplier(vehicle, 30.0)  -- additive, ~+30% power feel

  -- Optional helpers for metas that brickwall or short-shift badly:
  -- SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDragCoeff', 5.0)
  -- SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fClutchChangeRateScaleUpShift', 4.0)
  -- SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fClutchChangeRateScaleDownShift', 4.0)
end

-- Example usage matching your ESX context:
local ped = PlayerPedId()
local vehicle = GetVehiclePedIsIn(ped, false)
if vehicle ~= 0 and GetPedInVehicleSeat(vehicle, -1) == ped then
  -- Print current values if you want to inspect them
  print('fInitialDriveForce', GetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveForce'))
  print('fInitialDriveMaxFlatVel', GetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveMaxFlatVel'))

  -- IMPORTANT: do not set these to 0.1 (that makes it slower)
  fixSpeedOnModdedVehicle(vehicle)
end

Off-road script tip (since you don’t want model-wide changes)

  • Keep everything per-entity.
  • Detect off-road surfaces (dirt/grass/sand). When off-road, apply the function with a mild torque multiplier (e.g., 1.3–1.4). When back on asphalt, restore to stock (or a mild 1.1).
  • Reapply on an interval (250–1500 ms) so repairs/ownership changes don’t undo your tweak.

Why your current snippet “does nothing”

  • You never cleared the per-entity limiter, so speed is still capped by the entity.
  • You set fInitialDriveForce and fInitialDriveMaxFlatVel to 0.1, which is a huge nerf.
  • If you set too early or without ownership, GTA may ignore or immediately reset your changes.

Example

local OFFROAD_MATERIALS = { [-1595148316] = true, -- grass [510490462] = true, -- dirt [-1885547121] = true, -- mud [-1942898710] = true, -- sand }

local function ensureEntityControl(entity, timeoutMs) timeoutMs = timeoutMs or 500 if not DoesEntityExist(entity) then return false end local start = GetGameTimer() while not NetworkHasControlOfEntity(entity) and GetGameTimer() - start < timeoutMs do NetworkRequestControlOfEntity(entity) Citizen.Wait(0) end return NetworkHasControlOfEntity(entity) end

local function applySpeedBoost(vehicle, torqueMult) if not DoesEntityExist(vehicle) then return end if not ensureEntityControl(vehicle, 800) then return end

-- Disable per-entity cap and raise ceiling
SetVehicleMaxSpeed(vehicle, 0.0)
SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveMaxFlatVel', 1000.0)

local t = torqueMult or 1.4
if t < 0.1 then t = 0.1 end
SetVehicleEngineTorqueMultiplier(vehicle, t)

local powerAdd = (t - 1.0) * 60.0
SetVehicleEnginePowerMultiplier(vehicle, powerAdd)

-- Optional gearbox helpers (commented by default)
-- SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fClutchChangeRateScaleUpShift', 4.0)
-- SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fClutchChangeRateScaleDownShift', 4.0)

end

local function restoreStockFeel(vehicle) if not DoesEntityExist(vehicle) then return end if not ensureEntityControl(vehicle, 800) then return end

SetVehicleEngineTorqueMultiplier(vehicle, 1.0)
SetVehicleEnginePowerMultiplier(vehicle, 0.0)
SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveMaxFlatVel', 250.0)

end

local function getGroundMaterialHash(entity) local from = GetEntityCoords(entity) + vector3(0.0, 0.0, 1.0) local to = from + vector3(0.0, 0.0, -5.0) local ray = StartShapeTestRay(from.x, from.y, from.z, to.x, to.y, to.z, 1, entity, 7) local _, hit, _, _, materialHash = GetShapeTestResultIncludingMaterial(ray) if hit == 1 then return materialHash end return nil end

-- Main control loop: boost only off-road Citizen.CreateThread(function() local lastWasOffroad = false while true do local ped = PlayerPedId() if IsPedInAnyVehicle(ped, false) then local veh = GetVehiclePedIsIn(ped, false) if GetPedInVehicleSeat(veh, -1) == ped then local mat = getGroundMaterialHash(veh) local isOff = mat and OFFROAD_MATERIALS[mat] == true if isOff and not lastWasOffroad then applySpeedBoost(veh, 1.4) elseif not isOff and lastWasOffroad then restoreStockFeel(veh) -- Mild assist on-road or set to 1.0 by restoring only applySpeedBoost(veh, 1.1) end lastWasOffroad = isOff end else lastWasOffroad = false end Citizen.Wait(250) end end)

weturnhell avatar Oct 03 '25 13:10 weturnhell

Thanks for taking the time. I did most of it already.

I did set them to 0.1 for testing, if they would make any difference, it didnt.

SetVehicleEnginePowerMultiplier has issues with modded vehicles making them sometimes go slower, instead of faster + the other way around. But I will test the function again.

The driver also is always network controller i think.

Very nice of you to take this much time for a stranger. Much appreciated.

This should do the trick then and make the vehicle extremely slow, but it doesnt do ANYTHING at all. You told me, that my code doesnt work, because I dont remove the speed limiter before REDUCING speed, which didnt make sense for me, but I just rolled with it.

So still the Natives for torque, speed DO work, but they only work on vanillas correctly.

This should make the vehicle SUPER slow, but it doesnt do anything.

`local vehicle = GetVehiclePedIsIn(ESX.PlayerData.ped)

SetVehicleMaxSpeed(vehicle, 0.0)

print(GetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveForce'))
print(GetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveMaxFlatVel'))

SetVehicleHandlingField(vehicle, 'CHandlingData', 'fInitialDriveForce', 0.1)
SetVehicleHandlingField(vehicle, 'CHandlingData', 'fInitialDriveMaxFlatVel', 0.1)`

mcNuggets1 avatar Oct 04 '25 08:10 mcNuggets1