How to set up signals

A collection of tutorials, guides and FAQ's.
Forum rules
Please only create new topics if you are posting a new guide, tutorial or FAQ.

Feel free to post in any existing topic asking questions, seeking clarification etc.

How to set up signals

Postby AndiS » Fri May 16, 2014 12:50 pm

There is a lot to worry about in signals outside the signal script. This post focusses on semaphores. There is a guide to colour light signals here (focussing on a CLS shunt signal).

Standard Set-up

The default semaphores are set up as follows. Note that this refers to running signals, the disk signals are set up differently as described further below.

The root file is a signal blueprint. It is this file that you place in the world editor.
  • Name is something like B Lattice CombSig_hd 1T, i.e., prefix followed by description of the signal function followed by an indication of how many numbered links it has.
  • Category is track infrastructure.
  • Valid In Scenarios is false in most cases. If you want them to be scenario-specific, select true here.
  • Geometry ID can be any static part of the signal. In practice, this will be the shape of the post.
  • Number Of Track Links includes link 0, thus a 1T signal has 2 in this field.
  • Stopping is true if AI should see this signal as block signal, and false otherwise.
  • Junction Signal Type is only relevant for signals with more than one track link. If it is none, the table for the link properties is not shown in the right-hand fly-out. For all other values, it is shown. The type could be queried in the script, but no one does it.
  • Control Mode can be queried by the script, but again, it is useless as you could just as well set a constant in the script.
  • Script Name (eScriptComponentBlueprint in the .bin file) specifies the script without file extension, but with the complete path starting at Assets, i.e., including the provider & product folders.
  • Children fall into three categories: Sound, arms and static items. For all of them, the Child Name must equal the string left of the : in all Calls refering to it.

For the sound, the file referred to as a child is a simple Sound Blueprint. It does nothing but refer to the sound proxy in field Sound Component Blueprint.
This file is a Track Item Audio Control. It has the extension .proxybin and can be converted to XML by appending .bin to the end, then apply serz.exe. You could could replace extension proxybin by bin, too, I guess.
Besides a bunch of entries specifying the sound, it contains several fields that are connected to the signal script.
  • Controller Name is the second parameter in the system call to influence the sound. In the default scripts, it is SignalProgress.
  • TriggerType is ValueMovesPast in the default signals. This means that the sound is triggered if the value of the controller moves past the threshold given in the next line. However, you could also have Value Is Changing there, which means that the sound is triggered whenever the value is changed.
  • Trigger Value is the threshold for "ValueMovesPast". It should be irrelevant for "ValueIsChanging". In the default signals, this is 0.5, which results in the sound being played when the controller is changed from 0 to 1 and from 1 to 0.
  • You could set Trigger Type to ValueDecreasePast to only play the sound when the value decreases. Adding another sound child definition for ValueIncreasePast permits playing a different sound for up and down motion of the arm. I have not seen that at work, though.

For each arm, an Anim Procedural Scenery Blueprint is used. There is also Anim Scenery Blueprint - without Procedural in the name - but that is for scenery that only runs auto animations. In the version with Procedural in the name, animation can be Animation or Auto Animation. For signal arms, you need the version without Auto, as you don't want them to move all the time.
GeometryID refers to the shape of the arm.
  • AnimSet contains two references to animations - one for clearing and one for closing. Both refer to .ban files (created from .ia files) in their Animation Name field. Again, the path is giving including provider and product.
  • The names given in AnimationID are what the scripts refer to. They are chosen freely. By convention, they are Clear01 and Stop01. I never understood the need to number them as this file refers to exactly one arm.
  • Shadow type should be None, if only for the poor guys still on non-TSX mode.
  • Anim Procedural Scenery Blueprints don't have a display name and they don't show up in the object list.

For each static item, a Scenery Blueprint is used. Examples for such static items are the Rule 55 plate (diamond), ladders, motors, lamps, and anything else that is not animated and that cannot reasonably be a part of the post shape.
  • Keeping Category at Uncategorised keeps these bits out of the object list where you don't want them normally.
  • Shadow type None will be a good idea in many cases.

Monolithic single-arm signals

Alternatively to the set-up above, you can have arm and post in a single blueprint. I would not recommend this if there is more than one arm.

Here, you use Anim Signal Blueprint, because this blueprint describes a signal's root object, and it describes animations.

  • GeometryID refers to post and arm (disk) in a single file.
  • AnimSet contains two animations, one for clearing and one for closing. Again, the important bit is that AnimationID links to the strings used in the script.
  • Various signal properties are as described above.
  • There are no children for arms.
  • The sound is set up as described above.
  • There is no reason why you could not have static child items, but they are rarely seen.

