GuidesVehicle
Vehicle Scripting Patterns
Proven patterns for vehicle development — impact detection, speed-based logic, damage monitoring, cross-module communication, and throttled updates.
Patterns you'll use repeatedly in vehicle extensions. Each one solves a specific, common problem with production-quality code.
1. High-G Impact Detection (#damage #sensors)
Detecting when a vehicle has hit something hard, regardless of structural damage.
local impactThreshold = 50 -- G's
local function updateGFX(dt)
-- G-forces are available in sensors.gx, gy, gz
local gX = sensors.gx or 0
local gY = sensors.gy or 0
local gZ = sensors.gz or 0
local totalG = math.sqrt(gX*gX + gY*gY + gZ*gZ) / 9.81
if totalG > impactThreshold then
guihooks.message("Impact Detected!", 2, "safety")
end
end2. Speed-Based Conditional Logic (#speed #electronics)
Automatically performing an action (like deploying a spoiler) at a specific speed.
local deploySpeed = 80 / 3.6 -- 80 km/h in m/s
local function updateGFX(dt)
-- Speed is available in electrics.values.airspeed (m/s)
local speed = electrics.values.airspeed or 0
if speed > deploySpeed then
electrics.values.spoilerPosition = 1.0
else
electrics.values.spoilerPosition = 0.0
end
end3. Monitoring Damage Delta (#damage #logic)
Detecting a new collision by checking the change in total damage energy.
local lastDamage = 0
local function updateGFX(dt)
-- beamstate.damage accumulates dissipated energy from impacts
local currentDamage = beamstate.damage or 0
if currentDamage > lastDamage then
local delta = currentDamage - lastDamage
print("Vehicle sustained " .. delta .. " Joules of new damage!")
lastDamage = currentDamage
end
end4. Cross-Module Communication via electrics (#electronics #communication)
Using the electrics bus to decouple a custom controller from a visual prop.
-- In your custom extension or controller:
local function updateGFX(dt)
-- Set a custom value on the bus
electrics.values.customNeedle = math.sin(os.clock())
end
-- In the JBeam (visual prop section), the prop is defined to watch "customNeedle"
-- ["customNeedle", "needle_mesh_name", "rotation_axis", ...]5. Throttled Logic Updates (#core)
Running expensive logic at a lower frequency than the frame rate.
local timer = 0
local interval = 0.5 -- 2Hz (runs twice per second)
local function updateGFX(dt)
timer = timer + dt
if timer >= interval then
-- Run expensive check here
-- Example: check if underwater
if obj:inWater(0) then
print("Underwater!")
end
timer = 0
end
end6. Remote Vehicle State Sync (#communication)
Sending your speed to another vehicle for coordinated behavior (like a convoy).
local function updateGFX(dt)
local mySpeed = electrics.values.airspeed or 0
local targetVehId = 1234 -- ID of the other vehicle
-- Send Lua command to the other vehicle's VM
obj:queueObjectLuaCommand(targetVehId, string.format("convoy.updateLeadSpeed(%f)", mySpeed))
end