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
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 damage.
Module Exports (M)
Core Functions
| Function | Signature | Description |
|---|---|---|
getSectionsDamageInfoRaw | (vehId?) → table | Returns raw beam and collision damage per section (0–26) |
getTextualCollisionDamageLocations | (data?) → table | Returns named damage locations from collision damage |
getTextualBeamDamageLocations | (data?) → table | Returns named damage locations from beam/deformation damage |
getOverallDamageLevel | (vehId) → table | Returns severity name and level (0–3) |
calculateDamageVariation | (tableNumbers, maxValue?) → number | Normalized standard deviation of damage values (0–1) |
Debug
| Function | Signature | Description |
|---|---|---|
setDebug | (bool) | Toggle debug visualization (wireframe grid + damage values) |
Extension Lifecycle
| Export | Signature | Description |
|---|---|---|
onUpdate | (dtReal, dtSim, dtRaw) | Per-frame damage data collection from tracked vehicles |
onSerialize | () → table | Serialize tracking state for save |
onDeserialized | (data) | Restore tracking state from saved data |
Internals
Section Grid
The vehicle's oriented bounding box (OOBB) is divided into 27 sections (3×3×3 grid) using non-uniform cell sizes. Outer cells use a cutDepth calculated from the median axis, creating thinner edge cells and a larger center.
Each section provides:
{
sectionBeamDamage = number, -- deformation/beam damage
sectionCollisionDamage = number -- collision force damage
}Named Damage Locations
| Location | Cell IDs | Description |
|---|---|---|
| Front Center | 3, 4, 5 | Center front |
| Front Left | 6, 7, 8 | Left front |
| Front Right | 0, 1, 2 | Right front |
| Left Center | 15, 16, 17 | Left side |
| Right Center | 9, 10, 11 | Right side |
| Rear Left | 26, 25, 24 | Left rear |
| Rear Right | 20, 19, 18 | Right rear |
| Rear | 21, 22, 23 | Center rear |
| Top | 2,5,8,11,14,17,20,23,26 | Top surface |
| Bottom | 0,3,6,9,12,15,18,21,24 | Bottom surface |
| Front | 0–8 | Entire front |
| Rear | 18–26 | Entire rear |
| Right | 0,1,2,9,10,11,18,19,20 | Entire right |
| Left | 6,7,8,15,16,17,24,25,26 | Entire left |
Damage Severity Levels
| Threshold | Name | Severity |
|---|---|---|
| < 50 | No damage | 0 |
| ≥ 50 | Minor | 1 |
| ≥ 10,000 | Moderate | 2 |
| ≥ 30,000 | Severe | 3 |
M.calculateDamageVariation | (tableNumbers, maxValue) | - |
M.getOverallDamageLevel | (vehId) | - |
M.getSectionsDamageInfoRaw | (vehId) | - |
M.getTextualBeamDamageLocations | (data) | - |
M.getTextualCollisionDamageLocations | (data) | - |
M.onDeserialized | (data) | - |
M.onSerialize | () | - |
M.onUpdate | () | - |
M.setDebug | (newDebug) | - |
Damage Score Algorithm
For each named location, computes:
- totalDamage - Sum of cell damage differences (new vs old)
- maxCellDamage - Highest single cell damage
- averageCellDamage - Mean across location's cells
- damageVariation - Normalized standard deviation (concentrated vs spread)
- intensity - totalDamage / (maxCellDamage × cell count)
- damageScore - intensity × totalDamage × averageCellDamage / 1,000,000
The location with the highest damageScore is reported as mostDamagedLocation.
How It Works
getSectionsDamageInfoRaw()queries per-section beam and collision damage from the enginegetTextualCollisionDamageLocations(data)compares old vs new section state- For each named location, sums the damage difference across its cells
- Computes statistical metrics (variation, intensity) to determine the most likely impact zone
- Used by
crashDetectionto annotate impacts with spatial damage info
Usage Example
-- Get current damage sections
local sections = gameplay_util_damageAssessment.getSectionsDamageInfoRaw(vehId)
-- Get textual damage after a crash
local result = gameplay_util_damageAssessment.getTextualCollisionDamageLocations({
vehId = vehId,
oldSectionsDamageRaw = savedSections -- from before crash
})
log("I", "", "Most damaged: " .. (result.mostDamagedLocation or "none"))
-- Quick severity check
local level = gameplay_util_damageAssessment.getOverallDamageLevel(vehId)
log("I", "", level.damageName) -- "Minor", "Moderate", "Severe"See Also
- gameplay/util/crashDetection - Vehicle Crash Detection System - Related reference
- gameplay/util/groundContact - Ground Contact Detection - Related reference
- gameplay/util/sortedList - Sorted Object List Container - Related reference
- Gameplay Systems Guide - Guide
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
Ground Contact
Reference for `gameplay_util_groundContact`, a simple utility that checks whether a vehicle is resting on its wheels (right-side-up and touching the ground).