An Action is each of the in-game activities that can take place after the player has manipulated a Control .
E.g. steer left, change camera, toggle menu.
Actions are defined in one or more .json files.
It is possible to provide new extra actions through mods. Just remember that, if you don’t also provide some bindings, then the users of your mod will need to manually configure his controllers.
There are two basic kinds of actions: Regular actions and Vehicle-specific actions :
Regular actions are those that can take place regardless of which vehicle is currently used.
They can therefore be available for use even while in the main menu, before entering any level or spawning any vehicle.
BeamNG.drive comes with many predefined regular actions. These are defined in:
lua/ge/extensions/core/input/actions/*.json
Mods can bundle additional regular actions. To do so, they must provide one or more additional json files following this naming convention:
lua/ge/extensions/core/input/actions/*.json
For example:
lua/ge/extensions/core/input/actions/explosions_mod.json
lua/ge/extensions/core/input/actions/advanced_menus.json
Any actions defined there will be available to end-users in the Options → Controls menu, mixed in with the default actions provided by BeamNG.drive.
input_actions.json file with a customized one, this means the mod author will need to constantly update his modified file each time a BeamNG.drive update comes out with new actions (or modified actions, or removed ones). It is therefore strongly advised against.Vehicle-specific actions are those that can only be triggered while driving an specific vehicle. If you switch to a different kind of vehicle, they’ll be replaced by the actions of the new vehicle.
Some of BeamNG.drive official vehicles come with a few predefined vehicle-specific actions. For example, the Small Cannon provides the ability to open fire with your controller. These vehicle-specific actions are defined in:
vehicles/vehicle_directory_name/input_actions.json
Similarly to Regular actions , mods can bundle additional vehicle-specific actions too. The mod-provided files must follow this naming convention:
vehicles/vehicle_directory_name/input_actions*.json
For example:
vehicles/hatch/input_actions_hydraulic_suspension.json
vehicles/pickup/input_actions_winch_cable.json
All of these actions will be typically found in the “Vehicle-specific” category of the Options → Controls menu.
Action files mostly follow the
json format
. They must start with { and end with }. Here’s a sample of how the overall structure has to look like:
{
"an_action" : {"order":1, "title":"Do Something", ...},
"another_action": {"order":2, "title":"Do Something Else", ...},
"third_action" : {"order":10, "title":"Do More Things", ...},
//...
}
Each line has two parts:
"an_action"."order", "title", "ctx", and more.Here’s more information about them:
Action names must be unique, otherwise they may get overridden by other mods using the same action names. Specifically:
The easiest way to ensure the action names are unique, is to use a unique prefix. For example:
{
"extra-menus-mod_an_action" : { ... },
"extra-menus-mod_another_action": { ... },
"extra-menus-mod_third_action" : { ... },
//...
}
The parameters of an action controls what the action actually does and how it’s displayed in the menus. Here’s a table with all details:
Determines which Action Map the action will be assigned into. Common action maps include:
cat is menuctx is vluaCustom names can be specified, and the corresponding action map will be automatically created.
Defines where the code in onChange, onUp, onDown, or onRelative runs:
Deprecated contexts: “ui”, “ts”, and “slua”.
Specifies which source code will be executed when the action is triggered. The code execution context is defined in the ctx parameter of the current action
At least one of them must be defined. They are triggered like this:
The onChange, onDown, onUp, and onRelative fields contain short code snippets.
They are not a separate scripting language. They are strings that contain Lua code, with a few special placeholder words replaced by the input system before the code is executed.
Example:
{
"my_mod_toggle": {
"cat": "vehicle",
"order": 10,
"ctx": "vlua",
"onDown": "controller.getControllerSafe('myController').toggle()",
"title": "My Mod Toggle",
"desc": "Toggles a feature from my mod"
}
}
The action definition does two jobs:
| Field | When it runs | Typical use |
|---|---|---|
onChange |
Whenever the input value changes. Works with keys/buttons and axes. | Analog controls, held buttons, values that should follow input. |
onDown |
When a key/button is pressed. | Toggles, one-shot commands, mode changes. |
onUp |
When a key/button is released. | Releasing held state, momentary controls. |
onRelative |
For relative input such as mouse movement where supported. | Camera/mouse style controls. |
At least one of these fields must be present.
Use onChange for axes and analog controls. Use onDown for simple button toggles.
onDown or onUp for axis-only controls. Axes should use onChange.Before the action code is run, the input system replaces special placeholder words.
Common placeholders:
| Placeholder | Meaning |
|---|---|
VALUE |
Current input value. Usually 1 on press, 0 on release, 0..1 for normal analog inputs, or -1..1 when isCentered is true. |
FILTERTYPE |
Selected input filter type from the binding. Used by vehicle input functions. |
PLAYER |
Player index for multiseat-aware actions. |
ANGLE |
Steering wheel angle data where supplied by the binding/device. |
LOCKTYPE |
Steering lock type where supplied by the binding/device. |
OSCLOCKHP |
High precision timestamp used by some input paths. |
Programmatic action triggering can also replace:
| Placeholder | Meaning |
|---|---|
VEHICLEID |
Vehicle id passed to the action trigger helper. |
Example:
{
"set_table": {
"order": 1,
"ctx": "vlua",
"onChange": "electrics.values.table = VALUE",
"title": "Move Table",
"desc": "Moves the table with an analog input"
}
}
With a centered control:
{
"move_platform": {
"order": 1,
"ctx": "vlua",
"isCentered": true,
"onChange": "controller.getControllerSafe('platform').move(VALUE)",
"title": "Move Platform",
"desc": "Moves the platform in both directions"
}
}
isCentered changes the value range from 0..1 to -1..1.
The ctx field decides where the code runs.
ctx |
Runs in | Common use |
|---|---|---|
tlua |
Game Engine Lua. Default for regular actions. | UI/gameplay systems, global commands, editor/tool actions. |
vlua |
Active vehicle Lua. Default for vehicle-specific actions. | Vehicle controllers, electrics, powertrain, hydros, vehicle extensions. |
elua |
Game Engine Lua asynchronous path. | Legacy/special cases. Prefer tlua for normal GE Lua actions. |
bvlua |
All vehicle Lua contexts. | Broadcast a vehicle Lua command to all vehicles. |
Deprecated contexts:
ctx |
Status |
|---|---|
ui |
Deprecated. Use tlua and guihooks instead. |
ts |
Deprecated. Use tlua instead. |
slua |
Deprecated alias that is replaced with elua. |
If no ctx is specified for a regular action, the input system defaults to tlua. Vehicle-specific actions default to vlua.
Use vlua when the action controls the current vehicle:
"onChange": "input.event('throttle', VALUE, FILTERTYPE)",
"ctx": "vlua"
Use tlua when the action controls game systems, UI, editor tools, or global gameplay:
"onDown": "extensions.hook('onGameplayInteract')",
"ctx": "tlua"
Use bvlua only when every vehicle should receive the command:
"onDown": "electrics.set_warn_signal(true)",
"ctx": "bvlua"
Do not call vehicle-only APIs from tlua, and do not call game-engine UI systems directly from vlua.
actionMap controls which action map receives the binding.
Default behavior:
| Condition | Action map |
|---|---|
cat is menu |
MenuActionMap |
ctx is vlua |
VehicleCommonActionMap |
| vehicle-specific action | VehicleSpecificActionMap |
| otherwise | NormalActionMap |
You can override this with:
"actionMap": "BigMap"
The final scene object name is the action map name plus ActionMap, for example:
BigMapActionMap
Special case:
"actionMap": "MenuIndependent"
This creates a per-action menu-independent action map using the MenuIndependent_ prefix.
This regular action runs in Game Engine Lua and toggles a custom UI/tool feature:
{
"my_mod_toggle_tool": {
"cat": "menuExtra",
"order": 900,
"ctx": "tlua",
"actionMap": "Normal",
"onDown": "extensions.my_mod_tool.toggle()",
"title": "Toggle My Tool",
"desc": "Opens or closes my custom tool"
}
}
Suggested location:
lua/ge/extensions/core/input/actions/my_mod_actions.json
Use a unique file name and unique action names to avoid conflicts with other mods.
This vehicle-specific action writes a value to the vehicle electrics table:
{
"raise_arm": {
"order": 1,
"onChange": "electrics.values.arm = VALUE",
"title": "Raise Arm",
"desc": "Raises the vehicle arm"
}
}
Suggested location:
vehicles/<vehicleName>/input_actions_my_mod.json
Vehicle-specific actions automatically:
ctx = "vlua"Some vehicle parts define trigger/action data directly in JBeam events sections.
Example:
"events": [
["id", "title", "desc"],
["table_up", "ui.inputActions.tiltdeck.table_up.title", "ui.inputActions.tiltdeck.table_up.description",
{ "onChange": "electrics.values.table = VALUE", "order": 6 }
]
]
The action code uses the same onChange, onDown, onUp, and placeholder behavior as input_actions.json.
Use this when the action belongs tightly to a part or trigger setup. Use input_actions*.json when the action is a normal vehicle-level binding.
Vehicle interaction maps using *.interaction.json also use the same action-code format.
They are useful for interactions such as doors, latches, vehicle features, or part-specific controls that need to appear in the interaction UI.
See Interaction Maps and the vehicle trigger/interaction documentation for examples.
onDown for toggles.onChange for analog values and held controls.title and desc when shipping user-facing content.ui, ts, slua).Possible causes:
Possible causes:
onChange, onDown, onUp, or onRelative.ctx was used.Possible causes:
onDown instead of onChange.isCentered is missing for a centered axis.The category of an action is a mandatory parameter with only cosmetic effects.
It will influence where the action may be displayed in various in-game menus (such as the Options → Controls hierarchy of actions).
To see a list of available categories, please refer to the following file:
lua/ge/extensions/core/input/categories.lua
Was this article helpful?