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.
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.
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.
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.
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
|
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
|
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
|
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.
|
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.
|
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.
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]
|
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.
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]
|
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.
This action releases the handles again. This action does not take any parameters.
This action aborts all countdowns that are currently monitored. This action does not take any parameters.