`be` - BeamNG Engine Binding
Core C++ engine binding available globally in GE Lua. Provides direct access to vehicles, physics state, object management, time control, and world queries.
Core C++ engine binding available globally in GE Lua. Provides direct access to vehicles, physics state, object management, time control, and world queries.
Overview
be is the primary bridge between GE Lua and the C++ engine. It manages the object pool (mostly vehicles), physics simulation, player assignment, and low-level engine operations.
| Category | Methods | Purpose |
|---|---|---|
| Vehicle Access | getPlayerVehicle, getPlayerVehicleID, getObjectByID | Retrieve vehicle objects |
| Object Pool | getObject, getObjectCount | Iterate all managed objects |
| Physics | setPhysicsSpeedFactor, physicsStartSimulation, physicsStopSimulation | Control simulation |
| Vehicle Mgmt | enterVehicle | Switch player to vehicle |
| JavaScript | queueJS | Send JS to UI layer |
| Broadcast | queueAllObjectLua | Send Lua to all vehicles |
| Surface | getSurfaceHeightBelow | Ground height query |
Vehicle Access
Get Player Vehicle
-- Returns the vehicle object for player index (0 = first/only player)
local veh = be:getPlayerVehicle(0)
-- Returns just the ID (integer) - faster, no object lookup
local vehId = be:getPlayerVehicleID(0)
-- Common pattern: guard against nil
local veh = be:getPlayerVehicle(0)
if veh then
local pos = veh:getPosition()
endGet Vehicle by ID
-- Look up any vehicle by its numeric ID
local veh = be:getObjectByID(vehId)
-- Also available as a global shortcut:
local veh = getObjectByID(vehId)
-- From scenetree (alternative):
local veh = scenetree.findObjectById(vehId)Find by Name (use scenetree)
-- be does NOT have getObjectByName - use scenetree instead
local veh = scenetree.findObject("myVehicle")Object Pool Iteration
All managed objects (primarily vehicles) live in the object pool.
-- Total object count
local count = be:getObjectCount()
-- Get object by index (0-based)
local obj = be:getObject(i)
-- Iterate all vehicles
for i = 0, be:getObjectCount() - 1 do
local veh = be:getObject(i)
local id = veh:getID()
local name = veh:getJBeamFilename()
-- process...
end
-- Delete all except player vehicle
local playerId = be:getPlayerVehicleID(0)
for i = be:getObjectCount() - 1, 0, -1 do
local objId = be:getObject(i):getID()
if objId ~= playerId then
be:getObject(i):delete()
end
endGotcha: Always iterate backwards when deleting to avoid index shifting.
Vehicle Object Methods
Once you have a vehicle object from be, these methods are available:
Identity
| Method | Returns | Description |
|---|---|---|
veh:getID() | number | Unique vehicle ID |
veh:getJBeamFilename() | string | JBeam model name (e.g. "pickup") |
veh:getName() | string | Scene object name |
veh:isActive() | boolean | Currently active/valid |
veh:isHidden() | boolean | Visibility state |
Transform
| Method | Returns | Description |
|---|---|---|
veh:getPosition() | Point3F | World position |
veh:getRotation() | QuatF | Orientation quaternion |
veh:getVelocity() | Point3F | Linear velocity (m/s) |
veh:getAngularVelocity() | Point3F | Angular velocity |
veh:setPositionRotation(x,y,z, rx,ry,rz,rw) | - | Teleport vehicle |
veh:reset() | - | Reset to spawn position |
GE → VE Communication
-- Send Lua code to vehicle's VE context
veh:queueLuaCommand("electrics.values.hazard = 1")
-- Send data via JSON encoding
local data = jsonEncode({speed = 50, mode = "eco"})
veh:queueLuaCommand("myMod.receiveData('" .. data .. "')")
-- Trigger GE callback from VE result
veh:queueLuaCommand(string.format(
"partCondition.initConditions(nil, %d) obj:queueGameEngineLua('myExt.onFinished(%d)')",
condVal, vehId
))Vehicle Control
-- Enter/switch to vehicle
be:enterVehicle(0, veh) -- playerIndex, vehicleObj
-- Delete vehicle
veh:delete()Physics Control
-- Time scale (slow motion / fast forward)
be:setPhysicsSpeedFactor(0.5) -- Half speed
be:setPhysicsSpeedFactor(1.0) -- Normal
be:setPhysicsSpeedFactor(2.0) -- Double speed
-- Start/stop physics simulation
be:physicsStartSimulation()
be:physicsStopSimulation()
-- Pause/resume via simTimeAuthority (preferred over direct physics control)
simTimeAuthority.pause(true) -- Pause
simTimeAuthority.pause(false) -- ResumeNote: Physics pausing is typically handled via
simTimeAuthority, not directbemethods. ThephysicsStateChangedcallback in main.lua dispatchesonPhysicsPaused/onPhysicsUnpausedhooks.
Time of Day
Time of day is controlled via core_environment, not be directly:
-- Set time via core_environment
core_environment.setTimeOfDay({time = 0.5}) -- 0.0-1.0 (0.5 = noon)
-- Or via scenetree TimeOfDay object
local tod = scenetree.findObject("TimeOfDay")
if tod then
tod.time = 0.5
tod.play = false -- Stop day/night cycle
endJavaScript Bridge
-- Execute JavaScript in the UI (CEF) layer
be:queueJS("angular.element(document).scope().$broadcast('MyEvent')")Prefer
guihooks.trigger()over rawbe:queueJS(). The guihooks API is safer and handles serialization.
Global Shortcut Functions
Several be operations are aliased as global functions for convenience:
| Global | Equivalent | Notes |
|---|---|---|
getPlayerVehicle(0) | be:getPlayerVehicle(0) | Most common accessor |
getObjectByID(id) | be:getObjectByID(id) | By numeric ID |
-- These are equivalent:
local veh = be:getPlayerVehicle(0)
local veh = getPlayerVehicle(0)Common Patterns
Safe Vehicle Access
local function doSomethingWithPlayer()
local veh = be:getPlayerVehicle(0)
if not veh then return end
local vehId = veh:getID()
local pos = veh:getPosition()
-- ...
endSend Command to All Vehicles
for i = 0, be:getObjectCount() - 1 do
be:getObject(i):queueLuaCommand("extensions.load('fuelMultiplier')")
endDistance Check
local playerPos = be:getPlayerVehicle(0):getPosition()
local targetPos = scenetree.findObject("myTarget"):getPosition()
local dist = playerPos:distance(targetPos)
if dist < 50 then
-- Within 50 meters
endTrack Active Vehicle ID Changes
function M.onVehicleSwitched(oldId, newId, player)
if player == 0 then
log('I', 'myMod', 'Player switched from ' .. tostring(oldId) .. ' to ' .. tostring(newId))
end
endGotchas
getPlayerVehicle(0)can return nil - Always guard. No vehicle spawned yet, or player is walking.be:getObject(i)is 0-indexed - Loop from0togetObjectCount() - 1.queueLuaCommandis async - Code executes next physics frame, not immediately.- Vehicle IDs are not stable across sessions - Don't persist raw IDs; use inventory systems.
be:getPlayerVehicleID(0)returns -1 when no vehicle - Check before using as table key.
See Also
- Globals - All global objects including
be - Communication - Cross-VM communication patterns
- SceneTree - Alternative object lookup via scene graph
- Extensions - Hook system for vehicle events
unittests Reference
Script defined in `lua/console/unittests.lua`. Unit tests for vec3 math operations including correctness and performance validation.
Global Utility Functions Catalog
Functions available globally in both GE and VE contexts. Loaded from `lua/common/utils.lua` and `lua/common/luaCore.lua`.