RailScript
Complete current syntax
Keywords are shown in English. The editor can translate them to Dutch or German. Statements may be placed on one line or spread over several lines where the grammar is unambiguous.
Supported statements
| Statement | What it does |
|---|---|
PARAMS TYPE name [, TYPE name …] | Declare the script input parameters before its executable statements. |
RETURNS TYPE | Declare the type of value this script returns with RETURN. |
INT name = expression | Declare a local whole-number variable. STRING and BOOLEAN work in the same way. |
OBJECTTYPE name = domain["object"] | Declare a strongly typed local reference to one existing namespace object. |
name = expression | Assign a new value to an already declared local variable. |
SET object.property = expression | Write a writable namespace property. |
LOG expression | Write a value to the RailScript log. |
IF condition THEN … ELSE … END | Execute one of two branches; ELSE is optional. |
WHEN condition UNTIL condition DO … ELSE … END | Wait for an event condition; UNTIL and ELSE are optional. |
WHILE condition DO … END | Repeat statements while a condition remains true. |
FOR EACH item IN object[] DO … END | Iterate over a snapshot of an object collection. |
WAIT milliseconds | Pause only this script for the specified duration. |
PROMPT text | Pause this script and ask the user for confirmation. |
PROMPT text, variable | Ask the user for a value and store it in an existing variable. |
MOVE train USING route [QUEUE] | Start a saved route immediately or queue it. |
MOVE train TO block [SAVEAS name] | Generate a route to a destination block and optionally save it. |
RUN "script" [WITH arguments] | Start another enabled project script with optional parameters and continue immediately. |
RUN THIS | Restart this script and complete the current execution immediately. |
CALL "script" [WITH arguments] | Start a script and asynchronously wait for completion; any returned value is ignored here. |
TYPE result = CALL "script" [WITH arguments] | Wait for a script and store the value supplied by RETURN. |
RETURN expression | Finish the current called script and return its declared value. |
RESERVE targets FOR train | Atomically reserve blocks, accessories or routes for a placed train. |
RELEASE targets FOR train | Atomically release reservations belonging to a train. |
SWITCH [commandStation] [PROTOCOL p] ADDRESS expression POSITION position | Directly switch one decoder address; the defaults are DCC and the sole connected command station. |
Comments
-- comment | // comment | # comment
Examples
-- comment
// comment
# commentLocal variables
INT name = expression | STRING name = expression | BOOLEAN name = expression | name = expression
Examples
INT count = 0
STRING message = "Ready"
BOOLEAN allowed = true
count = count + 1Prompt the user
PROMPT text [, variable]
Examples
-- Confirmation only
PROMPT "Place the train on the programming track"
-- Store input in an existing local variable
INT speed = 40
PROMPT "Required speed?", speed
-- Or in an existing writable project variable
PROMPT "Driver name?", variable["driver"].valueWait for an event, optionally with a limit
WHEN condition [UNTIL condition] DO statements [ELSE statements] END
Examples
WHEN feedback["K31"].occupied
UNTIL timer["limit"].expired
DO
LOG "K31 became occupied"
ELSE
LOG "Time limit expired"
ENDSimple delay
WAIT milliseconds
Examples
WAIT 1500
WAIT timer["delay"].durationMillisSwitch a decoder address directly
SWITCH [commandStation] [PROTOCOL protocol] ADDRESS expression POSITION position
Examples
-- DCC on the sole connected command station
SWITCH ADDRESS accessory["Station signal"].address5 POSITION GREEN
-- Fully specified form
SWITCH commandStation["YaMoRC"] PROTOCOL MM ADDRESS 17 POSITION REDStrongly typed object variables
OBJECTTYPE name = domain["name or GUID"]
Examples
BLOCK station = block["Platform 1"]
TRAIN intercity = train["IC 123"]
ROUTE journey = route["Station loop"]
ACCESSORY turnout = accessory["W12"]
SET station.maximumSpeed = 60
RESERVE station FOR intercity
MOVE intercity USING journeyAn object variable refers to exactly one existing object for the duration of this script execution. Validation checks both the declared type and the type on the right-hand side of the equals sign. Available types are COMMANDSTATION, FEEDBACK, ACCESSORY, SIGNAL, SWITCH, BLOCK, TRAIN, WAGONGROUP, TRAINTYPE, LOCOMOTIVE, VARIABLE, ROUTE, SCRIPT, COUNTER and TIMER. COMMAND_STATION, WAGON_GROUP and TRAIN_TYPE are accepted as well.
Read and write namespace values
object.property | SET object.property = expression
Open the RailScript namespace reference
Examples
LOG feedback["K31"].occupied
SET counter["departures"].value = 1
SET accessory["A.1"].position = STRAIGHT
SET locomotive["Class 66"].speed = 64Conditions and expressions
IF condition THEN statements [ELSE statements] END
Examples
IF feedback["K31"].occupied AND NOT block["Station"].reserved
THEN
LOG "The route may be prepared"
ELSE
LOG "Waiting"
END
-- Operators: + - * / = != < <= > >= AND OR NOT ( )NULL and missing runtime values
expression = NULL | expression != NULL
Examples
IF train["Intercity"].currentRoute != NULL
THEN
LOG "The train has an active route"
ENDParameters and return values
PARAMS TYPE name [, TYPE name …] | RETURNS TYPE | RETURN expression
Examples
-- This is the separate script 'Choose station block'
PARAMS BLOCK currentBlock, TRAIN train
RETURNS BLOCK
SET currentBlock.maximumSpeed = 50
RETURN currentBlockWhen used, PARAMS belongs at the top; RETURNS is also part of the script header, directly after PARAMS or otherwise as the first declaration. Available types are INT, STRING, BOOLEAN, EVENT and every RailScript object type. Primitive values are copied. Objects are passed and returned as live GUID references, so changing an object through a parameter changes the real project object. Every execution path in a script with RETURNS must reach a matching RETURN.
Start scripts with RUN and CALL
RUN "script" [WITH arguments] | TYPE result = CALL "script" [WITH arguments] | CALL "script" [WITH arguments]
Examples
-- RUN starts the script and continues immediately
RUN "Announce departure" WITH train["Intercity"]
-- CALL waits and stores the BLOCK return value here
BLOCK chosen = CALL "Choose station block" WITH block["Platform 1"], train["Intercity"]
LOG chosen.name
-- A standalone CALL may ignore the returned value
CALL "Check station" WITH chosen
-- Nothing below RUN THIS is executed
RUN THISRUN is fire-and-forget: the called script starts with the supplied parameters while the caller continues. CALL waits for RETURN without blocking the user interface, so WAIT, WHEN and PROMPT remain asynchronous inside a called script as well. CALL chains are limited to 32 levels. Running and waiting scripts are visible in the Script Monitor and their execution is written to Script Logging; enable Debug there for statement-level logging.
Warning: scripts can start other scripts and restart themselves. Uncontrolled or very frequent starts can create so many concurrent executions that RailKernel, or even the entire system, becomes unresponsive. Keeping such constructions bounded and manageable is the user’s responsibility.
The event parameter
PARAMS EVENT event
Examples
-- RailKernel supplies this automatically when an object event starts the script
PARAMS EVENT event
LOG event.type + " from " + event.objectType + " " + event.objectName
IF event.trainName != NULL
THEN
LOG "Train: " + event.trainName
ENDThe parameter name is your choice. With PARAMS EVENT trigger, for example, the same script uses trigger.type and trigger.objectName. The existing implicit event.* values remain available for older scripts.
React to every train feedback
WHEN condition DO statements END
Examples
WHILE train["Intercity"].currentRoute != NULL
DO
WHEN train["Intercity"].newFeedback
DO
SET train["Intercity"].function[3].active = true
WAIT 500
SET train["Intercity"].function[3].active = false
END
ENDLoop
WHILE condition DO statements END
Examples
INT step = 0
WHILE step < 10
DO
step = step + 1
ENDCollections and FOR EACH
FOR EACH item IN object[] DO statements END
Examples
INT occupied = 0
FOR EACH item IN block[]
DO
IF item.occupied
THEN
occupied = occupied + 1
LOG item.name + " is occupied"
END
END
LOG "Occupied blocks: " + occupiedScript logging
LOG expression
Examples
LOG "Train speed: " + locomotive["Class 66"].speedStart or queue a saved route
MOVE train USING route [QUEUE]
Examples
MOVE "Intercity" USING "Station loop"
MOVE "Intercity" USING "Station loop" QUEUEGenerate a route to a destination block
MOVE train TO block [SAVEAS "route name"]
Examples
-- Generate and execute a temporary route
MOVE train["Intercity"] TO block["Platform 4"]
-- Save the generated route as well
MOVE "Intercity" TO "Platform 4" SAVEAS "Intercity to platform 4"
-- Names without spaces may be written without quotes
MOVE Intercity TO Platform4Reserve and release railway resources
RESERVE targets FOR train | RELEASE targets FOR train
Examples
-- Reserve one or more resources atomically for a placed train
RESERVE block["Platform 1"], accessory["A.1"] FOR train["Intercity"]
-- A block, accessory or complete route may be reserved
BOOLEAN acquired = RESERVE route["Station loop"] FOR train["Intercity"]
IF acquired
THEN
LOG "Route reserved"
END
-- Release the same resources; RELEASE also returns BOOLEAN
BOOLEAN released = RELEASE route["Station loop"] FOR train["Intercity"]Object selectors
domain["name or GUID"].property
Examples
feedback["K31"].occupied
feedback["object-guid"].occupied
locomotive["Class 66"].function[0].nameValue rules
- Object names and GUIDs are both accepted as selectors.
- Text uses double quotes; supported escapes include \n, \r, \t, \" and \\.
- Numbers may be integers or decimals. INT local variables require whole-number values.
- Boolean literals are true and false. Enum values such as STRAIGHT are written without quotes.
- SET is required for namespace attributes; local variables are assigned without SET.
- A script failure is recorded in RailScript logging and in the Script Monitor.
- NULL represents a value that is currently absent, such as currentRoute when a train has no active route.
- The ! operator is a compact equivalent of NOT.
- PROMPT accepts BOOLEAN, STRING and INT variables. BOOLEAN uses a TRUE/FALSE list; INT accepts whole numbers only. Cancelling the dialog cancels the waiting script.