Vehicle System
Introduction
DayZ vehicles are entities that extend the transport system. Cars extend CarScript, boats extend BoatScript, and both inherit from Transport. Vehicles have fluid systems, parts with independent health, gear simulation, and physics managed by the engine. This chapter covers the API methods you need to interact with vehicles in scripts.
Class Hierarchy
EntityAI
└── Transport // 3_Game - base for all vehicles
├── Car // 3_Game - engine-native car physics
│ └── CarScript // 4_World - scriptable car base
│ ├── CivilianSedan
│ ├── OffroadHatchback
│ ├── Hatchback_02
│ ├── Sedan_02
│ ├── Truck_01_Base
│ └── ...
└── Boat // 3_Game - engine-native boat physics
└── BoatScript // 4_World - scriptable boat baseTransport (Base)
File: 3_Game/entities/transport.c
The abstract base for all vehicles. Provides seat management and crew access.
Crew Management
proto native int CrewSize(); // Total number of seats
proto native int CrewMemberIndex(Human crew_member); // Get seat index of a human
proto native Human CrewMember(int posIdx); // Get human at seat index
proto native Human CrewGetOut(int posIdx); // Force crew member out of seat (returns the ejected human)
proto native void CrewDeath(int posIdx); // Kill crew member in seatCrew Entry
int GetAnimInstance(); // Scripted (overridable) method, not proto native
proto native int CrewPositionIndex(int componentIdx); // Component to seat index
proto void CrewEntry(int posIdx, out vector pos, out vector dir); // Entry point/direction in model space
proto void CrewEntryWS(int posIdx, out vector pos, out vector dir); // Entry point/direction in world spaceExample --- eject all passengers:
void EjectAllCrew(Transport vehicle)
{
for (int i = 0; i < vehicle.CrewSize(); i++)
{
Human crew = vehicle.CrewMember(i);
if (crew)
{
vehicle.CrewGetOut(i);
}
}
}Car (Engine Native)
File: 3_Game/entities/car.c
Engine-level car physics. All proto native methods that drive the vehicle simulation.
Engine
proto native bool EngineIsOn();
proto native void EngineStart();
proto native void EngineStop();
proto native float EngineGetRPM();
proto native float EngineGetRPMRedline();
proto native float EngineGetRPMMax();
proto native int GetGear();Fluids
DayZ vehicles have four fluid types defined in the CarFluid enum:
enum CarFluid
{
FUEL,
OIL,
BRAKE,
COOLANT
}proto native float GetFluidCapacity(CarFluid fluid);
proto native float GetFluidFraction(CarFluid fluid); // 0.0 - 1.0
proto native void Fill(CarFluid fluid, float amount);
proto native void Leak(CarFluid fluid, float amount);
proto native void LeakAll(CarFluid fluid);Example --- refuel a vehicle:
void RefuelVehicle(Car car)
{
float capacity = car.GetFluidCapacity(CarFluid.FUEL);
float current = car.GetFluidFraction(CarFluid.FUEL) * capacity;
float needed = capacity - current;
car.Fill(CarFluid.FUEL, needed);
}Speed
proto native float GetSpeedometer(); // Speed in km/h (absolute value)Controls (Simulation)
proto native void SetBrake(float value, float unused0 = 0, bool unused1 = false); // 0.0 - 1.0 (extra params unused)
proto native void SetHandbrake(float value); // 0.0 - 1.0
proto native void SetSteering(float value, bool unused0 = false); // -1.0 - 1.0 (second param unused)
proto native void SetThrottle(float value); // 0.0 - 1.0 (SetThrust is obsolete)
proto native void SetClutch(float value); // SetClutchState is obsoleteWheels
proto native int WheelCount();
proto native bool WheelIsAnyLocked();
proto native SurfaceInfo WheelGetSurface(int wheelIdx);Callbacks (Override in CarScript)
void OnEngineStart();
void OnEngineStop();
void OnContact(string zoneName, vector localPos, IEntity other, Contact data);
void OnFluidChanged(CarFluid fluid, float newValue, float oldValue);
void OnGearChanged(int newGear, int oldGear);
void OnSound(CarSoundCtrl ctrl, float oldValue);CarScript
File: 4_World/entities/vehicles/carscript.c
The scriptable car class that most vehicle mods extend. Adds parts, doors, lights, and sound management.
Part Health
CarScript uses damage zones to represent vehicle parts. Each part can be independently damaged:
// Check part health via the standard EntityAI API
float engineHP = car.GetHealth("Engine", "Health");
float fuelTankHP = car.GetHealth("FuelTank", "Health");
// Set part health
car.SetHealth("Engine", "Health", 0); // Destroy the engine
car.SetHealth("FuelTank", "Health", 100); // Repair the fuel tankDamage Zone Diagram
Common damage zones for vehicles:
| Zone | Description |
|---|---|
"" (global) | Overall vehicle health |
"Engine" | Engine part |
"FuelTank" | Fuel tank |
"Radiator" | Radiator (coolant) |
"Battery" | Battery |
"SparkPlug" | Spark plug |
"FrontLeft" / "FrontRight" | Front wheels |
"RearLeft" / "RearRight" | Rear wheels |
"DriverDoor" / "CoDriverDoor" | Front doors |
"Hood" / "Trunk" | Hood and trunk |
Lights
The light API lives on Transport:
proto native bool LightIsOn(); // True when lights are on
proto native void LightOn(); // Turn lights on
proto native void LightOff(); // Turn lights off
proto native void LightToggle(); // Toggle current light stateDoor Control
Door state is queried with GetCarDoorsState, which returns a CarDoorState value (DOORS_MISSING, DOORS_OPEN, or DOORS_CLOSED):
enum CarDoorState
{
DOORS_MISSING,
DOORS_OPEN,
DOORS_CLOSED
}
int GetCarDoorsState(string slotType); // Returns a CarDoorState valueKey Overrides for Custom Vehicles
override void EEInit(); // Initialize vehicle parts, fluids
override void OnEngineStart(); // Custom engine start behavior
override void OnEngineStop(); // Custom engine stop behavior
override void EOnPostSimulate(IEntity other, float timeSlice); // Per-tick simulation (CarScript)Example --- create a vehicle with full fluids:
void SpawnReadyVehicle(vector pos)
{
Car car = Car.Cast(GetGame().CreateObjectEx("CivilianSedan", pos,
ECE_PLACE_ON_SURFACE | ECE_INITAI | ECE_CREATEPHYSICS));
if (!car)
return;
// Fill all fluids
car.Fill(CarFluid.FUEL, car.GetFluidCapacity(CarFluid.FUEL));
car.Fill(CarFluid.OIL, car.GetFluidCapacity(CarFluid.OIL));
car.Fill(CarFluid.BRAKE, car.GetFluidCapacity(CarFluid.BRAKE));
car.Fill(CarFluid.COOLANT, car.GetFluidCapacity(CarFluid.COOLANT));
// Spawn required parts
EntityAI carEntity = EntityAI.Cast(car);
carEntity.GetInventory().CreateAttachment("CarBattery");
carEntity.GetInventory().CreateAttachment("SparkPlug");
carEntity.GetInventory().CreateAttachment("CarRadiator");
carEntity.GetInventory().CreateAttachment("HatchbackWheel");
}BoatScript
File: 4_World/entities/vehicles/boatscript.c
Scriptable base for boat entities. Similar API to CarScript but with propeller-based physics.
Engine & Propulsion
proto native bool EngineIsOn();
proto native void EngineStart();
proto native void EngineStop();
proto native float EngineGetRPM();Fluids
Boats use a separate BoatFluid enum that only defines FUEL:
float fuel = boat.GetFluidFraction(BoatFluid.FUEL);
boat.Fill(BoatFluid.FUEL, boat.GetFluidCapacity(BoatFluid.FUEL));Speed & Propulsion
Boat does not expose GetSpeedometer() (that method exists only on Car). Read engine RPM and propeller velocity instead:
proto native float EngineGetRPM(); // Engine rpm
proto native float PropellerGetAngularVelocity(); // Propeller angular velocityExample --- spawn a boat:
Boat_01 is not a directly spawnable class; spawn one of the concrete color variants (Boat_01_Blue, Boat_01_Orange, Boat_01_Black, Boat_01_Camo):
void SpawnBoat(vector waterPos)
{
BoatScript boat = BoatScript.Cast(
GetGame().CreateObjectEx("Boat_01_Blue", waterPos,
ECE_CREATEPHYSICS | ECE_INITAI)
);
if (boat)
{
boat.Fill(BoatFluid.FUEL, boat.GetFluidCapacity(BoatFluid.FUEL));
}
}Vehicle Interaction Checks
Checking if a Player is in a Vehicle
PlayerBase player;
if (player.IsInVehicle())
{
EntityAI vehicle = player.GetDrivingVehicle();
CarScript car;
if (Class.CastTo(car, vehicle))
{
float speed = car.GetSpeedometer();
Print(string.Format("Driving at %1 km/h", speed));
}
}Finding All Vehicles in the World
void FindAllVehicles(out array<Transport> vehicles)
{
vehicles = new array<Transport>;
array<Object> objects = new array<Object>;
array<CargoBase> proxyCargos = new array<CargoBase>;
// Use a large radius from center of map
GetGame().GetObjectsAtPosition(Vector(7500, 0, 7500), 15000, objects, proxyCargos);
foreach (Object obj : objects)
{
Transport transport;
if (Class.CastTo(transport, obj))
{
vehicles.Insert(transport);
}
}
}Summary
| Concept | Key Point |
|---|---|
| Hierarchy | Transport > Car/Boat > CarScript/BoatScript |
| Engine | EngineStart(), EngineStop(), EngineIsOn(), EngineGetRPM() |
| Fluids | CarFluid enum: FUEL, OIL, BRAKE, COOLANT |
| Fill/Leak | Fill(fluid, amount), Leak(fluid, amount), GetFluidFraction(fluid) |
| Speed | GetSpeedometer() returns km/h |
| Crew | CrewSize(), CrewMember(idx), CrewGetOut(idx) |
| Parts | Standard damage zones: "Engine", "FuelTank", "Radiator", etc. |
| Creation | CreateObjectEx with ECE_PLACE_ON_SURFACE | ECE_INITAI | ECE_CREATEPHYSICS |
| 1.28 Config | useNewNetworking, wheelHubFriction, doubled brake torque values |
| 1.28 Physics | Updated Bullet Physics, new Contact API fields, suspension always active |
| 1.29 Experimental | Physics multithreading, Transport sleep, dynamic collision for all transport |
Best Practices
- Always include
ECE_CREATEPHYSICS | ECE_INITAIwhen spawning vehicles. Without physics, the vehicle falls through the ground. Without AI init, the engine simulation does not start and the vehicle cannot be driven. - Fill all four fluids after spawning. A vehicle missing oil, brake fluid, or coolant will damage itself immediately when the engine starts. Use
GetFluidCapacity()to get correct max values per vehicle type. - Null-check
CrewMember()before operating on crew. Empty seats returnnull. IteratingCrewSize()without checking each index causes crashes when seats are unoccupied. - Use
GetSpeedometer()instead of computing velocity manually. The engine's speedometer accounts for wheel contact, transmission state, and physics correctly. Manual velocity calculations from position deltas are unreliable.
Compatibility & Impact
Mod Compatibility: Vehicle mods commonly extend
CarScriptwith modded classes. Conflicts arise when multiple mods override the same callbacks likeOnEngineStart()orEOnSimulate().
- Load Order: If two mods both
modded class CarScriptand overrideOnEngineStart(), only the last-loaded mod runs unless both callsuper. Vehicle overhaul mods should always callsuperin every callback. - Modded Class Conflicts: DayZ Expansion Vehicles ships its own custom vehicle base class; mods that also touch
EEInit()or fluid initialization onCarScriptfrequently conflict with it. Test with both loaded. - Performance Impact:
EOnSimulate()runs every physics tick for each active vehicle. Keep logic minimal in this callback; use timer accumulators for expensive operations. - Server/Client:
EngineStart(),EngineStop(),Fill(),Leak(), andCrewGetOut()are server-authoritative.GetSpeedometer(),EngineIsOn(), andGetFluidFraction()are safe to read on both sides.
Vehicle Configuration Changes (1.28+)
Warning (1.28): DayZ 1.28 introduced significant vehicle physics changes. If you are updating a vehicle mod from 1.27 or earlier, read this section carefully.
useNewNetworking Parameter
DayZ 1.28 added the useNewNetworking config parameter for all CarScript classes. Default value is 1 (enabled).
class CfgVehicles
{
class CarScript;
class MyVehicle : CarScript
{
// New networking improves rubber-banding at high ping
useNewNetworking = 1; // default — leave enabled for most mods
// Disable ONLY if your mod modifies vehicle physics
// outside of the SimulationModule config:
// useNewNetworking = 0;
};
};When to disable: If your mod directly manipulates vehicle physics through script (custom EOnSimulate overrides, direct force application, custom wheel logic) rather than through the config-based SimulationModule, the new reconciliation system may fight your changes. Set useNewNetworking = 0; in that case.
wheelHubFriction Parameter (1.28+)
New config variable that defines axle drag when no wheels are attached:
class SimulationModule
{
class Axles
{
class Front
{
wheelHubFriction = 0.5; // How quickly vehicle decelerates with missing wheels
};
};
};Brake Torque Migration (1.28)
Breaking Change: Prior to 1.28, brake and handbrake torque were applied twice due to a bug. This was fixed in 1.28. If you are migrating a vehicle mod, double your
maxBrakeTorqueandmaxHandbrakeTorquevalues to maintain the same braking feel.
// Pre-1.28 (bug: applied twice, so effective value was 2x)
maxBrakeTorque = 2000;
maxHandbrakeTorque = 3000;
// Post-1.28 (fix: applied once, so double to match old behavior)
maxBrakeTorque = 4000;
maxHandbrakeTorque = 6000;Suspension Always Active (1.28+)
Vehicle suspension is now always active while the vehicle is awake. Previously, suspension could be inactive in certain states. This improves stability but may change the feel of custom suspension tuning.
Bullet Physics Update (1.28)
The Bullet Physics library was updated to the latest Enfusion version. Subtle differences in collision response, friction, and restitution may occur. Test all custom vehicle configurations thoroughly.
Physics Contact API Changes (1.28)
The Contact class was modified:
Removed:
MaterialIndex1,MaterialIndex2Index1,Index2
Added:
ShapeIndex1,ShapeIndex2--- identify which shape in a compound body was hitVelocityBefore1,VelocityBefore2--- pre-collision velocitiesVelocityAfter1,VelocityAfter2--- post-collision velocities
Changed:
Material1,Material2--- type changed fromdMaterialtoSurfaceProperties
Mods that read Contact data in OnContact must update to the new variable names and types.
Vehicle Changes in 1.29 (Experimental)
Note: These changes are from DayZ 1.29 experimental and may change before stable release.
Bullet Physics Multithreading (1.29 Experimental)
Multithreading support was enabled for the Bullet Physics library. Server stress tests showed up to 400% FPS improvement (9 FPS to 50 FPS). Vehicle mods that rely on specific physics timing or make physics calls from script callbacks should be tested extensively.
Transport Sleep (1.29 Experimental)
Physics functions were added directly on Transport to allow vehicles to sleep when at rest. Inactive bodies no longer receive EOnSimulate / EOnPostSimulate callbacks. If your vehicle mod relies on these callbacks firing continuously, test on 1.29 experimental.
Dynamic Collision for All Transport (1.29 Experimental)
The Transport class (parent of CarScript and BoatScript) now has dynamic collision resolution. Previously, only CarScript had this. Boat mods benefit from proper collision handling.
Common Patterns in Published Vehicle Mods
These recurring patterns are all built from the vanilla CarScript API covered in this chapter:
- Custom initialization in
EEInit()— subclasses overrideEEInit()(callingsuper.EEInit()first) to set fluid levels and spawn required attachments the moment the vehicle is created. - Tick accumulator in
EOnPostSimulate()— rather than running expensive logic every physics tick, accumulatetimeSliceinto a member float and act only when it crosses a threshold (periodic fuel-consumption checks, wear simulation). - Admin eject-all via
CrewGetOut()— loop overCrewSize()and callCrewGetOut(i)for each occupied seat, exactly like theEjectAllCrew()example earlier in this chapter. - Collision damage tuning in
OnContact()— overrideOnContact()to scale or filter contact damage using theContactdata before delegating tosuper.
