Documentation

Handling

Every physics field with its unit and range, a tuning order that works, and what to check when a car feels wrong.

How a car accelerates, corners, settles over bumps and stops. This page owns every physics field: its unit, its accepted range and what changing it actually does. API covers how to read and write these values from a script. Model standard covers measuring a new car in the first place.

Before you change a number

A World Vehicles car is a composite RDR object with custom four-wheel physics. The C# solver calculates suspension and tyre forces, gearing and drag; the RedM bridge reads real body and ground contacts and applies the resulting impulses.

Two consequences worth holding on to:

  • A good result in the solver does not prove the asset, the ground probe or the native host is behaving. Check contacts before blaming values.
  • Field names from other Cfx platforms and handling.meta do not transfer. The fields below are the entire vocabulary.

Each car keeps its own baseline in its module:

text
wv_<vehicle>/vehicle.json
  profiles
    <profileId>
      physics

Keys are case-sensitive: EngineTorque, never engineTorque. Values are JSON numbers, never quoted strings. Unknown keys are rejected, so inventing Acceleration or TopSpeedMph creates nothing.

Four scopes, and picking the right one

Scope Use it for Affects Survives restart
Model baseline The car's stock definition That profile wherever it loads Yes, it is in the module's vehicle.json
Model settings Server-specific stock handling Every car of that profile, and future spawns Only if you save it
Instance handling One upgrade or one experiment A single car No
Global settings Transmission policy, controls, speedometer, debug The whole fleet Only if you save it

"Global handling" means the shared baseline for one model. It does not mean every car should get the same wheelbase, inertia or suspension.

The in-game /wvmenu panel exposes all four scopes; what it can do and who may open it is in Getting started.

Handling changes need the car assembled and stopped at no more than 0.6 m/s. A model edit needs every car of that profile stopped. A global transmission change needs the whole fleet stopped. Who is allowed to make each change is in the API reference.

Units and axes

Quantity Unit
Position, radius, suspension length Metres, model-local X right, Y forward, Z up
Wheel order 0 left front, 1 right front, 2 left rear, 3 right rear
Mass kg
Body unit inertia m², multiply by mass for full rotational inertia
Wheel rotational inertia kg·m²
Force, torque N, N·m
Spring, damping N/m, N·s/m
Steering angle and rate Radians and rad/s
Panel and light rotations, heading Degrees
Velocity m/s; mph = m/s ÷ 0.44704, km/h = m/s × 3.6

The steering-in-radians, everything-else-in-degrees split catches people out more than any other convention here.

The whole configuration has to validate together, not just each field:

  • MinLength < RestLength and IdleRpm < RedlineRpm.
  • MaxFrameTime >= MaxStep.
  • Exactly four ordered mounts, at least one driven wheel.
  • GearRatios holds 1 to 8 positive entries. The range check does not design a gearbox for you; use a sensibly descending sequence.
  • Vectors are exactly three finite numbers. No NaN, no infinity, no numeric strings.

The ranges below are accepted limits, not recommended targets. Your installed build answers authoritatively through getHandlingSchema, which also returns input steps and read-only flags.

Geometry and solver, read-only

These describe the converted body. They are not performance settings, and the editor will not let you change them live.

Field Range Meaning
Mass 100–50000 kg The collision body's intended mass. Lightening the number while the asset stays heavy is not a speed fix.
InertiaX/Y/Z 0.001–100 m² Whole-body unit inertia. X mostly pitch, Y roll, Z yaw.
COM ±10 m Real local centre of mass. Dropping it arbitrarily hides bad geometry and creates odd roll.
Mount0..3 ±10 m Suspension top anchors in wheel order. Not tyre contact points.
WheelRadius 0.05–2 m Final tyre radius, shared by the solver. Not a gearing shortcut.
MaxStep 0.001–0.02 s Maximum solver substep. Not an acceleration multiplier.
MaxFrameTime 0.001–0.25 s Long-frame rejection threshold. Raising it to hide stalls costs stability.
ForceScale 0.01–10 Native bridge scale. Not an engine upgrade.

Changing these means changing the asset. See Model standard.

Suspension

