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
Auto AnnotationBoosterCalibrate ESCCompile ImpostersCompile MeshesConfig List GeneratorDecal Roads EditorDependency TreeDoc CreatorExport (glTF)Follow The White RabbitForest GeneratorGround Model DebugInput System UtilsInstanced Line Render DemoJBeam StatsLog StreamsMap TilesNode Beam ExportNode StreamPhotomodePrecompile ShadersPrecompile VehiclesProcedural Track (Gymkhana Generator)Rectangle GeneratorRender Components APIResave MaterialsRich PresenceSave Dynamic DataScreenshot Creator (Vehicle Thumbnails)ShowroomSort LinesStep HandlerTerrain GeneratorTest Extension ProxiesTest JSON Files Syntaxutil/vehicleRopeDebug - Rope Physics Debug UIutil/worker - Batch Job Workerutil/wsTest - WebSocket Test Server

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 Extensionsutil

Procedural Track (Gymkhana Generator)

Generates randomized gymkhana / autocross tracks from seed-based procedural parameters.

Generates randomized gymkhana / autocross tracks from seed-based procedural parameters.


Overview

util_procTrack creates complete procedural gymkhana tracks by subdividing rectangles into node graphs, finding Hamiltonian paths, generating winding roads with curves and gates, and spawning all game objects (DecalRoads, pylons, gates, waypoints). Tracks are fully deterministic given a seed.

Extension path: lua/ge/extensions/util/procTrack.lua


Exports (M)

FunctionSignatureDescription
getDefaultParams() → tableReturns a fresh default parameter table for gymkhana generation.
makeGymkhana(params)Main entry point - generates a complete track from params.
reGenerate(seed)Re-generates the track with a new seed, preserving scenario/populate/after functions.
checkParams()Validates and fills in missing params (seed, node count, density).
makeBaseNodePositions() → graphCreates the base node graph via rectangle subdivision.
makePath(graph) → path|nilFinds a Hamiltonian path through the graph using DFS + backtracking.
createWindingPath(path) → nodesComputes winding road geometry (arcs, angles, radii) around path nodes.
createWindingRoad(nodes)Spawns DecalRoad objects for the track surface.
createPylons(nodes)Spawns pylons, circles, barrels, gates as visual markers.
decorateStartAndFinish(nodes)Places start/finish gate decorations.
createWaypointsForScenario(nodes)Creates BeamNGWaypoint objects and configures scenario lap config.
getSeed() → number|nilReturns the current track seed.
intToWords(int) → stringConverts a seed integer to a human-readable word string.
wordsToInt(word) → numberConverts a word string back to a seed integer.

Path-Finding Internals (exported to M during generation)

FunctionSignatureDescription

Utility Exports

FunctionSignatureDescription
dist(a,b,x,y) → number2D Euclidean distance.
getPosition(x,y,z) → {x,y,z}Transforms local coords to world coords using root position/angle.
getRotationDeg(deg) → numberTransforms local angle to world angle in degrees.
makePylon(pos, size, rot, skin)Spawns a barrier segment TSStatic.
makeGate(pos, rot)Spawns a gate TSStatic.
makeConcreteRing(pos, radius)Spawns a scaled concrete ring TSStatic.
makeBarrel(pos, rot, skin)Spawns a barrel marker TSStatic.

Internals

Generation Pipeline

  1. checkParams - seeds RNG, calculates node count from area/density, loads util/rectangleGen.
  2. makeBaseNodePositions - calls rectangleGen.getGraph() to subdivide rectangles into a graph with neighbor info.
  3. makePath - depth-first search with backtracking for a Hamiltonian path (NP-complete; uses heuristic limits).
  4. createWindingPath - computes angles, radii, loop/gate decisions, arc geometry using the belt problem.
  5. createWindingRoad - emits TorqueScript to create DecalRoad objects.
  6. createPylons - emits pylons, circles, barrels, gates as TSStatic objects.
  7. createWaypointsForScenario - sets up BeamNGWaypoint nodes and scenario lap configuration.

Key Parameters

ParameterDefaultDescription
rootX/Y/Z240/-20/34.35World origin of the track.
rootAngleRad0Rotation of the entire track.
rectModeParams.density0.85Nodes per 1000m².
rectModeParams.minNodes6Minimum node count.
rectModeParams.maxNodes27Maximum node count.
path.loopChance0.75Chance of a curve becoming a loop-around.
path.gateChance0.8Chance of a straight becoming a gate.
path.closedfalseWhether to create a closed circuit.

Seed Word Encoding

Seeds are encoded/decoded using a 500-word list, giving ~62.5 billion unique tracks.


How It Works

  1. Call makeGymkhana(params) with custom or default parameters.
  2. The system subdivides the arena into rectangles, places nodes at their centers.
  3. A path is found through all nodes (Hamiltonian path via DFS).
  4. Winding road geometry is computed using belt-problem math for smooth curves.
  5. TorqueScript spawns all game objects into a GymkhanaArena SimGroup.
  6. Waypoints are created for scenario integration.

Lua Examples

-- Generate a gymkhana track with default params
local params = extensions.util_procTrack.getDefaultParams()
params.seed = 12345
extensions.util_procTrack.makeGymkhana(params)

-- Re-generate with a new seed
extensions.util_procTrack.reGenerate(67890)

-- Convert seed to/from words
local words = extensions.util_procTrack.intToWords(12345)
local seed = extensions.util_procTrack.wordsToInt(words)

Additional Exports

  • M.checkParams - (undocumented)
  • M.createPylons - (undocumented)
  • M.createWaypointsForScenario - (undocumented)
  • M.createWindingPath - (undocumented)
  • M.createWindingRoad - (undocumented)
  • M.currentEdgeNotOK - (undocumented)
  • M.decorateStartAndFinish - (undocumented)
  • M.determineInOutAngle - (undocumented)
  • M.dist - (undocumented)
  • M.edgeCreatesSplitGraph - (undocumented)
  • M.getBaseInformationFromPath - (undocumented)
  • M.getDefaultParams - (undocumented)
  • M.getPathRoadNodes - (undocumented)
  • M.getPosition - (undocumented)
  • M.getRotationDeg - (undocumented)
  • M.getSeed - (undocumented)
  • M.intToWords - (undocumented)
  • M.isInList - (undocumented)
  • M.makeBarrel - (undocumented)
  • M.makeBaseNodePositions - (undocumented)
  • M.makeConcreteRing - (undocumented)
  • M.makeGate - (undocumented)
  • M.makeGymkhana - (undocumented)
  • M.makePath - (undocumented)
  • M.makePylon - (undocumented)
  • M.reGenerate - (undocumented)
  • M.wordsToInt - (undocumented)

Precompile Vehicles

M.dependencies = {'freeroam_freeroam', 'core_vehicles'}

Rectangle Generator

Generates a planar graph of nodes by recursively subdividing rectangles, used by `procTrack` for gymkhana track generation.

On this page

OverviewExports (M)Path-Finding Internals (exported to M during generation)Utility ExportsInternalsGeneration PipelineKey ParametersSeed Word EncodingHow It WorksLua ExamplesAdditional Exports