RLS Studios
ProjectsPatreonCommunityDocsAbout
Join Patreon
BeamNG Modding Docs

Guides

Reference

server/commands - Camera & Input Commandsge_utils - Game Engine Utility Functionsmain.lua - GE Lua Entry Point & Game Loopmap.lua - Navigation Graph (AI Road Map)screenshot.lua - Screenshot Systemserver/server - Level Loading & Game ServerserverConnection - Client-Server Connection Manager`setSpawnpoint` - Default Spawn Point Persistence`simTimeAuthority` - Simulation Time & Bullet Time Control`spawn` - Vehicle Spawning & Safe Placement`suspensionFrequencyTester` - Suspension Natural Frequency Analysis

UI

Resources

BeamNG Game Engine Lua Cheat SheetGE Developer RecipesMCP Server Setup

// RLS.STUDIOS=true

Premium Mods for BeamNG.drive. Career systems, custom vehicles, and immersive gameplay experiences.

Index

HomeProjectsPatreon

Socials

DiscordPatreon (RLS)Patreon (Vehicles)

© 2026 RLS Studios. All rights reserved.

Modding since 2024

API ReferenceGE Extensions

map.lua - Navigation Graph (AI Road Map)

Reference for `map.lua`. Builds and maintains the navigation graph (navgraph) used by AI traffic, GPS routing, and mission waypoints. Loads road data from DecalRoads and manual waypoints, then process

Reference for map.lua. Builds and maintains the navigation graph (navgraph) used by AI traffic, GPS routing, and mission waypoints. Loads road data from DecalRoads and manual waypoints, then processes it into a connected graph.


Key Exports

KeySignatureDescription
objectstableMap objects cache
objectNamestableMap object names
M.assureLoad()(No description available)
M.debugDrawTrajectory(trajectory)(No description available)
M.findBestRoad(pos, dir)(No description available)
M.findClosestRoad(pos, searchRadiusLim)find road (edge) closest to "position" and return the nodes ids (closestRoadNode1, closestRoadNode2) of that edge and distance to it.
M.getGraphpath()(No description available)
M.getManualWaypoints()(No description available)
M.getMap()(No description available)
M.getNodeLinkCount(nId)(No description available)
M.getNodesFromPathDist(path, dist)(No description available)
M.getPath(start, target, cutOffDrivability, dirMult, penaltyAboveCutoff, penaltyBelowCutoff)(No description available)
M.getPathLen(path)(No description available)
M.getPointNodePath(start, target, cutOffDrivability, dirMult, penaltyAboveCutoff, penaltyBelowCutoff, wZ)(No description available)
M.getPointToPointPath(startPos, targetPos, cutOffDrivability, dirMult, penaltyAboveCutoff, penaltyBelowCutoff, wD, wZ)(No description available)
M.getRoadRules()(No description available)
M.getState()(No description available)
M.getTrackedObjects()(No description available)
M.isCrashAvoidable(objectID, pos, radius)(No description available)
M.logGraphHashes()(No description available)
M.nameNode(prefix, idx)(No description available)
M.objectData(objId, isactive, damage, states, objectCollisions)recieves vehicle data from vehicles
M.onAddWaypoint(wp)TODO: please fix these functions, so users can interactively add/remove/modify the waypoints in the editor and directly see changes.
M.onDeserialize(s)(No description available)
M.onFilesChanged(files)(No description available)
M.onMissionLoaded()(No description available)
M.onModifiedWaypoint(wp)(No description available)
M.onRemoveWaypoint(wp)(No description available)
M.onSerialize()(No description available)
M.onWaypoint(args)(No description available)
M.optimizePath(path, s, useRawPos)(No description available)
M.request(objId, objbuildSerial)(No description available)
M.safeTeleport(vehId, posX, posY, posZ, rotX, rotY, rotZ, rotW, checkOnlyStatics_, visibilityPoint_, removeTraffic_, centeredPosition, resetVehicle)(No description available)
M.saveSVG(filename, includeLinks, includeNodes)(No description available)
M.setEditorState(enabled)(No description available)
M.setNameForId(name, id)(No description available)
M.setState(newState)(No description available)
M.surfaceNormal(p, r)(No description available)
M.tempObjectData(objId, isactive, pos, vel, dirVec, dirVecUp, damage, objectCollisions)used to add explicit vehicle data
M.toggleDrawNavGraph()(No description available)
M.toggleShuffledPairs(mode)for debugging issues in the deterministic build of the navgraph
M.updateDrivabilities(changeSet)(No description available)
M.updateGFX(dtReal, dtSim)(No description available)
M.drawNavGraphStatevariable(No description available)
M.loadvariable(No description available)
M.objectNamesvariable(No description available)
M.resetvariable(No description available)

