Train Scripting Language Support
Back to Index Page
On this page, you can find information about a train scripting language that allows you to customize the runtime behavior of your trains to some degree. The scripting language is accessible to non-programmers in a hopefully intuitive way. The idea behind this language was originally proposed in this thread on the official openBVE discussion board. Support for the scripting language is offered through a plugin. At the moment, everything is still in the earliest stages of development, highly experimental, subject to change at any time, and likely far from practically usable.

Getting Started

If you want to give the scripting language a try yourself, first pay a visit to the Get Add-ons menu. Make sure to enable Shared Library packages, then look out for the add-on called Train Scripting Language Support, filed under Other Countries, Other Cities, Other Operators. After you install the add-on, you can enable support for the scripting language by placing the following ats.cfg in your train folder:
$trainscript-train-plugin/TrainScript.dll
If you release your train as managed content, be sure to add the following dependency to your package.cfg and descriptor:
dependencies = trainscript-train-plugin (0.1)
For as long as openBVE does not support multiple concurrent train plugins, using the scripting language means that you cannot use another plugin such as OdakyufanAts or UkTrainSys at the same time.
The next step is to create a folder called Scripts inside your train folder. You can place as many scripts in there as you want. All scripts must have the file extension .script.
The best thing about this scripting language is that you can edit your scripts while the game is running. Whenever you make a change, hold down the home and end keys for three seconds, then all scripts will be reloaded. If there is an error in any of the scripts, all lamps in the cab will be lighted. You should check the debug dialog by pressing F10. Somewhere on that screen, you will find a hopefully helpful error message that should help you fix the problem.

Syntax

A script consists of tags. A tag is started by [tag] and ends with [/tag]. It can contain parameters of the form key=value as well as other tags.
Example:
[tag]
    key = value
    [tag]
        key = value
    [/tag]
[/tag]
It is highly recommended that you indent everything between a starting tag and an ending tag with tabs or spaces. If a tag does not contain anything, the shorthand notation [tag /] can also be used to start and end the tag on the same line.

Action Tags

An action tag performs an action. All top-level tags in a script must be action tags and are performed as soon as the simulation starts.

[event]

Events are the foundation of the entire scripting language. Even though it might sound somewhat confusing at first, the [event] tag is an action. When this action is performed, openBVE is told to start monitoring an event. What kind of event is specified with the name parameter. Depending on the kind of event, there may be further parameters. As soon as the event triggers, all actions that are enclosed by the [event] and [/event] lines are performed.
Example:
[event]
    name = key down
    type = A1
    [sound]
        index = 0
        looped = yes
    [/sound]
[/event]
The following kinds of events are available:

key down

key value
name key down or keydown
type Key : The abstract key.
This event happens as soon as a key is pressed down. It will only trigger again after the key is released and then pressed down again.

key press

key value
name key press or keypress
type Key : The abstract key.
This event happens when a key is pressed down. When held down, the key press is repeated in regular intervals and this event also triggers every time this happens.

key up

key value
name key up or keyup
type Key : The abstract key.
This event happens as soon as a key is released. It must have been pressed down before, of course.

beacon

key value
name beacon
type Range : The beacon type.
signal Range : The signal aspect.
This event happens every time the specified beacon is passed, but only if the attached signal matches the specified aspect.

count down

key value
name count down or countdown
interval Time : The interval.
This event happens as soon as the countdown has run out. After that, the event is automatically stopped. This means it will not be monitored again until the [event] action is performed again.

[panel]

This action can be used to modify the appearance of the panel or exterior. The way it works is that you assign values to indices, and you can query the value of an index using atsINDEX in the panel.cfg, or using pluginState[INDEX] in animated objects. This action takes the following parameters:
key value
index Integer : The index. Must be between 0 and 999.
value
values
Integer : The value, or multiple values separated by comma. If multiple values are entered, these will be cycled through.
interval Time : This is the time it takes to cycle through the whole list of values. You don't need this if you only have one value.
Examples:
[panel]
    index = 0
    value = 1
[/panel]
[panel]
    index = 0
    values = 1, 0
    interval = 1.3 seconds
[/panel]

[sound]

This action plays a sound. Sounds must be configured in the sound.cfg under the [ats] section where they are assigned an index. You can choose to play sounds once or in a loop, and change the pitch or volume if you want. This action takes the following parameters:
key value
index Integer : The index as configured in the sound.cfg
looping Boolean : Whether to play this sound in a loop.
volume Ratio : The volume. By default 100%.
pitch Ratio : The pitch. By default 100%.
Example:
[sound]
    index = 0
    looping = yes
    volume = 80%
    pitch = 200%
[/panel]
You can stop sounds using the [stop_sound] action.

[stop_sound]

This action stops a sound. Sounds must be configured in the sound.cfg under the [ats] section where they are assigned an index. This action takes the following parameters:
key value
index Integer : The index as configured in the sound.cfg
Example:
[stop_sound]
    index = 0
[/stop_sound]

[handles]

This action overwrites the reverser, power notch or brake notch. If any of the handles is overwritten, the driver can set that lever into any position without effect. This allows you, for example, to force an emergency brake application. This action takes the following parameters:
key value
reverser Reverser : The position of the reverser.
power Power : The power notch.
brakes Brakes : The brake notch.
Example:
[handles]
    reverser = N
    power = N
    brakes = EMG
[/handles]
You can use [release_handles] to release the handles again.

[release_handles]

This action releases the handles again. This action does not take any parameters.
Example:
[release_handles /]

[abort_countdown]

This action aborts all countdowns that are currently monitored. This action does not take any parameters.
Example:
[abort_countdown /]