This is a work in progress thread for documenting how to access various parts of the Vehicle Lua API. Usage of this has been tested in BeamNG.Drive version 0.16 (the latest at the time of this thread's creation). I will make the formatting better when I get a chance to. Global Tables: Spoiler Code: bdebug beamstats energyStorage socket drivetrain wheel beam jit bit powertrain color settings loadingTimes core_quickAccess ai controller Light Quaternion streams fire IProp debug thrusters backwardsCompatibility guihooks beamstate particlefilter partmgmt groundModel json recovery display collisionData sounds custom_inputs IBody particles wheelData wheels HighPerfTimer table path advancedwheeldebug cruiseControl scenario ffi midpointT motionSim mapmgr IFlexMesh gui hydros bullettime sensors electrics v input io _G float3 extensions os debugdrawer string material mime props Vector3 damageTracker Settings coroutine node_dynamic_property BeamObject dbg playerInfo package commands math Global Functions: Spoiler Code: stringToVec3 arrayFindValueIndex graphicsStep rawget beamDeformed arrayConcat ipairs setControllingPlayers print requestCameraConfig tableToFloat3Default createCurve quatFromEuler tableReadOnly dumps tableIsDict bytes_to_string load tableToColor saveCompiledJBeamRecursive tableMerge round tableKeys getContrastColorF isnan setCameraConfig sign2 vehicleDestroy detectGlobalWrites tableSizeC couplerDetached isnaninf addNode vec3toString log_jbeam processResponseCurve tonumber vehicleResetted vec3 rawset tableFindKey unserialize dump jsonDecode isinf smoothstep getContrastColorStringRGBA beamBroken split newTemporalSmoothing executeLuaSandboxed jsonEncode setfenv addHubWheelTSV dumpz formatTimeStringNow saveCompiledJBeam rerequire require debugDraw exportPersistentData rainbowColor tostring couplerAttached join newExponentialSmoothing serializePackages pcall clamp tableContains dumpsz stringHash addPressureWheel trim axisSystemApply sign torsionbarBroken nop tableIsEmpty init xpcall getTime getContrastColor loadstring fsign catmullRomQuat unrequire float3ToTable graphs onSettingsChanged smoothmin smootherstep readFile type select ipairs_safe unpack startDebugger newTemporalSpring addRotator float3_2_Vector3 lerp PSItoPascal createCurveArray sendUITextureData quatFromDir readDictJSONTable tableSize addMonoHubWheel addWheel closestLinePoints module addBeam addBeamWithOptions addNodeWithOptions increaseMax newExtensionProxy tableMergeRecursive importPersistentData shallowcopy axisSystemCreate rpad smootheststep newTemporalSmoothingNonLinear require_optional jsonReadFile square quat initSystems getfenv linePointFromXnorm next tableFromHeaderTable pairs addHubWheel loadfile lookAt rawequal dumpToFile guardZero const physicsStep tableValuesAsLookupDict newproxy lpad tableContainsCaseInsensitive nodeCollision jsonEncodePretty debugPoll getContrastColorStringRGB writeFile tableToFloat3 ui_message deserializePackages loadIni saveIni serialize timeprobe error parseColor newValueSampler dofile newLinearSmoothing gcprobe addHubWheelTSI jsonWriteFile newTemporalSigmoidSmoothing assert tableDepth couplerFound collectgarbage setmetatable pairs_safe catmullRom deepcopy getmetatable log gcinfo Powertrain reference: Spoiler Code: powertrain.getDevices() -- Gets a table of powertrain devices. powertrain.getDevice(name) -- Gets a powertrain device by its name (name is a string). Spoiler: mainEngine Code: powertrain.getDevices().mainEngine -- Gets the engine table for typical vehicles. This does not work for the eSBR. powertrain.getDevice("mainEngine") -- Also gets the engine table for typical vehicles. This might be a better way to access it. powertrain.getDevice("mainEngine").dyanmicFriction -- Variable for dynamic friction. powertrain.getDevice("mainEngine").friction -- Variable for friction. powertrain.getDevice("mainEngine").engineBrakeTorque -- Variable controlling engine braking. powertrain.getDevice("mainEngine"):scaleOutputTorque(number) -- multiplies output torque by number. powertrain.getDevice("mainEngine"):scaleFriction(number) -- multiplies friction by number powertrain.getDevice("mainEngine"):enable() -- enables the engine powertrain.getDevice("mainEngine"):disable() -- disables the engine Spoiler: gearbox WIP Spoiler: clutch WIP Engine thermals: Spoiler Code: powertrain.getDevice("mainEngine").thermals -- Table of thermal related variables and functions.` powertrain.getDevice("mainEngine").thermals:reset() -- Reset engine temps. powertrain.getDevice("mainEngine").thermals.oilTemperature -- Variable for oil temp. powertrain.getDevice("mainEngine").thermals.coolantTemperature -- Variable for coolant temp. powertrain.getDevice("mainEngine").thermals.engineBlockTemperature -- Variable for engine block temp. Powertrain table dump: https://gist.github.com/ChargedCreeper/414aacb8e2785c7d981e130590d4f905
You may want to embolden "Engine Thermals:" but thanks for this thread it should be very useful in the future
It is nowhere near finished. I still have a lot of other functions and tables to document the purpose of. Some I will probably need help to figure out later on too.
I think this is very important and valuable project, your time and effort put to this is appreciated very much
Just an update. I have added a raw data dump of the Powertrain table. While it is complete on what there is to access, it may be difficult to find anything useful as quickly. I used Lua to dump the data, so errors or typos are extremely unlikely. Using Github gists is becoming needed due to the sheer amount of data. Neither this forum or Pastebin are good for posts approaching or exceeding a full megabyte of text. Gists handles it very well though.
You can look in the game's install folder (in Steam's steamapps\common folder, or wherever the non-Steam version installs to) for the Lua source code, which has all the function definitions for everything that powers the game. Visual Studio Code comes in extremely handy for Lua browsing, as it has a very nice third-party Lua extension. You can open the "lua" folder of the game as a workspace and browse through all the files to discover how all the components (powertrain, controllers, etc) fit together. There used to be a "lua-doc" folder with HTML documentation on all the Lua code, but it's empty for me now...the source code is fairly easy to navigate though.
This is valid for 0.16.0.2 game version. To get roll of vehicle, you can use obj:getRollPitchYaw() So if you have three variables, myRoll, myPitch and myYaw, you can get all three from that single object by doing this: myRoll, myPitch, myYaw = obj:getRollPitchYaw() To get degrees you need to do this: myRoll = Math.Asin(myRoll) * (180 / Math.PI); //C# myRoll = Math.asin(myRoll) * (180 / Math.PI) //Lua For heading (compass etc) in degrees you need to do this: myYaw = (myYaw * 180 / Math.PI + 180); //C# myYaw = (myYaw * 180 / Math.PI + 180) //Lua G-forces you can get by these: gForceY = sensors.gy / 9.81 gForceX = sensors.gx / 9.81 gForceZ = sensors.gz / 9.81 That gives how many G's there is, don't divide by 9.81 if you want just forces game sensors will output. Do dump(sensors) and dump(electrics) in console vehicle lua selected to see all possible sensors. I have been modifying outsim.lua now and found those from several of ui apps and other lua files, some vehicle lua files etc. it is like finding hidden keys all over the room, there is still few I need to find to get outsim to work, but bit by bit it is getting closer. Then I try to look outgauge and see if I can get unfinished parts of that done too. This is really nice with C# and visual studio in figuring out things with outsim and outgauge and as it may be useful for someone else in future, I put link here too: https://github.com/alexmcbride/insimdotnet/ Edit: Fixed errors with my math by math of developers
Also one note, guistreams.lua was great place to find ways to get more data accessed. For example obj:getPositionXYZ() I found there, it works like this, you need three variables which you place data from that object: myPosX, myPosY, myPosZ = obj:getPositionXYZ() //Lua Now as I am playing with outsim here, some data types might be bit different actually in straight lua, for outsim for example position data is integers, which I need to scratch my head a bit to get more sensible data out from them, I might need to multiply and then divide in my program to get all decimals imported too. So be wary that some of above might be outsim specific in terms of data types and in lua you might need different math to get some values to be what you need them to be. Update: with Outsim issue was when I wanted to read values directly to o.posX etc. using additional variable and then multiplying that before putting value to o.posX did give me 1000 times of value I needed as integer which I then could divide by 1000 and got nice number with fractions. For outsim.lua I got this and I surely hope that there is better way to do this: local positionX local positionY local positionZ positionX, positionY, positionZ = obj:getPositionXYZ() o.posX = positionX * 1000 o.posY = positionY * 1000 o.posZ = positionZ * 1000 However I got coordinate for X show up fine on my program with insane update rate of how much packets outsim is sending, but it is fast at least, yeah my hacks might need few iterations, anyway thought that might be useful for someone visiting this thread.
Oh yes this is all quite complex but once I'm 'in the zone' I can make most out of this. Very useful info, thx for sharing btw The value that we get from the G sensors is actually the value that is contained within the real life accelerometers. This division by 9.81 has to do something with Earth's gravity. I found out when I made my own accelerometer in BeamNG, I was checking the values by visiting Wikipedia on accelerometer ( G-meter, wich is the same) and there it is explained.
Oh, nice We are working on an actual documentation, but it is not finished yet, wanne work with us on that? Write me a pm
I'll contribute a little: Spoiler: Electrics Code: electrics.values.wheelspeed - Vehicle wheelspeed, average speed of all wheels. Measured in meters per second. electrics.values.airspeed - Vehicle speed through the air, more accurate speed measurement but not usually used by cars. Measured in meters per second. electrics.values.gearIndex - Manual gear index. Reverse gears have negative values, neutral has a value of 0. electrics.values.gear_A - Automatic gear index. Varies by automatic type. x/y, with x being the "position" of the current gear in the list of available automatic modes, and y being the total amount of automatic modes. electrics.values.gear - Current gear in string form, usually sent to UI apps such as Tacho2 or ETK gauges electrics.values.steering - Steering amount. Full lock left = -1, full lock right = 1, neutral = 0. electrics.values.altitude - Height above ground level, measured in meters. electrics.values.esc - Is ESC active? electrics.values.tcs - Is TCS active? electrics.values.signal_L - Is left signal active and pulsed on? electrics.values.signal_R - Is right signal active and pulsed on? electrics.values.signal_left_input - Is left signal active, regardless of pulse? electrics.values.signal_right_input - is right signal active, regardless of pulse? electrics.values.horn - Is the horn active? electrics.values.checkengine - Is the engine dead? electrics.values.hazard - Are both signals active and pulsed on? electrics.values.hazard_enabled - Are both signals active, regardless of pulse? electrics.values.reverse - Is gearIndex less than 0? electrics.values.parking - Currently unused, will be used for parking lights later electrics.values.rpm - Engine RPM electrics.values.rpmspin - Engine RPM for spinning props like pulleys electrics.values.rpmTacho - Smoothed engine RPM, less accurate, ideal for older or low quality analog tachometers Spoiler: General things to know Code: controller - Lua file that runs on vehicle spawn and allows to control vehicle parameters and send information to other controllers. Must be called from jbeam. controller.getController() - Calls a controller for use by other controllers. dt - Game's internal clock. Starts on vehicle reload. Measured in seconds. Must refer to dt within a controller's updateGFX function. updateGFX - Function that runs on every frame that is not paused. Every controller has one of these, although some of them do nothing. nop - Shorthand for "no operation". Does nothing. Used to cancel out functions and/or avoid potential errors. jbeamData - Allows controllers to retrieve data from a vehicle's jbeam. Spoiler: Examples Spoiler: Calling a controller within jbeam Code: "controller": [ ["fileName"], ["beamNavigator",{"screenMaterialName": "@etk800_screen", "htmlFilePath": "local://local/vehicles/common/ETK_navi_screen.html", "name":"etk800_navi"}], ], "beamNavigator" - controller name things inside brackets - parameters to send to the controller Spoiler: jbeamData Code: "etkGauges": { // controller name "unitType": "imperial", // parameters to pass on to the controller }, Spoiler: Using nop Code: local function init(jbeamData) local hasESC = controller.getController("esc") ~= nil if not hasESC then M.updateGFX = nop //do nothing on every frame else transfercase = powertrain.getDevice("transfercase") if transfercase then initialSplitA = transfercase.diffTorqueSplitA initialSplitB = transfercase.diffTorqueSplitB initialViscousCoef = transfercase.viscousCoef else M.updateGFX = nop //do nothing on every frame end end end Spoiler: Powertrain Spoiler: Transfer Case Code: powertrain.getDevice("transfercase") - Calls the transfer case, unless you named it something other than "transfercase". diffTorqueSplitA - Percentage of power going to side A. Usually the front wheels. diffTorqueSplitB - Percentage of power going to side B. Usually the rear wheels. More to be added.
Yes, in here it says that 1g is one gravity, that is 9.81 (or 9.8 in article) https://en.wikipedia.org/wiki/G-force Accelerometer sensor, like sensors in BeamNG tell how much 1 gravity is for example, which is ~9.81m/s^2 Hence to know how many g's car pulls, I need to divide by 9.81. Gravity 'g', not grams, not SI unit, actually according to article it should be 9.80665 instead of 9.81 for accuracy. There is then gy2, gx2 and gz2 sensors, which I'm not sure what difference they have with gy, gx and gz sensors, haven't had chance to test them enough, it could be that 2 indicates improved sensor or something totally else, but 2 is one that many part of game uses, so might need to use that instead.
Yep, that's the article And yes that could be the very case about gy2, gx2 and gz2. They might be improved or alternate or even simplified formulas @Tsutarja495 Know those already except for one : didn't know 'nop' stands for 'no operation', so that's technically something like 'nil' I guess thx
Just updated the thread with more info on global tables and functions. This doesn't "call" the transfer case, it returns it. The transfer case (and other parts) isn't represented as a function, but as a table in Lua.