Graph Building (internal, called via hooks)

The module exposes many internal functions through M but the primary public interface is through lifecycle hooks:

  • onMissionLoaded() - triggers full navgraph build
  • updateGFX(dtReal, dtSim) - per-frame update
  • onFilesChanged(files) - hot-reload on file changes
  • assureLoad() - ensures map is loaded
  • onWaypoint(args) - waypoint trigger callback

Internals

Graph Structure

map.nodes = {
  ["nodeName"] = {
    pos = vec3,           -- world position
    radius = number,      -- road half-width
    links = {             -- connections to other nodes
      ["otherNode"] = {
        drivability = number,   -- 0-1 surface quality
        hiddenInNavi = bool,    -- hidden from GPS
        oneWay = bool,          -- directional road
        lanes = string,         -- lane config e.g. "--++"
        speedLimit = number,    -- m/s (nil = auto)
        inNode = string,        -- direction: traffic flows inNode → outNode
        outNode = string,
        inPos = vec3,           -- edge endpoint positions (may differ from node pos)
        outPos = vec3,
        inRadius = number,      -- edge endpoint radii
        outRadius = number,
        type = string,          -- 'private', nil, etc.
        noMerge = bool,         -- prevent junction merging
      }
    },
    manual = number,      -- 1 if BeamNGWaypoint
    noMerge = bool,       -- prevent merging
    endNode = bool,       -- road endpoint
    junction = bool,      -- merged junction node
  }
}

Road Data Sources

  1. DecalRoads: Scene objects with drivability > 0. Can use subdivision edges or control points.
  2. BeamNGWaypoints: Manual waypoints placed in the editor.
  3. map.json: Level-specific manual road segment definitions connecting waypoints.

Lane Configuration

  • + = forward direction (inNode → outNode)
  • - = reverse direction
  • "--++" = 2 lanes each way (left-hand drive)
  • Right-hand drive swaps lane order
  • flipLanes() reverses the string for bidirectional edges

Graph Processing Pipeline

  1. Load - loadJsonDecalMap() reads DecalRoads, waypoints, and map.json
  2. Merge overlapping nodes - nodes within radius are merged
  3. Resolve T-junctions - dead-end roads are connected to nearby crossing roads
  4. Resolve X-junctions - crossing roads get intersection nodes
  5. Speed limits - auto-calculated from road radius and drivability
  6. Build spatial indices - kd-trees for edge and node queries

Spatial Indexing

  • edgeKdTree: 2D kd-tree of all edges for fast closest-edge queries
  • nodeKdTree: 2D kd-tree of all nodes
  • Uses kdTreeBox2D and quadtree for spatial queries

Deterministic Building

  • Graph hashing via hashNodeData() and hashEdgeData() for build verification
  • Optional shuffled pairs iteration for determinism testing
  • Careful use of sorted lists and safeVecSum for floating-point reproducibility

How It Works

The navgraph is built when a level loads (onMissionLoaded). It reads all DecalRoad objects and BeamNGWaypoint objects from the scene, constructs a graph, then processes it through several refinement passes (overlap merging, junction resolution). The resulting graph supports pathfinding via graphpath and spatial queries for AI navigation.

-- Map is loaded automatically, but can be forced:
map.assureLoad()

-- The graph is accessible (read-only recommended) via internal state
-- AI systems use map functions for pathfinding and closest-road queries

Exported Variables

  • drawNavGraphState - Exported variable - initialized as 'off'
  • warnedMapBackwardCompatibility - Exported variable - initialized as true

Additional Functions

debugDrawTrajectory(trajectory)

(No description available)

findBestRoad(pos, dir)

(No description available)

  • Returns: bestRoad1, bestRoad2, math.sqrt(bestDist)

findClosestRoad(pos, searchRadiusLim)

this is also in vehicle/mapmgr.lua find road (edge) closest to "position" and return the nodes ids (closestRoadNode1, closestRoadNode2) of that edge and distance to it.

getGraphpath()

(No description available)

  • Returns: gp

getManualWaypoints()

(No description available)

  • Returns: manualWaypoints

getMap()

(No description available)

  • Returns: map

getNodeLinkCount(nId)

(No description available)

getNodesFromPathDist(path, dist)

(No description available)

