RLS Studios
ProjectsPatreonCommunityDocsAbout
Join Patreon
BeamNG Modding Docs

Guides

Reference

Server CommandsGE UtilitiesGame Engine MainNavigation GraphScreenshot CaptureServerServer ConnectionSpawnpoint ManagerSimulation TimeVehicle SpawningSuspension Frequency Tester
Gameplay AchievementGameplay CityDiscoverForce FieldGarage ModeMarker InteractionParking SystemGameplay Playmode MarkersGameplay PoliceGameplay RallyGameplay Rally LoopGameplay Raw POIsGameplay Skidpad TestSpeed Trap LeaderboardsSpeed Traps and CamerasGameplay StatisticsTaxi Ride SystemTraffic SystemVehicle PerformanceWalking
Rally Audio ManagerRally Camera Path PlayerRally ClientRally Cut CaptureRally EnumsRally Extension HelperRally GeometryRally ManagerRecce ManagerRecce AppRecce SettingsRally Settings ManagerSnap-to-RoadTraffic Exclusion ZonesRally UtilityRally Vehicle CaptureRally Vehicle Tracker

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 Extensionsgameplayrally

Rally Utility

Central utility module for the rally system. Provides constants, file path helpers, mission detection, notebook loading, corner call classification, string utilities, vehicle geometry helpers, and tim

Central utility module for the rally system. Provides constants, file path helpers, mission detection, notebook loading, corner call classification, string utilities, vehicle geometry helpers, and time formatting.


Public API - Constants

| Constant | Value | Description | |------ | M.activeState_countdown | any | activeState_countdown | | M.activeState_stageActive | any | activeState_stageActive | | M.activeState_vehicleProximity | any | activeState_vehicleProximity | | M.activeState_inactive | any | activeState_inactive | | M.rallyLoop_flowgraph_color | any | rallyLoop_flowgraph_color | | M.rally_flowgraph_color | any | rally_flowgraph_color | | M.customDir | any | customDir | | M.systemDir | any | systemDir | | M.structuredDir | any | structuredDir | | M.freeformDir | any | freeformDir | | M.generatedPacenotesDir | any | generatedPacenotesDir | | M.var_da | any | var_da | | M.var_db | any | var_db | | M.validPunctuation | any | validPunctuation | | M.unknown_transcript_str | any | unknown_transcript_str | | M.transcriptsExt | any | transcriptsExt | | M.pacenotesMetadataBasename | any | pacenotesMetadataBasename | | M.notebooksPath | any | notebooksPath | | M.recceRecordSubdir | any | recceRecordSubdir | | M.missionSettingsFname | any | missionSettingsFname | | M.default_waypoint_intersect_radius | any | default_waypoint_intersect_radius | | M.default_codriver_language | any | default_codriver_language | | M.rallySettingsRoot | any | rallySettingsRoot |--- | M.formatTimeFromSeconds | (timeSecs, includeSeconds, includeTenths) | any | formatTimeFromSeconds | | M.drawVehBB | (vehId) | nil | drawVehBB | | M.drawVehLeadingPoint | (vehId, inside) | nil | drawVehLeadingPoint | | M.arePointsEqualWithinThreshold | (point1, point2, threshold) | any | arePointsEqualWithinThreshold | | M.translatedMissionNameFromId | (missionId) | any | translatedMissionNameFromId | | M.translatedMissionName | (missionName) | any | translatedMissionName | | M.getMissionName | (missionId) | any | getMissionName | | M.getMissionSettingsFile | (missionDir) | any | getMissionSettingsFile | | M.makePacenoteAudioFilename | (pacenoteHash) | string | makePacenoteAudioFilename | | M.getCompositorMetadataFile | (compositorVoice) | any | getCompositorMetadataFile | | M.getCompositorPacenoteFile | (compositorVoice, pacenoteHash) | any | getCompositorPacenoteFile | | M.getCompositorFile | (compositorVoice, basename) | any | getCompositorFile | | M.customRound | (dist, round_to) | any | customRound | | M.useNote | (text) | any | useNote | | M.stripBasename | (thepath) | any | stripBasename | | M.pacenoteHashSha1 | (s) | any | pacenoteHashSha1 | | M.finalDrivelineFile | (missionDir) | any | finalDrivelineFile | | M.getAppropriateTextColor | (clr) | any | getAppropriateTextColor | | M.missionReccePath | (missionDir, basename) | any | missionReccePath | | M.missionRecceRecordDir | (missionDir) | any | missionRecceRecordDir | | M.matchSearchPattern | (searchPattern, stringToMatch) | nil | matchSearchPattern | | M.hasPunctuation | (last_char) | boolean | hasPunctuation | | M.getTime | () | any | getTime | | M.detectMissionManagerMissionId | () | nil | detectMissionManagerMissionId | | M.detectMissionEditorMissionId | () | nil | detectMissionEditorMissionId |-|-------|-------------| | missionRallyDir | "rally" | Rally subdirectory name | | notebooksDir | "notebooks" | Notebooks subdirectory | | recceDir | "recce" | Recce recordings subdirectory | | defaultNotebookFname | "primary.notebook.json" | Default notebook filename | | defaultCodriverName | "Sophia" | Default co-driver name | | default_codriver_voice | "british_female" | Default TTS voice | | autofill_blocker | "#" | Blocks autofill for a pacenote | | autodist_internal_level1 | "<none>" | Internal placeholder | | extRally | "gameplay_rally" | Rally extension name | | extRallyLoop | "gameplay_rallyLoop" | Rally loop extension name | | activeState_* | various | Rally loop states: inactive, vehicleProximity, stageActive, countdown |