Field Range Effect
SpringStiffness 100–500000 N/m Per-wheel spring rate. Too low bottoms out, too high amplifies every bump.
DamperRate 0–100000 N·s/m Base damping. More settles oscillation, too much makes bumps harsh.
CompressionDampingMultiplier 0–4 Damping while the body moves toward the surface.
ReboundDampingMultiplier 0–4 Damping while it moves away. Excess rebound holds the car down through repeated bumps.
RestLength 0.01–3 m Uncompressed suspension length. Raises equilibrium height; it is not ground clearance.
MinLength 0–2 m Fully compressed length. Must stay below rest length.
FrontAntiRoll 0–100000 N/m Front axle roll stiffness.
RearAntiRoll 0–100000 N/m Rear equivalent. Extreme rear stiffness starves the inside wheel.
MaxWheelLoad 100–200000 N Per-wheel support cap. Too low leaves the car unsupported.

Static compression on level ground works out as:

text
compression ≈ Mass × 9.81 / (4 × SpringStiffness)
loaded length ≈ max(MinLength, RestLength − compression)

That is a setup estimate, not the exact native equilibrium: weight distribution, geometry, damping and the bridge all still matter. At 1900 kg and 31000 N/m it predicts about 0.15 m of compression.

To raise one car by ten centimetres use setSuspensionHeight with 0.10. It adds to the model baseline rest length, so calling it twice does not add twenty. To change stock ride height for the whole model, edit RestLength.

For a heavier, more planted feel, get clearance and travel right first, then damping, then spring and anti-roll balance, then steering. Do not fake weight by letting the body sink into its own collision.

Tyres and ground contact

Field Range Effect
LongitudinalGrip 0.05–5 Peak drive and braking force against supported load.
LateralGrip 0.05–5 Peak cornering force. Very high values make steering abrupt and hide bad balance.
RollingResistance 0–1 Rolling loss. Not a speed governor.
TireB 0.01–100 Slip-curve stiffness: how fast force builds with slip.
TireC 0.01–2 Slip-curve shape. Tune with B and grip together.
WheelInertia 0.01–100 kg·m² Per-wheel rotational inertia. Changes spin-up, not body mass.
Driven0..3 Boolean Which wheels get torque. Core default is rear drive.
Capsule Boolean Capsule ground tests instead of rays. Does not create a wheel collider.
ProbeRadius 0–2 m Capsule radius. Large values catch surfaces you did not mean.
TraceFlags 0–65535 RedM shape-test bitmask. Not the drawable IncludeFlags mask.
ContactTimeout 0.001–2 s Maximum age of a ground sample. Extending it keeps stale ground rather than fixing lost contact.
VisualRange 1–1000 m Client visual culling distance.

The tyre model is peak × sin(C × atan(B × slip)) with a combined longitudinal and lateral friction ellipse. Acceleration and cornering share the same available grip.

Wheel visuals are separate props. A spinning wheel proves nothing about contact, load or torque, so check per-wheel contact flags and normal loads before touching grip. Equally, a working tyre probe is not a body collision test: a car can support itself perfectly while players walk straight through it.

Explicit physics.Capsule, TraceFlags, ProbeRadius, ContactTimeout and VisualRange take precedence over the older probe.* and profile-level fallbacks. Editing the legacy fields does not reach this solver.

Engine, gearbox and brakes

Field Range Effect
EngineTorque 0–10000 N·m Peak torque before the RPM curve, ratios and drivetrain loss. Not horsepower.
IdleRpm 100–5000 Lower running bound.
RedlineRpm 500–20000 Upper bound, must exceed idle. Drive cuts near redline.
GearRatios 1–8 values, each 0.1–20 Forward ratios in order. The count is the gear count.
FinalDrive 0.1–20 Multiplies every ratio. Higher means more wheel torque, less speed per RPM.
ReverseRatio 0.1–20 Separate from the forward array.
DrivetrainEfficiency 0.01–1 Fraction of engine output that reaches the wheels.
MaxSpeedMps 0–100 m/s Forward torque-governor target. Zero disables the governor, not gravity.
BrakeTorque 0–50000 N·m Applied to each wheel at full input, not divided among four.
HandbrakeTorque 0–50000 N·m Per rear wheel at full input.
EngineBrakingTorque 0–5000 N·m Extra braking on driven wheels off-throttle with the engine on.

