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 Save your .lua file inside /lua/vehicle/extensions/auto/. Press Ctrl+L in BeamNG to reload Lua scripts. 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
A good start! Thank you. Debugging with vs code works well too (if it works )There is an addon for it.
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!
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.
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
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 endend For convenient you can also print("my debug message") rather than using the log() function. Hope that helps.
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! 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 ! Thanks.
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