Public API - Functions

FunctionSignatureReturnsDescription
detectMissionIdHelper()id, dir, errDetect active mission from manager/editor/rally editor
missionDirHelper(missionId)string?Returns /gameplay/missions/<id> path
loadNotebook(fname)notebook?Load notebook from file path
loadNotebookForMissionDir(missionDir, basename)notebook?Load notebook relative to mission dir
createNotebook(fname)notebook?Create and save new empty notebook
loadRacePath(missionDir)racePath, errLoad race.race.json from mission dir
determineCornerCall(angles, steering)angle, str, pctClassify steering angle into corner call
getNotebookFullPath(missionDir, basename)stringFull path to notebook file
drivelineFile(missionDir)stringPath to driveline.json
cutsFile(missionDir)stringPath to cuts.json
transcriptsFile(missionDir)stringPath to transcripts.json
loadCornerAnglesFile()json, errLoad corner angle definitions
calculateForwardNormal(snap_pos, next_pos)vec3Unit direction vector between two points
normalizeName(name)stringReplace non-alphanumeric chars with _
trimString(txt)stringStrip leading/trailing whitespace
getVehFrontCenter(vehId)vec3?Center of vehicle front face from OOBB
getVehFrontBottom(vehId)vec3?Bottom center of vehicle front edge
formatTime24Hour(secs, incSec, incTenth)tableFormat seconds-of-day as 24h time
formatTime12Hour(secs, incSec, incTenth)tableFormat seconds-of-day as 12h time
randomId()string8-char random SHA1 hash
M.detectMissionEditorMissionId()nildetectMissionEditorMissionId
M.detectMissionManagerMissionId()nildetectMissionManagerMissionId
M.getTime()nilgetTime
M.hasPunctuation(last_char)nilhasPunctuation
M.matchSearchPattern(searchPattern, stringToMatch)nilmatchSearchPattern
M.missionRecceRecordDir(missionDir)nilmissionRecceRecordDir
M.missionReccePath(missionDir, basename)nilmissionReccePath
M.getAppropriateTextColor(clr)nilgetAppropriateTextColor
M.finalDrivelineFile(missionDir)nilfinalDrivelineFile
M.pacenoteHashSha1(s)nilpacenoteHashSha1
M.stripBasename(thepath)nilstripBasename
M.useNote(text)niluseNote
M.customRound(dist, round_to)nilcustomRound
M.getCompositorFile(compositorVoice, basename)nilgetCompositorFile
M.getCompositorPacenoteFile(compositorVoice, pacenoteHash)nilgetCompositorPacenoteFile
M.getCompositorMetadataFile(compositorVoice)nilgetCompositorMetadataFile
M.makePacenoteAudioFilename(pacenoteHash)nilmakePacenoteAudioFilename
M.getMissionSettingsFile(missionDir)nilgetMissionSettingsFile
M.getMissionName(missionId)nilgetMissionName
M.translatedMissionName(missionName)niltranslatedMissionName
M.translatedMissionNameFromId(missionId)niltranslatedMissionNameFromId
M.arePointsEqualWithinThreshold(point1, point2, threshold)nilarePointsEqualWithinThreshold
M.drawVehLeadingPoint(vehId, inside)nildrawVehLeadingPoint
M.drawVehBB(vehId)nildrawVehBB
M.formatTimeFromSeconds(timeSecs, includeSeconds, includeTenths)nilformatTimeFromSeconds

