GuidesVehicle
62 Vehicle Scripting Recipes
Copy-paste solutions for powertrain control, JBeam manipulation, input handling, UI communication, and niche modding tasks.
Numbered recipes for quick reference. Each one is a self-contained solution you can drop into your vehicle extension.
:::tip Use Ctrl+F to search by keyword (e.g., "turbo", "mass", "steering"). :::
1. Powertrain & Torque (#powertrain #torque #rpm)
- Add permanent torque boost (In
onInit):for rpm, torque in pairs(eng.torqueCurve) do if type(rpm) == "number" then eng.torqueCurve[rpm] = torque * 1.2 end end; eng.torqueData = eng:getTorqueData() - Find the main engine object:
local eng = powertrain.getDevice("mainEngine") - Check if clutch is slipping:
local isSlipping = math.abs(eng.outputAV1 - gearbox.inputAV) > 1 - Force a specific gear:
controller.mainController.shiftToGearIndex(2) - Disable/Reset rev limiter:
eng:resetTempRevLimiter() - Calculate current Horsepower:
local hp = (eng.combustionTorque * eng.outputAV1) / 745.7 - Stall/Lock engine:
powertrain.getDevice("mainEngine"):lockUp() - Check fuel level percentage:
local fuel = electrics.values.fuel * 100 - Change idle RPM dynamically:
eng.idleAVOverwrite = 800 * 0.104719755 - Detect when shifting starts:
if electrics.values.isShifting then ... end - Architectural Boost (UI Visible): Override
getTorqueDatato multiply curve values (see Modding Guide). - Master Power Multiplier:
eng.outputTorqueState = 0.5(50% power) - Get total wheel torque:
local totalTorque = wheels.wheelTorque - Check if engine is running:
local running = not eng.isStalled and eng.outputAV1 > 0 - Apply braking torque to all wheels:
wheels.scaleBrakeTorque(1.0) - Get turbo boost pressure:
local boost = electrics.values.turboBoost or 0 - Check if NOS is active:
local nos = electrics.values.n2oActive or false
2. JBeam & Physics (#physics #jbeam #pos #force)
- Get JBeam variable value:
local myVar = v.data.variables["$myVar"] - Change beam spring/damp at runtime:
obj:setBeam(cid, id1, id2, strength, spring, damp) - Find node CID by name:
local nodeId = beamstate.nodeNameMap["nodeName"] - Get node world position:
local pos = obj:getNodePosition(nodeId) - Add mass to a node:
obj:setNodeMass(nodeId, newMass) - Check if a part is broken (via DamageTracker):
local isBroken = damageTracker.getDamage("body", "hood") - Break a group of beams:
beamstate.breakBreakGroup("groupName") - Get distance between two nodes:
local dist = obj:getNodePosition(id1):distance(obj:getNodePosition(id2)) - Apply a force vector to a node:
obj:applyForceVector(nodeId, vec3(0, 5000, 0)) - Get vehicle world rotation (Quat):
local rot = obj:getRotation() - Check if vehicle is upright:
local up = obj:getDirectionVectorUp(); if up.z > 0.8 then ... end - Deflate a specific tire:
beamstate.deflateTire(wheelId) - Get total vehicle mass:
local mass = 0; for _, n in pairs(v.data.nodes) do mass = mass + n.nodeWeight end - Apply a global torque impulse:
obj:applyTorqueAxisCouple(500, node1, node2, node3) - Check for node collision: Hook into
onNodeCollision(p).
3. Input & Control (#electronics #input)
- Override user steering:
electrics.values.steeringOverride = 0.5 - Disable user throttle:
electrics.values.throttleOverride = 0 - Read raw user steering:
local rawSteer = electrics.values.steering_input - Detect controller button event: Use
input.event("name", val, filter) - Create a non-blocking timer:
local t = HighPerfTimer(); ... if t:stop() > 1000 then ... end - Throttled update (2Hz):
timer = timer + dt; if timer > 0.5 then timer = 0; ... end - Toggle hazard lights:
electrics.toggle_warn_signal() - Set ignition to 'On':
electrics.setIgnitionLevel(2) - Check if parking brake is on:
if (electrics.values.parkingbrake or 0) > 0 then ... end - Smooth a value over time:
val = smoother:get(target, dt)
4. UI & Communication (#ui #communication)
- Trigger screen message:
guihooks.message("Impact!", 5, "safety") - Send data to UI app:
guihooks.queueStream("myKey", myValue) - Call function in Game Engine:
obj:queueGameEngineLua("print('Hello')") - Send command to another vehicle:
obj:queueObjectLuaCommand(targetId, "electrics.values.horn = 1") - Play a one-time sound effect:
obj:playSFXOnce("event:>Vehicle>Failures>tire_burst", nodeId, 1, 1) - Register damage update callback:
damageTracker.registerDamageUpdateCallback(myFunc) - Check if first player is seated:
if playerInfo.firstPlayerSeated then ... end - Draw debug line in world:
obj.debugDrawProxy:drawLine(pos1, pos2, color) - Draw debug text at node:
obj.debugDrawProxy:drawNodeText(nodeId, color, "Broken!") - Sync variable to peer vehicle:
obj:queueObjectLuaCommand(id, "myModule.syncValue(" .. myVal .. ")")
5. Niche Modding Tasks
- Get vehicle's unique object ID:
local id = obj:getId() - Check if in walking/unicycle mode:
local isWalking = (controller.mainController.typeName == "playerController") - Disable a powertrain device:
powertrain.getDevice("rearDiff"):disable() - Check if a node is underwater:
if obj:inWater(nodeId) then ... end - Get environmental air density:
local density = obj:getRelativeAirDensity() - Check if any player is in vehicle:
if playerInfo.anyPlayerSeated then ... end - Change node friction at runtime:
obj:setNodeFrictionSlidingCoefs(id, 1.0, 0.8) - Get gravity magnitude:
local g = powertrain.currentGravity - Trigger custom UI event:
guihooks.trigger("MyEvent", {val = 1}) - Lock a differential:
powertrain.setDeviceMode("rearDiff", "locked")
Vehicle Lua Cheat Sheet
60+ copy-paste one-liners for vehicle scripting — physics, electrics, powertrain, damage, UI, and inter-VM communication.
Vehicle Modding Guide
How to add custom logic to vehicles safely — extensions vs controllers, the electrics data bus, powertrain API, safe overrides, and UI visibility.