getPath(start, target, cutOffDrivability, dirMult, penaltyAboveCutoff, penaltyBelowCutoff)

(No description available)

getPathLen(path)

(No description available)

getPointNodePath(start, target, cutOffDrivability, dirMult, penaltyAboveCutoff, penaltyBelowCutoff, wZ)

(No description available)

getPointToPointPath(startPos, targetPos, cutOffDrivability, dirMult, penaltyAboveCutoff, penaltyBelowCutoff, wD, wZ)

(No description available)

getRoadRules()

(No description available)

  • Returns: rules or {}

getState()

(No description available)

  • Returns: M

getTrackedObjects()

(No description available)

  • Returns: M.objects

isCrashAvoidable(objectID, pos, radius)

(No description available)

logGraphHashes()

(No description available)

nameNode(prefix, idx)

(No description available)

  • Returns: nodeName

objectData(objId, isactive, damage, states, objectCollisions)

recieves vehicle data from vehicles

onAddWaypoint(wp)

TODO: please fix these functions, so users can interactively add/remove/modify the waypoints in the editor and directly see changes.

onDeserialize(s)

(No description available)

onModifiedWaypoint(wp)

(No description available)

onRemoveWaypoint(wp)

(No description available)

onSerialize()

(No description available)

  • Returns: {isEditorEnabled, buildSerial}

optimizePath(path, s, useRawPos)

(No description available)

request(objId, objbuildSerial)

(No description available)

reset()

(No description available)

safeTeleport(vehId, posX, posY, posZ, rotX, rotY, rotZ, rotW, checkOnlyStatics_, visibilityPoint_, removeTraffic_, centeredPosition, resetVehicle)

(No description available)

saveSVG(filename, includeLinks, includeNodes)

(No description available)

setEditorState(enabled)

(No description available)

setNameForId(name, id)

(No description available)

setState(newState)

(No description available)

surfaceNormal(p, r)

(No description available)

  • Returns: p3

tempObjectData(objId, isactive, pos, vel, dirVec, dirVecUp, damage, objectCollisions)

used to add explicit vehicle data

toggleDrawNavGraph()

(No description available)

toggleShuffledPairs(mode)

for debugging issues in the deterministic build of the navgraph

updateDrivabilities(changeSet)

(No description available)

main.lua - GE Lua Entry Point & Game Loop

Reference for `main.lua`. The root entry point for the Game Engine Lua VM - sets up the runtime environment, loads core modules, defines the main update loop, and handles all lifecycle callbacks from

screenshot.lua - Screenshot System

Reference for `screenshot.lua`. Handles screenshot capture, metadata collection, format selection, and optional upload to BeamNG's media server.

On this page

Key ExportsGraph Building (internal, called via hooks)InternalsGraph StructureRoad Data SourcesLane ConfigurationGraph Processing PipelineSpatial IndexingDeterministic BuildingHow It WorksExported VariablesAdditional FunctionsdebugDrawTrajectory(trajectory)findBestRoad(pos, dir)findClosestRoad(pos, searchRadiusLim)getGraphpath()getManualWaypoints()getMap()getNodeLinkCount(nId)getNodesFromPathDist(path, dist)getPath(start, target, cutOffDrivability, dirMult, penaltyAboveCutoff, penaltyBelowCutoff)getPathLen(path)getPointNodePath(start, target, cutOffDrivability, dirMult, penaltyAboveCutoff, penaltyBelowCutoff, wZ)getPointToPointPath(startPos, targetPos, cutOffDrivability, dirMult, penaltyAboveCutoff, penaltyBelowCutoff, wD, wZ)getRoadRules()getState()getTrackedObjects()isCrashAvoidable(objectID, pos, radius)logGraphHashes()nameNode(prefix, idx)objectData(objId, isactive, damage, states, objectCollisions)onAddWaypoint(wp)onDeserialize(s)onModifiedWaypoint(wp)onRemoveWaypoint(wp)onSerialize()optimizePath(path, s, useRawPos)request(objId, objbuildSerial)reset()safeTeleport(vehId, posX, posY, posZ, rotX, rotY, rotZ, rotW, checkOnlyStatics_, visibilityPoint_, removeTraffic_, centeredPosition, resetVehicle)saveSVG(filename, includeLinks, includeNodes)setEditorState(enabled)setNameForId(name, id)setState(newState)surfaceNormal(p, r)tempObjectData(objId, isactive, pos, vel, dirVec, dirVecUp, damage, objectCollisions)toggleDrawNavGraph()toggleShuffledPairs(mode)updateDrivabilities(changeSet)