Help
RailScript (as of 12.01)
RailScript is RailKernel’s built-in automation language. It reads live railway state, changes supported values, waits for events and starts or queues saved routes without bypassing RailKernel’s routing and safety rules.
What RailScript can do
A RailScript can inspect command stations, feedbacks, accessories, signals, blocks, trains, locomotives, train types, routes, variables, counters, timers and system state. Scripts can make decisions, wait for a condition, repeat work, write to the script log, operate writable attributes and start an existing Route Move. Project scripts and their language are stored with the project.
The script editor
Each script has a name, an enabled flag, a language and source text. Validate checks the complete program without running it. Run starts the current source. Stop cancels the current execution. Changing between English, Dutch and German translates RailScript keywords while preserving object names, strings and comments. Tab or Ctrl+Space opens context-sensitive completion for keywords, objects and attributes.
Execution and safety
IF and WHILE evaluate immediately. FOR EACH walks through a snapshot of every object in a collection such as block[] or feedback[]. The loop variable exposes that object’s normal namespace attributes. WHEN waits without blocking RailKernel and resumes when its condition becomes true or its optional UNTIL condition wins. PROMPT pauses only the current script while asking the user for confirmation or a typed value; RailKernel and other scripts continue running. A train’s newFeedback event is consumed by the successful WHEN that reads it and then becomes false again. MOVE delegates to the normal Route Move engine, so its safety rules remain active. RUN starts another project script; RUN THIS restarts the current script and immediately completes the old execution, ignoring all following statements.
Example: departure from a station
This extended example shows a complete departure sequence: detect a train at its platform, stop it, observe a station dwell timer, sound the conductor’s whistle and start a saved departure route. Replace the object names and function number with values from your own project.
-- Departure from the station with a conductor's whistle
WHEN train["Intercity 1200"].currentBlock = "Platform 1"
AND train["Intercity 1200"].placed
DO
LOG "Intercity 1200 has arrived at platform 1"
SET locomotive["NS 1200"].speed = 0
SET timer["station dwell"].durationMillis = 30000
SET timer["station dwell"].running = true
WHEN timer["station dwell"].expired
DO
-- Function 3 is assumed to contain the conductor's whistle.
SET locomotive["NS 1200"].function[3].active = true
SET timer["whistle"].durationMillis = 1500
SET timer["whistle"].running = true
WHEN timer["whistle"].expired
DO
SET locomotive["NS 1200"].function[3].active = false
LOG "Departure signal given"
MOVE "Intercity 1200" USING "Depart platform 1"
END
END
ENDComplete 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.
Comments
-- comment
// comment
# commentLocal variables
INT count = 0
STRING message = "Ready"
BOOLEAN allowed = true
count = count + 1Prompt the user
-- 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"].valueRead and write namespace values
LOG feedback["K31"].occupied
SET counter["departures"].value = 1
SET accessory["A.1"].position = STRAIGHT
SET locomotive["Class 66"].speed = 64Conditions and expressions
IF feedback["K31"].occupied AND NOT block["Station"].reserved
THEN
LOG "The route may be prepared"
ELSE
LOG "Waiting"
END
-- Operators: + - * / = != < <= > >= AND OR NOT ( )Wait for an event, optionally with a limit
WHEN feedback["K31"].occupied
UNTIL timer["limit"].expired
DO
LOG "K31 became occupied"
ELSE
LOG "Time limit expired"
ENDNULL and missing runtime values
IF train["Intercity"].currentRoute != NULL
THEN
LOG "The train has an active route"
ENDStart and coordinate scripts
RUN "Station loop sounds"
WHEN !script["Station loop sounds"].isRunning
DO
LOG "The sound script has completed"
END
-- Restart this script; nothing below RUN THIS is executed.
RUN THISReact to every train feedback
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
INT step = 0
WHILE step < 10
DO
step = step + 1
ENDCollections and FOR EACH
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: " + occupiedSimple delay
WAIT 1500
WAIT timer["delay"].durationMillisScript logging
LOG "Train speed: " + locomotive["Class 66"].speedStart or queue a saved route
MOVE "Intercity" USING "Station loop"
MOVE "Intercity" USING "Station loop" QUEUEObject selectors
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.