You may very well create a monolithic signal from a single stop arm and nothing else. You would then fix that wherever you want.

I do not claim that monolithic signals with more than one arm are impossible. However, I would not want to script the control of their animations seeing how funny the code is that you are required to use for a single arm. (You must reset the opposite animation all the time while you run one animation.)


The following is an abstract list of the dependencies. I took out all the concrete examples of names to be 100% sure that people understand that names are nothing, the location where the string is placed is all. I use underscore instead of the usual italics for better readability.

Sound child item

Script: Call ("child name:SetParameter",
Signal blueprint: <ChildName d:type="cDeltaString">child name</ChildName>

Sound controller

Script: Call ("...SetParameter", "sound controller", ...
Sound proxy: <ControllerName d:type="cDeltaString">sound controller</ControllerName>

Arm child item

Script: gArmTable[ARM_MAIN][ARM_HOME][SEM_CHILD_NAME] = "child name"
Signal blueprint: <ChildName d:type="cDeltaString">child name</ChildName>

Instead of ARM_MAIN, you can have other values for other routes. Instead of ARM_HOME you can may have ARM_DIST for the distant arm. Both depend on the script.

Arm animation reference

gArmTable[ARM_MAIN][ARM_HOME][SEM_PROCEED_ANIM] = "opening animation"
gArmTable[ARM_MAIN][ARM_HOME][SEM_BLOCKED_ANIM] = "closing animation"

Anim Procedural Scenery Blueprint:
<AnimationID d:type="cDeltaString">opening animation</AnimationID>
<AnimationID d:type="cDeltaString">closing animation</AnimationID>
Top Link Driver!
Posts: 629
Joined: Wed Apr 09, 2014 5:48 pm
Has thanked: 260 times
Been thanked: 301 times

Re: How to set up signals

Postby AndiS » Tue Jun 24, 2014 10:38 am

I just analysed Anthony's beautiful signals and found that this setup works, too:

  • The signal blueprint has child elements for the arms, but not for the sound.
  • The arm blueprints are Animated Signal Blueprints, not scenery. They do not contain a reference to a script, though. But they have a child blueprint named ControlSound linking to the sound as described above.

Checking the good old developer documentation, you find the statement that for ChildName:SomeCall, the game searches all descendants to find one named ChildName. That includes grandchildren, and Anthony's signals show it works.
Top Link Driver!
Posts: 629
Joined: Wed Apr 09, 2014 5:48 pm
Has thanked: 260 times
Been thanked: 301 times

Re: How to set up signals

Postby cjbarnes5294 » Tue Jun 24, 2014 12:30 pm

AndiS wrote:Checking the good old developer documentation, you find the statement that for ChildName:SomeCall, the game searches all descendants to find one named ChildName. That includes grandchildren, and Anthony's signals show it works.

That's good to know, thank you. I can't currently think of a situation when I might need to call descendants beyond the first child, but it's useful to know it can be done if desired. :)

The Red Queen Hypothesis, applicable to train sim development?

"Here, you see, it takes all of the running you can do, to keep the same place."
Posts: 398
Images: 82
Joined: Mon Mar 31, 2014 12:40 pm
Location: Gloucestershire/North Yorkshire
Has thanked: 551 times
Been thanked: 187 times

Re: How to set up signals

Postby AndiS » Tue Jun 24, 2014 12:57 pm

There are a few fine details in favour of Antony's setup:

It makes sure all the signals have the sounds - add it half a dozen arms and a hundred signals are fitted with sound.

You can have different sounds for different arms, without the script knowing about it. You could have two sound children in the signal blueprint and alternatively play one of them, based on script logic, but it complicates the script. Adding different sounds under the same name is more elegant.

In theory, different arms would play copies of the same sound when they move simultaneously, but in practice, only one arm should move at a time anyway. Except for resetting both main and distant arm of a signal, when and if that is done simultaneously.

You might have some sound specific to the signal, like rattling of some chain or wire, then making the sound a child of the signal itself would be better. But for semaphores, it does not look like there is a need for that. A bracket makes the same sound as a single post. At least I never heard of anyone providing different sound recordings for different signal configurations.

Much to my disappointment, I cannot make up any reasonable example for another usage of grandchildren. :roll:
Top Link Driver!
Posts: 629
Joined: Wed Apr 09, 2014 5:48 pm
Has thanked: 260 times
Been thanked: 301 times

Return to Tutorials, Guides, FAQ

Who is online

Users browsing this forum: No registered users and 1 guest