How It Works

  1. Mission detection cascades through three sources: mission manager (running game), rally editor, then mission editor
  2. Corner call maps absolute steering angle to named ranges (e.g., "3L", "5R", "C" for center) using angle definition data
  3. File paths follow a consistent structure: /gameplay/missions/<id>/rally/...
  4. Notebook loading deserializes JSON into a rally/notebook/path object and sets adjacent note references
local rallyUtil = require('gameplay/rally/util')

-- Detect current mission
local missionId, missionDir, err = rallyUtil.detectMissionIdHelper()
if not err then
  local notebook = rallyUtil.loadNotebookForMissionDir(missionDir, 'primary.notebook.json')
end

-- Classify a steering angle
local angle, callStr, pct = rallyUtil.determineCornerCall(sortedAngles, -45.0)
-- callStr = "3R", pct = 0.6

Dependencies

  • gameplay/rally/notebook/path - notebook data structure
  • gameplay/race/path - race path data
  • gameplay_missions_missionManager - mission detection
  • editor_rallyEditor / editor_missionEditor - editor mission detection

Module Variables

VariableTypeDescription
M.rallySettingsRootanyrallySettingsRoot
M.default_codriver_languageanydefault_codriver_language
M.default_waypoint_intersect_radiusanydefault_waypoint_intersect_radius
M.missionSettingsFnameanymissionSettingsFname
M.recceRecordSubdiranyrecceRecordSubdir
M.notebooksPathanynotebooksPath
M.pacenotesMetadataBasenameanypacenotesMetadataBasename
M.transcriptsExtanytranscriptsExt
M.unknown_transcript_stranyunknown_transcript_str
M.validPunctuationanyvalidPunctuation
M.var_dbanyvar_db
M.var_daanyvar_da
M.generatedPacenotesDiranygeneratedPacenotesDir
M.freeformDiranyfreeformDir
M.structuredDiranystructuredDir
M.systemDiranysystemDir
M.customDiranycustomDir
M.rally_flowgraph_coloranyrally_flowgraph_color
M.rallyLoop_flowgraph_coloranyrallyLoop_flowgraph_color
M.activeState_inactiveanyactiveState_inactive
M.activeState_vehicleProximityanyactiveState_vehicleProximity
M.activeState_stageActiveanyactiveState_stageActive
M.activeState_countdownanyactiveState_countdown
M.autodist_internal_level1value-
M.autofill_blockervalue-
M.calculateForwardNormal(snap_pos, next_pos)-
M.createNotebook(fname)-
M.cutsFile(missionDir)-
M.defaultCodriverNamevalue-
M.defaultNotebookFnamevalue-
M.default_codriver_voicevalue-
M.detectMissionIdHelper()-
M.determineCornerCall(angles, steering)-
M.drivelineFile(missionDir)-
M.extRallyvalue-
M.extRallyLoopvalue-
M.formatTime12Hour(timeSecs, includeSeconds, includeTenths)-
M.formatTime24Hour(timeSecs, includeSeconds, includeTenths)-
M.getNotebookFullPath(missionDir, basename)-
M.getVehFrontBottom(vehId)-
M.getVehFrontCenter(vehId)-
M.loadCornerAnglesFile()-
M.loadNotebook(notebookFname)-
M.loadNotebookForMissionDir(missionDir, basename)-
M.loadRacePath(missionDir)-
M.missionDirHelper(missionId)-
M.missionRallyDirvalue-
M.normalizeName(name)-
M.notebooksDirvalue-
M.randomId()-
M.recceDirvalue-
M.transcriptsFile(missionDir)-
M.trimString(txt)-

See Also

  • Rally Audio Manager - Related reference
  • Rally Camera Path Player - Related reference
  • Rally Client - Related reference
  • Gameplay Systems Guide - Guide

Traffic Exclusion Zones

Creates traffic exclusion zones around rally stage infrastructure (start positions, pathnodes) to prevent AI traffic from interfering with rally routes. Zones are applied to the navgraph via `map.setT

Rally Vehicle Capture

Class that records vehicle position, rotation, and steering data at distance-based intervals during a recce drive. Writes data to a JSONL driveline file.

On this page

Public API - ConstantsPublic API - FunctionsHow It WorksDependenciesModule VariablesSee Also