All About Lua - Tutorial For Beginners

Discussion in 'Content Creation' started by Jack The Fox, Apr 17, 2025.

  1. Jack The Fox

    Jack The Fox
    Expand Collapse

    Joined:
    Jan 22, 2025
    Messages:
    23
    Welcome to my Lua scripting tutorial for beginners in BeamNG.drive modding! This guide will walk you through everything you need to know to get started with Lua—the language behind BeamNG's powerful modding system.

    What is Lua?
    Lua is a lightweight scripting language used by BeamNG.drive to control game logic, behaviors, UI apps, and more. It's easy to read and write, making it perfect for creating mods like custom sounds, vehicle AI, scenarios, UI apps, and full gameplay features.

    Basic Concepts
    Variables
    local speed = 100
    local isCrashed = false

    Functions
    local function greetPlayer(name)
    print("Welcome, " .. name .. "!")
    end

    greetPlayer("Jack The Fox")

    If Statements
    if [Put something here] then
    print("A message")
    end

    Loops
    for i = 1, 5 do
    print("This is loop number " .. i)
    end

    File Structure
    Mods with Lua often follow this pattern:

    lua/vehicle/extensions/auto/

    The /auto/ folder ensures the script loads automatically for all vehicles.

    Exported Functions in Extensions

    local M = {}
    function M.onInit()
    print("Vehicle script loaded")
    end

    function M.onUpdate(dt)
    -- Your update code here
    end

    return M

    Testing Your Script

    1. Save your .lua file inside /lua/vehicle/extensions/auto/.

    2. Press Ctrl+L in BeamNG to reload Lua scripts.

    3. Use log() or print() to debug:
    log("D", "MyMod", "This is a debug message.")

    Common Globals
    be - BeamNG engine interface
    obj - The vehicle object
    v.data - Vehicle part and node data
    playerInfo - Info about player status (e.g., seated)
    damageTracker - Tracks vehicle damage states

    Other Cool Tricks

    Manually Create a Radiator Leak
    damageTracker.setDamage("engine", "radiatorLeak", true)

    Refuel Vehicle
    energyStorage.getStorage('mainTank'):setRemainingRatio(1)

    AI Chase Behavior
    ai.setTarget("targetID", "chase")

    Tips for Beginners
    • Start small: Try logging messages.

    • Use Ctrl+L to reload Lua without restarting the game.

    • Look in /lua/vehicle/extensions/ for examples.

    • Don’t give up! Everyone starts somewhere. Even the pros have many trials and errors. ;)

    Final Thoughts

    Lua is a fantastic tool for making BeamNG mods feel alive and interactive. Whether you're building custom alarms, creating a refuel system, or making wild weather effects, Lua lets your imagination run wild.

    Feel free to ask questions (If you have questions reply to this post), share your mods, and most importantly—keep experimenting. Happy modding!

    – Jack The Fox
     
    #1 Jack The Fox, Apr 17, 2025
    Last edited: Apr 17, 2025
    • Like Like x 4
  2. AlexKidd71

    AlexKidd71
    Expand Collapse

    Joined:
    Mar 16, 2022
    Messages:
    552
    A good start! Thank you.
    Debugging with vs code works well too (if it works :))There is an addon for it.
     
    • Like Like x 1
  3. robingdv

    robingdv
    Expand Collapse

    Joined:
    Jul 2, 2025
    Messages:
    4
    Hello,

    I'm new to BeamNG modding and I'm trying to create a simple Lua mod for an interactive project. I'm facing a strange issue that I can't seem to solve.

    The Problem: My mod (.zip file) is correctly listed in the Mod Manager, but it seems that neither the info.json file nor the .lua script inside is actually being read or executed by the game.

    Symptoms:

    • The .zip package is visible in the Mod Manager list.

    • However, when I select the mod, the details panel on the right does not show the author or version information from my info.json. It just shows the filename.

    • The Lua script does not run. I have a very simple test script with just a log() command, and the message never appears in the console.
    What I've already tried:

    • I am running game version 0.36.

    • I have tried multiple standard folder structures inside the .zip (lua/ge/extensions/..., lua/vehicle/extensions/..., and a simple lua/ge/...).

    • I confirmed that my .zip archive is correctly created (the lua and info.json files are at the root of the archive).

    • I have tested with all other mods disabled and after clearing the cache.
    It feels like the game detects the mod package but fails to parse its contents. Does anyone know if there's a new requirement for the mod structure in version 0.36, or what could cause this specific symptom?

    Any help would be greatly appreciated. Thank you!
     
  4. Jack The Fox

    Jack The Fox
    Expand Collapse

    Joined:
    Jan 22, 2025
    Messages:
    23
    Hello, here is some information that might help you:

    You should not manually create your own info.json. If you are publishing to the repository, you absolutely cannot include one. The game will generate it automatically after the mod is approved. Even if you know how to format it correctly, including your own can still cause problems or lead to rejection. If you are not sharing the mod publicly, it's best to leave it out entirely.

    As for your Lua script not running, it might be because you do not have a key to activate it or no condition that triggers it. If you want it to activate with a key press, you will need to add two files.

    1. Add this file:
    /lua/ge/extensions/core/input/actions/modName.json

    Code:
    {
      "toggleModName": { "cat": "vehicle", "order": 1, "ctx": "tlua", "onDown": "extensions.load('crazyMod_script')", "title": "Toggle Mod Name", "desc": "Toggles Something" }
    }
    • toggleModName is the internal function name.

    • cat is the category your keybind shows up in. You can change this.

    • ctx should be tlua for GE Lua or vlua for vehicle Lua.

    • onDown is the command that runs when you press the key.
      • Use extensions.load('your_path') to load your Lua file.

      • Or use extensions.your_path.functionName() to run a specific function.

      • The underscores point to your folder path. And replace the last part with the Lua file name without .lua.
    2. Add this file:
    /settings/inputmaps/keyboard_modName.json

    Code:
    {
      "bindings": [
       { "control": "shift a", "action": "toggleModName" }
      ]
    }
    • Change "shift a" to the key you want.

    • Make sure "toggleModName" matches the name from the other file.
    I hope that could help you! If it didn't consider downloading one of my mods and looking at my mod files and comparing them to yours.
     
    #4 Jack The Fox, Jul 2, 2025
    Last edited: Jul 3, 2025
  5. robingdv

    robingdv
    Expand Collapse

    Joined:
    Jul 2, 2025
    Messages:
    4

    Thanks a lot for your answer.

    I'm not sure I get it all, I thought a lua script could be loaded automatically when a game was launched. But I will try to dowload one of your mod, and see if I could understand what you did !

    Thanks mate
     
  6. Riccarr

    Riccarr
    Expand Collapse

    Joined:
    Jul 28, 2024
    Messages:
    41
    Hi ...I'm assuming your not getting your code to run at all yet from the sounds of it?

    From your description it feels like your over complexing things. As already mentioned, you don't need to create the info.json just to get your mod working so you can test/develop it. Also consider how/when you want your mod lua code to run. As Jack mentions above, do you need/want it to run based on a keybind, or just generally when the game starts you want your code to run?

    I suggest you create you mod folder under the unpacked folder under mods folder. This way you don't need to build a zip file every time you change code. Just CTRL-L to reload your code in game after saving code changes.

    These comments below are to have your code run in a general "when game starts" approach ...

    You should have the console window open as soon as possible to monitor for any of your logging messages. Use the tilde ` key to open/close it.

    You should also have this file \mods\unpacked\my_mod\scripts\modScript.lua
    And it should contain these lines ...
    load("my_mod")
    setExtensionUnloadMode("my_mod", "manual")

    Replace "my_mod" with your mod name.

    Then have your mods .lua files in: \mods\unpacked\my_mod\lua\ge\extensions\my_mod.lua

    Your my_mod.lua file will be loaded when game loads. Note this happens at BeamNG main menu load time. If you don't want your mod to do anything until loaded into a map/level, this is where you need to check for specific "events" to know when player is loaded into a map level, if you want your mod code to run that way (not keybind activation).

    Here's a list of events to code in your my_mod.lua. Catching these events you can use to set variables so that your code can know if your loaded into a map, or whatever you want ...

    -- occurs at start of game (main menu) as well as CTRL-L reload - not when map/level loaded
    local function onInit()
    log('I', "MY MOD", "OnInit triggered")​
    end

    -- occurs at start of game (main menu) as well as CTRL-L reload - not when map/level loaded
    local function onExtensionLoaded()
    log('I', "MY MOD", "onExtensionLoaded triggered")​
    end

    -- occurs when map/level loaded; not after reload CTRL-L
    local function onWorldReadyState(state)
    log('I', "MY MOD onWorldReadyState", "--------- Start (state:" .. state .. ") ---------")

    if state == 2 then
    -- game has completed the loaded into a map level
    end​
    end

    For convenient you can also print("my debug message") rather than using the log() function.

    Hope that helps.
     
  7. robingdv

    robingdv
    Expand Collapse

    Joined:
    Jul 2, 2025
    Messages:
    4
    Hi,

    First Thanks a lot for your answer. I didn’t know it was possible to avoid zipping the code and restarting the game each time. That’s going to save me a lot of time! :D
    I managed to print a message using a keybinding. However, I’m trying to develop a mod that performs actions based on the key pressed. But so far, I haven’t really managed to get it working, and I’m not sure if I’m using the right architecture.
    Right now, I have a .lua file with my script, and two .json files — one containing the bindings and their associated actions, and the other acting like a “listener” that triggers the function in my script depending on the input from the first JSON key bind.

    I think I’m overcomplicating things, and there’s probably a simpler way to do this… But I'm learning ! :D

    Thanks.
     
  8. Foxy 5

    Foxy 5
    Expand Collapse

    Joined:
    Jun 19, 2023
    Messages:
    8
    I'm new to all this, but I want to know if there's a way that I can make an engine breaking systems that you can add your own audio file for here to work and at work with engine RPm's and stuff like that with Lua, I have no clue how. Lua works either. I would.
    Just use the semi truck one, but it doesn't work
    Like how I want it to. Any help would be nice. Thank you
     
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice