Skip to content

Chapter 6.2: Vehicle System

Home | << Previous: Entity System | Vehicles | Next: Weather >>


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 base

Transport (Base)

File: 3_Game/entities/transport.c

The abstract base for all vehicles. Provides seat management and crew access.

Crew Management

c
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 void  CrewGetOut(int posIdx);              // Force crew member out of seat
proto native void  CrewDeath(int posIdx);               // Kill crew member in seat

Crew Entry

c
proto native int  GetAnimInstance();
proto native int  CrewPositionIndex(int componentIdx);  // Component to seat index
proto native vector CrewEntryPoint(int posIdx);         // World entry position for seat

Example --- eject all passengers:

c
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

c
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:

c
enum CarFluid
{
    FUEL,
    OIL,
    BRAKE,
    COOLANT
}
c
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:

c
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

c
proto native float GetSpeedometer();    // Speed in km/h (absolute value)

Controls (Simulation)

c
proto native void  SetBrake(float value, int wheel = -1);    // 0.0 - 1.0, -1 = all wheels
proto native void  SetHandbrake(float value);                 // 0.0 - 1.0
proto native void  SetSteering(float value, bool analog = true);
proto native void  SetThrust(float value, int wheel = -1);    // 0.0 - 1.0
proto native void  SetClutchState(bool engaged);

Wheels

c
proto native int   WheelCount();
proto native bool  WheelIsAnyLocked();
proto native float WheelGetSurface(int wheelIdx);

Callbacks (Override in CarScript)

c
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:

c
// 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 tank

Damage Zone Diagram

Common damage zones for vehicles:

ZoneDescription
"" (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

c
void SetLightsState(int state);   // 0 = off, 1 = on
int  GetLightsState();

Door Control

c
bool IsDoorOpen(string doorSource);
void OpenDoor(string doorSource);
void CloseDoor(string doorSource);

Key Overrides for Custom Vehicles

c
override void EEInit();                    // Initialize vehicle parts, fluids
override void OnEngineStart();             // Custom engine start behavior
override void OnEngineStop();              // Custom engine stop behavior
override void EOnSimulate(IEntity other, float dt);  // Per-tick simulation
override bool CanObjectAttachWeapon(string slot_name);

Example --- create a vehicle with full fluids:

c
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

c
proto native bool  EngineIsOn();
proto native void  EngineStart();
proto native void  EngineStop();
proto native float EngineGetRPM();

Fluids

Boats use the same CarFluid enum but typically only use FUEL:

c
float fuel = boat.GetFluidFraction(CarFluid.FUEL);
boat.Fill(CarFluid.FUEL, boat.GetFluidCapacity(CarFluid.FUEL));

Speed

c
proto native float GetSpeedometer();   // Speed in km/h

Example --- spawn a boat:

c
void SpawnBoat(vector waterPos)
{
    BoatScript boat = BoatScript.Cast(
        GetGame().CreateObjectEx("Boat_01", waterPos,
                                  ECE_CREATEPHYSICS | ECE_INITAI)
    );
    if (boat)
    {
        boat.Fill(CarFluid.FUEL, boat.GetFluidCapacity(CarFluid.FUEL));
    }
}

Vehicle Interaction Checks

Checking if a Player is in a Vehicle

c
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

c
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

ConceptKey Point
HierarchyTransport > Car/Boat > CarScript/BoatScript
EngineEngineStart(), EngineStop(), EngineIsOn(), EngineGetRPM()
FluidsCarFluid enum: FUEL, OIL, BRAKE, COOLANT
Fill/LeakFill(fluid, amount), Leak(fluid, amount), GetFluidFraction(fluid)
SpeedGetSpeedometer() returns km/h
CrewCrewSize(), CrewMember(idx), CrewGetOut(idx)
PartsStandard damage zones: "Engine", "FuelTank", "Radiator", etc.
CreationCreateObjectEx with ECE_PLACE_ON_SURFACE | ECE_INITAI | ECE_CREATEPHYSICS
1.28 ConfiguseNewNetworking, wheelHubFriction, doubled brake torque values
1.28 PhysicsUpdated Bullet Physics, new Contact API fields, suspension always active
1.29 ExperimentalPhysics multithreading, Transport sleep, dynamic collision for all transport

Best Practices

  • Always include ECE_CREATEPHYSICS | ECE_INITAI when 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 return null. Iterating CrewSize() 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 CarScript with modded classes. Conflicts arise when multiple mods override the same callbacks like OnEngineStart() or EOnSimulate().

  • Load Order: If two mods both modded class CarScript and override OnEngineStart(), only the last-loaded mod runs unless both call super. Vehicle overhaul mods should always call super in every callback.
  • Modded Class Conflicts: Expansion Vehicles and vanilla vehicle mods frequently conflict on EEInit() and fluid initialization. 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(), and CrewGetOut() are server-authoritative. GetSpeedometer(), EngineIsOn(), and GetFluidFraction() 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).

cpp
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:

cpp
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 maxBrakeTorque and maxHandbrakeTorque values to maintain the same braking feel.

cpp
// 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, MaterialIndex2
  • Index1, Index2

Added:

  • ShapeIndex1, ShapeIndex2 --- identify which shape in a compound body was hit
  • VelocityBefore1, VelocityBefore2 --- pre-collision velocities
  • VelocityAfter1, VelocityAfter2 --- post-collision velocities

Changed:

  • Material1, Material2 --- type changed from dMaterial to SurfaceProperties

Mods that read Contact data in EOnContact 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.


Observed in Real Mods

These patterns were confirmed by studying the source code of professional DayZ mods.

PatternModFile/Location
Override EEInit() to set custom fluid capacities and spawn partsExpansion VehiclesCarScript subclasses
EOnSimulate accumulator for periodic fuel consumption checksVanilla+ vehicle modsCarScript overrides
CrewGetOut() loop in admin eject-all commandVPP Admin ToolsVehicle management module
Custom OnContact() override for collision damage tuningExpansionExpansionCarScript

Home | << Previous: Entity System | Vehicles | Next: Weather >>

Released under CC BY-SA 4.0 | Code examples under MIT License