Torque is shared across the driven wheels. The RPM curve and shift thresholds live in code; there is no JSON torque curve to author.

Shift policy

Automatic upshifts at 85% of redline, downshifts at 30%, with a 0.4 second cooldown. A manual downshift that would over-rev is refused. Swapping between forward and reverse needs both longitudinal and horizontal speed under 0.8 m/s. That policy explains most rejected inputs; sending the same gear change every frame will not get round it.

A target is not a guarantee

Target MaxSpeedMps km/h
80 mph 35.7632 128.75
160 mph 71.5264 257.50

The governor eases drive away over the last 0.5% before the target. It never clamps velocity and never brakes, so a car can pass the target downhill and never reach it uphill.

To sanity-check gearing, the no-slip redline speed in top gear is:

text
speed_mps = RedlineRpm × 2π × WheelRadius / (60 × last_GearRatio × FinalDrive)

That is an upper bound. Real speed still depends on grip, torque, drag, slope and damage.

The known host ceiling

RedM's native damping imposes a speed ceiling that more torque does not solve. The workaround is a controller setting rather than a physics field, and every use of it re-checks that the body is assembled, that the authored and live model hashes match, and that this client still owns the car. Switches cover the fleet by module group:

Switch What it covers
hostPhysics.pioneerDampingOverride The four Pioneer modules
hostPhysics.*DampingOverride Any further module group you install, each with its own switch

Each one takes a literal boolean, each needs the exact matching wv_<profile>_body model, and each needs a core restart. None of them is a wildcard: a lookalike profile, a clearance test variant or a model with a similar name is not covered, and no switch enables another switch's cars. A shipped production config has them on, because that is the state the prepared fleet was driven in.

Rolling one back means turning the flag off and spawning a fresh car. The native slot has no readback, so a car that already received the treatment is not restored by clearing the flag.

A recorded run reached about 56.83 mph on a mixed route with improved acceleration. That was not a clean top-speed test and says nothing about any other model.

Steering and drag

Field Range Effect
SteeringAngleLimit 0.01–1 rad Low-speed lock. 0.5236 rad is 30°.
SteeringRate 0.01–20 rad/s How fast steering reaches its target. Lower feels heavier.
SteeringSpeedSensitivity 0–1 s/m Reduces available angle as speed rises. Zero disables.
SteeringRateSpeedSensitivity 0–1 s/m Reduces response rate as speed rises.
DragCoefficientArea 0–30 m² Drag coefficient times frontal area, not the coefficient alone.
AirDensity 0–5 kg/m³ Keep a sensible atmosphere rather than using it as an upgrade.
text
angle_limit   = SteeringAngleLimit / (1 + abs(forward_speed) × SteeringSpeedSensitivity)
steering_rate = SteeringRate       / (1 + abs(forward_speed) × SteeringRateSpeedSensitivity)

Drag opposes velocity and grows with its square. Zeroing both drag and rolling loss to hit a number also ruins coasting and downhill behaviour.

Upgrade presets

Presets are always recomputed from the current model baseline, never multiplied onto the previous upgrade, so repeating one never compounds.

Preset Input What it does
Engine level 0–4 Baseline torque and target ×1.00 / 1.10 / 1.20 / 1.30 / 1.40, with taller final drive and redline headroom.
Top speed 20–200 mph A full performance preset: torque from the squared speed ratio, taller gearing, new target.
Suspension firmness 0.5–2 Springs and both anti-roll rates ×factor, base damping ×√factor. Keeps the chosen height.
Suspension height −0.2 to 0.3 m Baseline rest length plus offset. Keeps the chosen firmness.

On an 80 mph car, engine levels request 80, 88, 96, 104 and 112 mph. Level 4 is plus forty percent, not double.

The top-speed preset and engine levels work differently, so do not reach for setTopSpeedMph when you only want to lower the governor: edit MaxSpeedMps directly for that.

When the model baseline changes, valid presets are rebased onto it, custom top-speed presets keep their mph, and raw overrides on the fields you just edited give way. Re-read effective handling afterwards. The exact calls are in the API reference.

