Electric vehicles
Needed only if you turn on Battery regeneration in /hud → Admin → Vehicles.
Why a patch is needed at all
Section titled “Why a patch is needed at all”GTA V has no battery. Electric vehicles use the same fuel field as petrol cars, and the
game does not even drain it by default — that is FiveM’s SetFuelConsumptionState, and it
only ever drains. There is no regeneration anywhere in the game.
So the work is split:
| Side | Job |
|---|---|
| Aurora HUD | Measures acceleration at 10 Hz and knows which models are electric |
ox_fuel |
Owns the fuel value and writes it |
Two resources writing the same value would fight — one overwrites, the other undoes it. The
bridge is a read-and-clear export: the HUD accumulates at its own rate, ox_fuel drains
at its own rate. The two do not have to line up, and a missed call never double-credits.
The patch
Section titled “The patch”Two blocks in ox_fuel/client/init.lua.
1. Before local function startDrivingVehicle()
Section titled “1. Before local function startDrivingVehicle()”local AURORA_HUD = 'hud' -- the Aurora HUD resource name
local function auroraRegen() -- The HUD keeps this statebag LOCAL: it is only true in an ELECTRIC vehicle with -- regeneration enabled. Reading it is cheap. Without it, this patch would pay the -- cross-resource export boundary (~0.2ms) once a second in ANY car, petrol included, -- only to be handed 0. It also saves a GetResourceState call: if the flag is true, -- the HUD is running and set it. if not LocalPlayer.state.aurora_ev_regen then return 0 end local ok, gain = pcall(function() return exports[AURORA_HUD]:ConsumeElectricRegen() end) return (ok and type(gain) == 'number' and gain > 0) and gain or 0endIf you renamed the HUD resource, change AURORA_HUD to match. The dependency is
optional: without the HUD the flag never exists, this is one nil read per second, and
ox_fuel behaves exactly as before.
2. Inside the driving loop, right after the leaking-tank block
Section titled “2. Inside the driving loop, right after the leaking-tank block” if fuelAmount > 0 then if GetVehiclePetrolTankHealth(vehicle) < 700 then newFuel -= math.random(10, 20) * 0.01 end
-- AURORA PATCH local regen = auroraRegen() if regen > 0 then newFuel = math.min(newFuel + regen, 100.0) endA punctured tank still leaks. Regenerating does not plug a hole.
Safeguards
Section titled “Safeguards”All of these live on the HUD side, so you do not configure them in ox_fuel:
| Guard | Why |
|---|---|
| Ceiling, default 85% | Braking never takes you above it; the rest needs a charger. Stops a long descent from filling the car, and matches reality — a nearly full battery will not take charge. |
| 8 m/s² limit | Above that it is not braking, it is a crash. Without the cap, hitting a wall would hand you half a battery. It is capped rather than ignored so there is no step change. |
| Intensity, default 30% | How much of the braking energy comes back. ~30% is the real-world order of magnitude. |
| Only while slowing, above 2 m/s | Stationary, there is no kinetic energy to recover. |
| Credit cleared on vehicle change | Leaving with undelivered charge must not hand it to the next car. |
How “regenerating” is decided
Section titled “How “regenerating” is decided”The test is whether the motor is braking, not whether the car is slowing down — those are not the same thing. The balance is of forces, per unit of mass, which cancels out:
motor = measured acceleration + gravity for/against + dragTwo calibrations do the rest:
- Drag is per vehicle, via
GetVehicleEstimatedMaxSpeed. At top speed on the flat a car is by definition giving everything it has, so drag at that point is full scale. A fixed curve assuming 200 km/h for every car underestimated it badly in a slow one. - No regeneration while on the throttle (
GetVehicleThrottleOffset). In a real electric car it starts when you lift off or brake.
With that, every case falls out on its own:
| Situation | Readout |
|---|---|
| Coasting downhill, off the throttle | 0% — gravity is doing the work, the battery gives nothing |
| Downhill braking on the motor | −50% · charging |
| Downhill, throttle floored | +100% · consuming |
| Flat, at top speed, floored | +100% · consuming |
| Uphill at constant speed | +58% · consuming — it is fighting gravity |
What you actually get
Section titled “What you actually get”At the default 30% intensity:
| Situation | Gain |
|---|---|
| Hard stop, 100 → 0 km/h | 0.11% of battery |
| Gentle stop, 50 → 0 km/h | 0.03% |
| Crashing at 100 km/h | 0.11% — same as a hard stop, which is the cap working |
| 60 accelerate-brake cycles | 1.6%, having spent far more than that accelerating |
| Descending all of Mount Chiliad (700 m, braking) | ~1.7% |
Chiliad gives so little because the energy is limited by height, not by time: 700 m of descent is about 6.4% of a battery in raw energy, and only 30% of that comes back.
There is no perpetual motion here — to come down you had to go up, and going up costs far more than the descent returns.