VE Architecture Quick Reference
10-second refresher on Vehicle Engine core rules — lifecycle hooks, override patterns, and the no-ghost-values rule.
A 10-second refresher on VE (Vehicle Engine) core rules. Read this before any coding.
1. Extension Lifecycle (When Code Runs)
| Hook | Timing | Use For |
|---|---|---|
onInit | Vehicle boot | Setup vars, load modules, one-time init |
onVehicleLoaded | After physics ready | Timers, logic needing physical body |
updateGFX(dt) | Every frame (GFX rate) | UI updates, visual changes, input |
onPhysicsStep(dt) | 2000Hz (if enabled) | Torque, forces, actuators |
onReset | User presses 'R' | Clean state, stop timers/modes |
onDespawnObject | Before removal | Final cleanup, save data to GE |
Enable physics step: obj:setPhysicsStepEnabled(true)
2. Hook System (How to Extend)
Core Principle: Hook > Override
Always prefer hooks over function overrides. Hooks chain; overrides replace.
-- GOOD: Hook pattern (chains with other mods)
local function onInit()
-- Your init logic
end
M.onInit = onInit
-- AVOID: Direct overrides unless absolutely necessary
-- someModule.func = function() ... end -- Breaks other mods!Safe Override Pattern (When You Must)
Always call original FIRST to let game logic finish, then apply your changes.
local orgFunc = target.func
target.func = function(...)
local res = orgFunc(...) -- Game does its work FIRST
-- Your mod logic here (won't be overwritten)
return res
end3. No Ghost Values (Keep Physics & UI in Sync)
Rule: If you change physics, you MUST update the UI/reporters.
A "Ghost Value" = physics changed but UI shows old data. Confusing UX!
Example: Torque Curve Modification
-- After modifying torqueCurve, update derived data
eng.torqueCurve[rpm] = torque * 1.2
eng.torqueData = eng:getTorqueData() -- Sync UI!
eng.maxTorque = eng.torqueData.maxTorque
eng.maxPower = eng.torqueData.maxPowerExample: Safe getTorqueData Override
local orgGetTorqueData = eng.getTorqueData
eng.getTorqueData = function(device)
local data = orgGetTorqueData(device) -- Get base data FIRST
-- Modify returned data for UI visibility
data.maxTorque = data.maxTorque * multiplier
return data
end4. Architectural > Hacks
| Do This | Avoid This |
|---|---|
Modify torqueCurve in onInit for permanent boosts | Using outputTorqueState in a loop when curve mod works |
Use onPhysicsStep for 2000Hz physics forces | Running physics in updateGFX |
Use updateGFX for UI/visual updates | Heavy physics calcs in updateGFX |
Namespace your electrics: myMod_value | Generic names that collide: customValue |
5. Quick Discovery
powertrain.getDevice("mainEngine") -- Engine object
electrics.values -- Shared data bus
v.data.variables -- JBeam config values
extensions.hook("onReset") -- Trigger all reset hooksSummary Checklist
- Hook into lifecycle at the right timing
- Prefer hooks over overrides
- Call original first when overriding
- Update UI/reporters when changing physics
- Namespace your electrics to avoid collisions
Vehicle Control from GE
How to find, spawn, switch, and send commands to vehicles from Game Engine Lua — the essential operations for any gameplay mod.
Vehicle Scripting Patterns
Proven patterns for vehicle development — impact detection, speed-based logic, damage monitoring, cross-module communication, and throttled updates.