A tuning order that works

  1. Baseline. Record versions, profile, effective handling, transmission mode, damage and upgrade state. Repair or respawn the car, close the menu, engine running.
  2. Geometry before power. Tyre radius, mounts, body bounds, clearance, four accepted contacts on level road. A chassis dragging on the road cannot be fixed with torque.
  3. Ride height and travel. Loaded length against minimum and rest. Leave compression travel; the underside must clear without the wheels floating.
  4. Settle the suspension. One repeatable bump slowly. Springs and base damping in modest steps, then compression and rebound separately. A row of bumps exposes rebound problems.
  5. Drivetrain. Driven wheels, gear changes, top-gear redline speed above your target. Then torque, judged by actual acceleration rather than engine pitch.
  6. Grip and brakes. Straight braking and acceleration on one surface. Balance longitudinal against lateral without killing all slip. Test handbrake release on a slope.
  7. Cornering. Steady radius at low then moderate speed, then a lane change. Change response and anti-roll separately. Check the second client before calling drift a grip problem.
  8. Extremes. Long straight, hill, bumps, a jump, rollover, collision, water, ownership transfer. Record failures instead of compensating elsewhere.
  9. Save what you accepted. Persist the whole intended patch, restart the core, spawn fresh and retest briefly.

Five to ten percent is a sensible experimental step. Keep the previous exact values so you can go back.

Under-terrain recovery

A car that ends up under the map is put back without a respawn. The controller keeps a recent safe pose, recorded while all four wheels had fresh static contact under an upright dry body, and only accepts one from the last four seconds and within forty metres. To act on it, it has to witness the body crossing down through an upward-facing static surface along real recent movement, confirm more than a metre of penetration with a second ray, and see no wheel support. Being flipped, airborne or simply low in the world never triggers it, and no highest-ground query is used, so the road above a cave is not a destination.

The saved point is checked again at all four contacts, a coarse cabin test rejects it if something is standing there, and the car is then restored with fifteen centimetres of clearance, velocity and solver history cleared, a 150 ms freeze and a five second cooldown. It is the same chassis: occupants and assembled parts come with it, nothing is repaired, no plate is rerolled and no handling value changes.

It is a safety net, not a guarantee. No recent safe pose, missing terrain, an obstructed return point or an ownership change makes it skip. A successful return prints one line to the console and nothing to chat.

When something is wrong

Symptom Check first
Wheels spin, car barely moves Driven-wheel contacts, normal loads, slip, chassis collision, brakes, flooding, ownership
Feels stuck in first gear Real gear and RPM, transmission mode, bindings, driven-wheel support, ratios. Audio is not telemetry
More torque, same top speed Gearing, redline, governor target, drag equilibrium, slope, host ceiling
Bounces standing still Mounts, radius, self-collision, static clearance, contact freshness, then damper balance
Glued to the ground Rebound damping, stale contact diagnostics, rest logic. Compare supported and airborne frames
Falls through the road Streaming and native body collision, probe acceptance, sample age. Grip cannot load missing collision
Others see it drifting sideways Ownership, replicated heading, snapshot age, contact projection. Compare owner and remote views
Cannot climb a hill Drive axle support, wheel load and slip, torque and gearing, body scraping
Editor rejects a sane value Cross-field constraints, every affected car stopped, read-only fields, the installed schema
A saved value reverted Whether the field was actually in the saved patch, correct profile, both journal files
JSON edit did nothing Restart the core, then check saved overrides and instance upgrades against effective handling

For speed, keep your measurements straight: telemetry.speed is signed forward m/s, while getSpeed is absolute 3D speed including vertical movement. A jump adds vertical speed and wheel RPM can rise with no forward travel. At a steady top speed, near-zero acceleration is normal because forces balance.

To record a run, enable developer debug for the test and turn it off afterwards. A useful pattern is: fresh car, wait 3 s, engine on, accelerate on a safe level straight for 30 s, brake fully, wait 10 s, exit. Do hills, bumps and ownership migration as separate runs rather than one unexplained number. Diagnostics land in the core resource under exports/diagnostics/.