RLS Studios
ProjectsPatreonCommunityDocsAbout
Join Patreon
BeamNG Modding Docs

Guides

Reference

Server CommandsGE UtilitiesGame Engine MainNavigation GraphScreenshot CaptureServerServer ConnectionSpawnpoint ManagerSimulation TimeVehicle SpawningSuspension Frequency Tester
Ambient SoundUI Apps ManagerUI AudioBindings LegendCamera Distance AppDeveloper ConsoleCredits MusicExternal WebSocket ServerFade ScreenGame BlurGameplay App ContainersGrid SelectorLivery EditorMessages DebuggerMessages/Tasks App ContainersMission InfoPolice InfoTop BarUI ModsNavigation Map DataVehicle Paint EditorVehicle Vicinity AppUI Visibility
Camera ManagementAction Map ManagementEdit Mode State MachineLivery EditorUndo/Redo WrapperLayer ActionsLayer Edit LifecycleLayer DataDecal Texture LoaderLayer SelectionToolsLivery FilesMath Utilities

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 ExtensionsuiliveryEditor

Layer Data

Manages the UI-side layer data model - parsing, caching, and notifying the UI of layer stack changes.

Manages the UI-side layer data model - parsing, caching, and notifying the UI of layer stack changes.


Overview

ui_liveryEditor_layers transforms the raw API layer stack into a UI-friendly format with order indices, parent references, paths, and visibility flags. It maintains a layerMap keyed by UID for fast lookup and fires guihooks when layers change.

Extension path: lua/ge/extensions/ui/liveryEditor/layers.lua


Exports (M)

FunctionSignatureDescription
parseLayersData(layersData, parentLayer) → uiLayers[]Recursively transforms raw API layers into UI-formatted layer objects.
rebuildLayerData()Re-parses the full layer stack from the API and triggers UI updates.
getLayers() → layers[]Returns the cached flat layers array.
getLayerByUid(layerUid) → layerLooks up a UI-formatted layer by UID from the layer map.
getLayerByOrder(order, parentUid) → layerFinds a layer by its order index within a parent.
getChildrenCount(layerUid) → numberReturns child count for a layer, or root layer count if no UID given.
getVisibleLayersCount() → numberCounts layers not marked as hidden.
requestInitialData()Triggers a full rebuild and UI notification.

Data Fields

FieldTypeDescription
M.layerstableReference to the cached flat layers array.
M.layerMaptableUID-keyed map of {order, parentUid, layer, hidden} for O(1) lookups.

Hook Listener Exports

ExportSignatureDescription
dynamicDecals_onLayerAdded(layerUid)Rebuilds data, fires liveryEditor_OnLayerAdded.
dynamicDecals_onLayerDeleted(layerUid)Rebuilds data, fires liveryEditor_OnLayerDeleted.
dynamicDecals_onLayerUpdated(layerUid)Rebuilds data, fires liveryEditor_onLayersUpdated.
dynamicDecals_moveLayer(from, fromParentUid, to, toParentUid)Rebuilds data after layer reorder.

Internals

UI Layer Format

Each layer is transformed into:

{
  uid = "...",
  id = "...",
  name = "Layer Name",
  type = "decal",         -- decal, fill, linkedSet
  enabled = true,
  locked = false,
  order = 3,              -- 1-based index within parent
  parentUid = "...",      -- nil for root layers
  path = {"uid1", "uid2"},           -- ancestry chain
  pathIndices = {1, 3},              -- index ancestry chain
  siblingCount = 5,
  childrenCount = 0,
  hidden = false,         -- true for non-decal/non-linkedSet types
  -- type-specific fields:
  preview = "texture/path",  -- decal
  rotation = 45.0,           -- decal (degrees)
  color = {r, g, b, a},     -- decal/fill
  mirrored = false,          -- decal
  scale = {x, y},            -- decal
  skew = {x, y},             -- decal
  colorPaletteMapId = 0,     -- fill
}

Layer Map

M.layerMap[uid] stores {order, parentUid, layer, hidden} for O(1) lookups.

Layer Ordering

Layers are inserted in reverse order (table.insert(uiLayers, 1, uiLayer)) so the UI displays top-to-bottom matching the visual stacking order.


Hook Listeners

HookBehaviour
dynamicDecals_onLayerAdded(layerUid)Rebuilds data, fires liveryEditor_OnLayerAdded
dynamicDecals_onLayerDeleted(layerUid)Rebuilds data, fires liveryEditor_OnLayerDeleted
dynamicDecals_onLayerUpdated(layerUid)Rebuilds data, fires liveryEditor_onLayersUpdated
dynamicDecals_moveLayer(from, fromParentUid, to, toParentUid)Rebuilds data, fires liveryEditor_onLayersUpdated

How It Works

  1. Any layer mutation triggers rebuildLayerData()
  2. The full API layer stack is recursively parsed into UI format
  3. layerMap is rebuilt for fast UID lookups
  4. liveryEditor_OnLayersUpdated and liveryEditor_Layers_OnVisibleCountChanged are triggered to the UI

Additional Exports

The following exports are available but not yet documented in detail:

  • M.dynamicDecals_moveLayer
  • M.dynamicDecals_onLayerAdded
  • M.dynamicDecals_onLayerDeleted
  • M.dynamicDecals_onLayerUpdated
  • M.getChildrenCount
  • M.getLayerByOrder
  • M.getLayerByUid
  • M.getLayers
  • M.getVisibleLayersCount
  • M.parseLayersData
  • M.rebuildLayerData
  • M.requestInitialData

See Also

  • Livery Editor - Camera - Related reference
  • Livery Editor - Controls - Related reference
  • Livery Editor - Edit Mode - Related reference
  • UI System Guide - Guide

Layer Edit Lifecycle

Manages the full edit lifecycle for a single decal layer - transform (translate, rotate, scale, skew), material properties, and gamepad/controller hold-repeat input.

Decal Texture Loader

Loads and categorises decal textures from the dynamic decals texture registry for the UI resource browser.

On this page

OverviewExports (M)Data FieldsHook Listener ExportsInternalsUI Layer FormatLayer MapLayer OrderingHook ListenersHow It WorksAdditional ExportsSee Also