RLS Studios
ProjectsPatreonCommunityDocsAbout
Join Patreon
BeamNG Modding Docs

Guides

GE Extension SystemGE Architecture Quick ReferenceGE Boot SequenceGE Cross-VM CommunicationHow Mods Are LoadedInter-VM Communication (GE ↔ VE ↔ UI)Vehicle Boot Sequence & Lifecycle

Reference

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

GuidesArchitecture

GE Architecture Quick Reference

10-second refresher on Game Engine extension lifecycle, hooks, and core rules. Pin this page while coding.

A 10-second refresher on GE (Game Engine) core rules. Read this before any coding.


1. Extension Lifecycle (When Code Runs)

HookArgsTimingUse For
onExtensionLoaded(deserializedData)GE boot / VM reloadSetup vars, one-time init. Called only on the extension itself with deserialized state. Return false to abort loading.
onInit(deserializedData)After onExtensionLoaded (GE only)Second-phase init, after all batch-loaded extensions are ready
onClientStartMission(levelPath)Level loading beginsEarly level setup (before objects ready)
onClientPostStartMission(levelPath)Level Lua loaded, objects availableMission logic, trigger setup, entity queries
onWorldReadyState(state)World objects ready (1=loading, 2=fully loaded)Post-spawn setup, deferred entity queries. state=2 is the safe point.
onUiReadynoneUI (CEF) fully loadedTrigger UI-dependent logic
onFirstUpdatenoneVery first frame after initOne-shot startup logic
onUpdate(dtReal, dtSim, dtRaw)Every frame (before physics)Game logic, timers, state machines
onPreRender(dtReal, dtSim, dtRaw)Every frame (after physics, before render)Visual updates, debug drawing
onGuiUpdate(dtReal, dtSim, dtRaw)Every frame (during onPreRender)UI-specific per-frame updates
onVehicleSpawned(vid, vehObj)Vehicle spawnedTrack vehicles, attach vehicle hooks
onVehicleDestroyed(vid)Vehicle removedCleanup vehicle-specific data
onVehicleSwitched(oldId, newId, player)Player switches vehicleCamera, UI, context updates
onVehicleResetted(vehicleID)Vehicle reset (R key)Re-sync state after reset
onResetGameplay(playerID)Gameplay resetClean state, stop timers/modes
onClientEndMission(levelPath)Leaving levelLevel-specific cleanup
onPreExitnoneBefore game shutdownSave data, cleanup
onExitnoneGame shutting downFinal cleanup
onPreWindowClosenoneWindow close requestedPrompt save, confirm exit
onScreenFadeState(state)Screen fade transitions1=fading to black, 2=fully black, 3=fading from black. Use state 2 to do work while screen is hidden (swap vehicles, teleport, etc.)

2. Hook System (How to Extend)

Core Principle: Hook > Override

Always prefer hooks over function overrides. Hooks chain; overrides replace.

-- GOOD: local function + export pattern (chains with other mods)
local function onExtensionLoaded()
    -- Your init logic
end
M.onExtensionLoaded = onExtensionLoaded

-- Note: onExtensionLoaded is only called on the extension itself (with deserialized data).
-- There is no broadcast to other extensions when an extension loads.

-- 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
end

3. No Ghost Values (Keep State & UI in Sync)

Rule: If you change internal state, you MUST update the UI/reporters.

A "Ghost Value" = state changed but UI shows old data. Confusing UX!

Example: Freeroam Mission State

-- After modifying mission state, update UI
freeroam_missions.state = newState
freeroam_missions.saveMissionProgress()  -- Persist!
guihooks.trigger("MissionStateChanged", newState)  -- Sync UI!

Example: Safe State Getter Override

local orgGetState = module.getState
module.getState = function()
    local state = orgGetState()  -- Get base state FIRST
    -- Modify returned data for UI visibility
    state.modified = true
    return state
end

4. Architectural > Hacks

Do ThisAvoid This
Use onClientPostStartMission for level setupPolling map.getMap().nodes in onUpdate
Use onVehicleSpawned to track vehiclesPolling map.vehicles every frame
Use guihooks.trigger() for UI updatesDirectly modifying UI DOM from GE
Namespace your settings: myMod_settingGeneric names that collide: setting
Use extensions.hook() for cross-module commsDirect function calls across extensions

5. Quick Discovery

be:getPlayerVehicle(0)               -- Get player vehicle object
map.getMap()                         -- Current level data
scenetree.findObject("name")         -- Find entity by name
extensions.hook("onResetGameplay")    -- Trigger all reset hooks
jsonEncode({data = true})            -- Serialize to JSON
jsonDecode('{"key": "value"}')      -- Parse JSON

Summary Checklist

  • Hook into lifecycle at the right timing
  • Prefer hooks over overrides
  • Call original first when overriding
  • Update UI/reporters when changing state
  • Namespace your settings to avoid collisions

See Also

  • Architecture - Full extension system reference
  • Boot Sequence - Startup order details
  • Hook Catalog - All available hooks
  • Common Patterns - Proven patterns

GE Extension System

Complete reference for the Game Engine extension system — loading, unloading, hooks, dependencies, and creating custom extensions.

GE Boot Sequence

Complete documentation of the GE boot sequence — when extensions load, hook execution order, and how to initialize correctly.

On this page

1. Extension Lifecycle (When Code Runs)2. Hook System (How to Extend)Core Principle: Hook > OverrideSafe Override Pattern (When You Must)3. No Ghost Values (Keep State & UI in Sync)Example: Freeroam Mission StateExample: Safe State Getter Override4. Architectural > Hacks5. Quick DiscoverySummary ChecklistSee Also