Crash Detection
Reference for `gameplay_util_crashDetection`, which tracks vehicle damage in real-time to detect crashes and individual impacts. Provides event hooks for crash start/end and impact start/end, with acc
Reference for gameplay_util_crashDetection, which tracks vehicle damage in real-time to detect crashes and individual impacts. Provides event hooks for crash start/end and impact start/end, with acceleration-based damage thresholds.
Module Exports (M)
Vehicle Tracking
| Function | Signature | Description |
|---|---|---|
addTrackedVehicleById | (vehId, crashSettings?, owner?) | Start tracking a vehicle for crash events |
removeTrackedVehicleById | (vehId) | Stop tracking a vehicle |
isVehCrashing | (vehId) → bool | Check if a tracked vehicle is currently crashing |
isVehTracked | (vehId) → bool | Check if a vehicle is being tracked |
resetCrashData | (vehId) | Reset all crash/impact data for a vehicle |
Debug
| Function | Signature | Description |
|---|---|---|
setDebug | (bool) | Toggle debug visualization (spheres, ImGui graphs) |
Extension Lifecycle
| Export | Signature | Description |
|---|---|---|
dependencies | {"gameplay_util_damageAssessment"} | Required extension dependency |
onUpdate | (dtReal, dtSim, dtRaw) | Per-frame crash state machine tick; processes damage deltas |
onSerialize | () → table | Serialize tracked vehicle settings for save |
onDeserialized | (data) | Restore tracked vehicles from saved state |
onVehicleDestroyed | (vehId) | Cleanup tracking data when vehicle is removed |
Hooks Fired
| Hook | Data | Description |
|---|---|---|
onVehicleCrashStarted | {vehId, vehImpactPos, vehImpactSpeed} | First impact of a crash |
onNewImpactStarted | {newImpactData} | Subsequent impact within same crash |
onVehicleCrashEnded | {impacts, sanitizedData, totalDamage, vehId} | Crash fully ended |
Internals
Crash Settings
| Setting | Default | Description |
|---|---|---|
minAccel | 0 | Min acceleration for threshold scaling |
maxAccel | 100 | Max acceleration for threshold scaling |
minDamage | 150 | Damage threshold at max acceleration |
maxDamage | 5000 | Damage threshold at zero acceleration |
verticallyUnweighted | false | Reduce vertical acceleration weight (removes road bumps) |
minVelocity | 1 m/s | Minimum velocity to sustain a crash |
groupImpactsDist | 1m | Max distance between frames to group as same impact |
enableImpactLocationData | false | Enable damage section analysis per impact |
M.addTrackedVehicleById | (vehId_, crashSettings, owner) | - |
M.dependencies | value | - |
M.isVehCrashing | (vehId) | - |
M.isVehTracked | (vehId) | - |
M.onDeserialized | (data) | - |
M.onSerialize | () | - |
M.onUpdate | (dtReal, _dtSim) | - |
M.onVehicleDestroyed | (vehId) | - |
M.removeTrackedVehicleById | (vehId) | - |
M.resetCrashData | (vehId) | - |
M.setDebug | (_debug) | - |
Detection Pipeline (per frame)
- updateAccelData - Tracks two points (front/rear) on the vehicle, computing smoothed acceleration and jerk
- logicDuringCrash - Increments crash timer if crashing or might-be-crashing
- managedImpactAndDetectImpacts - Compares damage to acceleration-scaled threshold:
- Below threshold →
preImpactData(stored in case it becomes a real impact) - Above threshold →
currentImpactData(confirmed impact)
- Below threshold →
- checkIfPreImpactEnded - Clears pre-impact data if vehicle moved away
- checkIfImpactEnded - Finalizes impact when vehicle distance exceeds
groupImpactsDistor velocity drops - checkIfCrashEnded - Ends crash if
stopCrashDelay(1.8s) elapsed since last impact or velocity too low
Impact Data Structure
{
frameDamages = {
{time, newDamage, newDamageSum, vehPos, speed, touchedVehIds, isAboveDamageThreshold},
...
},
touchedVehIds = {[id] = {name = "pickup"}},
averagePos = vec3,
totalDamage = number,
impactSpeed = number,
startingDamageState = table, -- if enableImpactLocationData
damageStateDiff = table -- textual damage locations
}Crash End Data
{
vehId = number,
impacts = { impact1, impact2, ... },
sanitizedData = {
touchedVehIds = {[id] = {name = "..."}},
initialImpactPos = vec3,
initialImpactSpeed = number,
},
totalDamage = number,
}How It Works
The system uses a dynamic threshold that scales with jerk (rate of acceleration change). High jerk → lower damage threshold → more sensitive impact detection. This prevents road bumps from triggering false crashes while still catching real collisions.
Impacts are grouped spatially - if the vehicle stays within groupImpactsDist of the last frame damage, it's part of the same impact. Multiple impacts form a crash, which ends after 1.8s of no new impacts.
Usage Example
-- Start tracking player vehicle
local vehId = be:getPlayerVehicleID(0)
gameplay_util_crashDetection.addTrackedVehicleById(vehId, {
maxDamage = 3000,
enableImpactLocationData = true,
}, "myMod")
-- Listen for crash events
local function onVehicleCrashEnded(data)
log("I", "", string.format("Crash! %d damage, %d impacts", data.totalDamage, #data.impacts))
end
-- Check if crashing right now
if gameplay_util_crashDetection.isVehCrashing(vehId) then
-- vehicle is mid-crash
endSee Also
- gameplay/util/damageAssessment - Vehicle Damage Location Assessment - Related reference
- gameplay/util/groundContact - Ground Contact Detection - Related reference
- gameplay/util/sortedList - Sorted Object List Container - Related reference
- Gameplay Systems Guide - Guide
Suspect Traffic Role
Reference for the `suspect` traffic role, which marks a vehicle as a wanted suspect that police will chase. Manages the transition from watched → wanted → fleeing → arrested states.
Damage Assessment
Reference for `gameplay_util_damageAssessment`, which provides spatial damage analysis by dividing a vehicle's bounding box into a 3×3×3 grid (27 sections) and determining which body regions sustained