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/ambientSound - Ambient Sound Stream PlayerUI Apps ManagerUI AudioBindings LegendCamera Distance AppConsole (consoleNG)Credits MusicExternal App (WebSocket UI Server)Fade ScreenGame BlurGameplay App ContainersGrid SelectorLivery EditorMessages DebuggerMessages/Tasks App ContainersMission InfoPolice InfoTop BarUI ModsUI Navigation / MapVehicle Paint EditorVehicle Vicinity AppUI Visibility
Livery Editor - CameraLivery Editor - ControlsLivery Editor - Edit ModeLivery Editor – Editor (Core)Livery Editor – HistoryLivery Editor – Layer ActionLivery Editor – Layer EditLivery Editor – LayersLivery Editor – ResourcesLivery Editor – SelectionLivery Editor – ToolsLivery Editor – User DataLivery Editor – Utils

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

Livery Editor – Layer Edit

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

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


Overview

ui_liveryEditor_layerEdit handles adding new decals and editing existing ones. It maintains an editState object that tracks whether the user is adding or modifying, stores the original layer for cancel/restore, and provides incremental transform operations with configurable step units. It also implements a hold-repeat system for controller input.

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


Exports (M)

FunctionSignatureDescription
setup()Resets the edit state.
editNewDecal(params)Begins adding a new decal with params.texturePath.
editExistingLayer(layerUid, replaceOnSave)Begins editing an existing layer. If replaceOnSave, the layer is hidden and cursor shown.
setCursorProperties(layer)Copies all layer properties (position, texture, color, scale, rotation, mirror) to the cursor.
translateLayer(steps_x, steps_y) → {x, y}Moves the cursor position by step increments.
setPosition(x, y)Sets cursor position absolutely.
scaleLayer(steps_x, steps_y) → {x, y}Adjusts scale by step increments.
setScale(x, y, lock)Sets scale absolutely. If lock is true, aspect ratio is locked.
skewLayer(x, y) → {x, y}Adjusts skew by step increments.
setSkew(x, y)Sets skew absolutely.
rotateLayer(steps, counterClockwise) → degreesRotates by step increments. Returns new degree value.
setRotation(degrees)Sets rotation absolutely in degrees.
setLayerMaterials(properties)Sets color, metallic, and roughness. Values 0–100 from UI are scaled to 0–1.
saveChanges()Commits edits - stamps a new decal if position changed.
cancelChanges()Restores original layer properties and exits edit mode.
requestReposition()Enters reposition mode (shows cursor, hides layer).
applyReposition()Stamps repositioned decal and updates the layer.
cancelReposition()Cancels reposition, restores layer visibility.
stampDecal()Stamps cursor as decal (mouse projection mode).
requestStateData()Sends current editState to the UI.
requestLayerMaterials()Sends color/metallic/roughness to the UI.
requestTransform()Enables transform action maps and shows cursor.
endTransform()Disables transform action maps and hides cursor.
showCursorOrLayer(show)Shows/hides the cursor or layer depending on edit mode.
requestInitialLayerData()Sends full transform data (position, scale, skew, rotation, materials) to the UI.
resetEditState()Clears edit state to defaults.
toggleUseMouseOrCursor() → {isUseMouse}Toggles between mouse and cursor projection.

Controller Hold-Repeat

FunctionSignatureDescription
holdTranslate(axis, value)Starts/stops held translation on x or y axis.
holdTranslateScalar(axis, value)Scalar axis translation with threshold.
holdRotate(direction, value)Starts/stops held rotation.
holdScale(axis, value)Starts/stops held scaling.
holdSkew(axis, value)Starts/stops held skewing.
holdPrecise(enable)Toggles precise mode (smaller increments).
setIsRotationPrecise(value)Sets whether rotation uses precise stepping.
setAllowRotationAction(value)Sets whether rotation input actions are allowed.
holdTranslateAction()Executes pending hold-translate on update tick.
holdRotateAction()Executes pending hold-rotate on update tick.
holdScaleAction()Executes pending hold-scale on update tick.
holdSkewAction()Executes pending hold-skew on update tick.

Data Fields

FieldDescription
M.isPositionChangedfalse - tracks whether position was modified during edit.
M.allowRotationActiontrue - whether rotation actions are permitted.
M.isRotationPrecisefalse - whether rotation uses precise stepping.
M.holdActionnil - current hold-repeat action function.
M.holdValuenil - current hold-repeat value.
M.holdAxisnil - current hold-repeat axis.
M.holdTime0 - accumulated hold time for repeat threshold.
M.precisefalse - whether precise mode is active for hold-repeat.
M.showCursorfunction - reference to the internal showCursor function.

Internals

Step Units

TRANSLATE_STEP_UNIT = 0.001
ROTATE_STEP_UNIT    = 0.01
SCALE_STEP_UNIT     = 0.01
SKEW_STEP_UNIT      = 0.01

Edit State

M.editState = {
  layerUid = nil,        -- UID of the layer being edited
  layerType = nil,       -- api.layerTypes value
  isAdd = nil,           -- true = adding new, false = editing existing
  layer = nil,           -- deep copy of original layer (for cancel)
  replaceOnSave = nil,   -- if true, stamps a new decal on save
  isStampReapplying = nil,
  useMouseRealValue = nil
}

onUpdate(dtReal, dtSim, dtRaw)

The onUpdate tick checks if a hold action is active. After a 0.5s delay, it repeats the action every frame, providing smooth continuous transform via controller sticks.


How It Works

  1. editExistingLayer(uid, true) - stores original layer, switches camera, shows cursor
  2. User adjusts position/scale/rotation via UI controls or controller
  3. saveChanges() - stamps a new decal at the cursor position, replaces the original
  4. Or cancelChanges() - restores the deep copy of the original layer

Additional Exports

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

  • M.applyReposition
  • M.cancelChanges
  • M.cancelReposition
  • M.editExistingLayer
  • M.editNewDecal
  • M.endTransform
  • M.holdPrecise
  • M.holdRotate
  • M.holdRotateAction
  • M.holdScale
  • M.holdScaleAction
  • M.holdSkew
  • M.holdSkewAction
  • M.holdTranslate
  • M.holdTranslateAction
  • M.holdTranslateScalar
  • M.onUpdate
  • M.requestInitialLayerData
  • M.requestLayerMaterials
  • M.requestReposition
  • M.requestStateData
  • M.requestTransform
  • M.resetEditState
  • M.rotateLayer
  • M.saveChanges
  • M.scaleLayer
  • M.setAllowRotationAction
  • M.setCursorProperties
  • M.setIsRotationPrecise
  • M.setLayerMaterials
  • M.setPosition
  • M.setRotation
  • M.setScale
  • M.setSkew
  • M.setup
  • M.showCursorOrLayer
  • M.skewLayer
  • M.stampDecal
  • M.toggleUseMouseOrCursor
  • M.translateLayer

Livery Editor – Layer Action

Dispatches high-level actions (reproject, transform, delete, duplicate, mirror, etc.) on the currently selected layer(s).

Livery Editor – Layers

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

On this page

OverviewExports (M)Controller Hold-RepeatData FieldsInternalsStep UnitsEdit StateonUpdate(dtReal, dtSim, dtRaw)How It WorksAdditional Exports