Creating a Signal System with SigEdit - MagnumMacKivler/trakpak3 GitHub Wiki

Back to In-Game Tutorials

Back to Adding Signals to your Map

NEXT Tutorial: Placing Signals and Blocks in Hammer

In this tutorial, we'll walk through how to create a simple signaling system using SigEdit, Trakpak3's in-game signal system editor.

Table of Contents

Getting Started

Create a New Signal System

Create a Save

Define Rules

Define Signal Types and Tags

Signal Interpretations

Logic Editor

Signal Simulator

Usage in Maps

Getting Started

  1. You're going to want to figure out what you want your signal system to look like.

In this example, we'll be replicating the Signals of the Delaware and Hudson Railroad. If you're looking to replicate any existing signaling system, many North American signal systems can be found on Railroadsignals.us. It's a great learning resource, too!

  1. You're going to want to bind a key to the console command tp3_signal_editor.

I use the forward slash key ( bind / tp3_signal_editor ), but you can use any key you want, as long as it doesn't overlap with something else. Typing bind <key> (for example bind / ) will show what, if anything, is bound to that key.

Create a New Signal System

Upon pressing the key for the first time, you should be greeted by a small window with a couple of buttons and a text box.

New/Load

Since we're making a signal system from scratch, we're going to want to create a new one.

To create a new signal system, press Create New.

The text box can be used to load an existing signal system later. To load an existing signal system to edit:

  1. Type the filename of the saved signal system (located in garrysmod/data/trakpak3/signalsystems/ ) without the extension (no ".txt").
  2. Press Load Existing.

Create a Save

Immediately after you complete the last step, you should find yourself face to face a much larger window. Before we can start filling out information, it's important to set up a save in case you crash or need to work on this later.

  1. Using the tabs at the top of the window, navigate to the Save Signal System window.
  2. Type in a name for your signal system (avoid using nonstandard characters; it's a file name).
  3. Hit the Save Signal System button.

If everything is successful, a chat message should appear, indicating that the file is saved correctly.

Imgur

It is recommended that you save frequently while making signal systems.

Define Rules

Now that we have a basic save set up, we can start defining the list of rules that the signal system can display. Use the tabs at the top of the window to navigate to the Define Rules window.

Imgur

Each Rule we make corresponds to a signal indication from the railroad's rulebook. Looking at our D&H signal chart, we can see there are a total of 9 rules: Stop, Stop and Proceed, Medium Approach, Approach, Medium Approach Medium, Medium Clear, Advance Approach, Approach Medium, and Clear. Let's start from the most restrictive of the list and work our way up.

  1. Start by typing the first rule name into the Rule Name box. In our example, the first rule name will be "Stop".
  2. Click on the Signal Speed dropdown and select the signal speed. In our example, select "Stop/Danger" (See Note 1).
  3. Type the rule's description into the Rule Description box. This is where you detail exactly what the signal means besides simply maximum permissible speed.
  4. Select a Rule Color. For our example, we will choose "Red" (See Note 2).
  5. Press Add New Rule and the rule will be added to the table above.
  6. Repeat steps 1-5 for all the other rules your signal system will be using.

Note 1: If a signal requires a train to stop (but then allows it to proceed, typically at restricted speed), then it's recommended to set the rule's Signal Speed to "Restricted" instead of "Stop/Danger".

Note 2: The Rule Color is not what the signal will show (we will configure that later). Instead, this is the color that the engineer will see when he/she uses Signal Vision to decode signals in-game.

Imgur

Imgur

Some tips and tricks for defining rules:

  • If you click a rule in the table at the top, the information will auto-populate into the boxes at the bottom. If desired, you can make changes and then press Update Selected to apply them.
  • The text boxes can be cleared by pressing Clear Data Entry. This will not affect the rules in the table above.
  • The table items can be reordered by selecting the item and pressing the Move Up or Move Down buttons. Order doesn't matter functionally, but it helps to keep things organized.

Once you're done defining rules, go ahead and Save.

Defining Signal Types and Tags

Use the tabs again to navigate to the Define Signal Types & Tags window. Here we see two sets of buttons and text boxes that are used to generate a simple list.

Signal Types

Some signal systems use many different signal types to show specific rules. For example, a railroad might use Color Light signals, Semaphores, and Position Light signals - and they all have different ways to show "Stop"! Some might use bodygroups, some may use skins, and some may use animation cycle (fraction), and some may use different values for each one. To organize these, signals should be split up into Signal Types; all the signals in one Signal Type should behave the same for each rule they are expected to show.

Imgur

For the purposes of this test, we'll be setting up three different signal types: one for Color Light / Searchlight signals (they use the same system), one for dwarf color light signals, and one for semaphores.

  1. In the Signal Type Name box, type the name of a signal type. For our example, type "cl_high" for wayside (high) color light signals.
  2. Press Add Signal Type. The signal type should now appear in the list to the left.
  3. Repeat steps 1 & 2 for all other signal types your system will support. For our example, add a signal type "cl_dwarf" for the color light dwarf signals and "uq_high" for upper quadrant semaphore signals.

As always, don't forget to save!

Imgur

Tags

Tags are additional information that the mapper can assign to a signal to give it hints as to what rule to display under specific circumstances. For example, tags can be used to make a signal Permissive; instead of displaying Stop, it would display Stop and Proceed instead. Tags can also be used to limit a signal's speed, picking only slow speed aspects for a signal with the "slow" tag set for example. Tags are used later on in the Logic Editor. For now, add the tags "abs" and "medium" using the same method as above:

  1. In the Tag Name box, type the name of the tag you wish to add. For our example, type "abs". This will be used to make automatic block signals display Stop and Proceed instead of Stop.
  2. Press Add Tag. The tag should now appear in the list on the right.
  3. Repeat steps 1 & 2 to add the tag "adv". This tag is to designate signals with 2 or more heads that are capable of showing Advanced Approach, which is yellow over yellow in this signal system. Signals without this tag won't be able to display Advanced Approach, which is what we want for single-headed signals.

Any number of tags can be assigned this way. Some other signals can use tags to designate grade signals, but our example doesn't have them, so we'll just keep 'abs' and 'adv' for now.

Don't forget to save!

Imgur

Signal Interpretations

Use the tabs at the top to navigate to the Signal Interpretations window. Here we see a list of the rules and a list of the signal types we defined earlier, some fields for bodygroups, skins, and animation cycles, and three signal models which are rendered on the right.

The Signal Interpretations window is used to define how each Signal Type expresses each rule. For example, a color light signal will use bodygroups to show the colors red, yellow, and green. A semaphore, however, will use a combination of bodygroups and animation cycle!

Imgur

Setting the Preview Models

The three signal models on the right will be used to display a preview of the signal aspects. Before we start, be sure to pick a set of models that suit the Signal Type being worked on. To change the preview models, simply paste the model path into the text box and press Enter. The slider can be used to zoom in and out if necessary.

Since we will be starting with the color light Signal Type (cl_high), the default models should be okay for now.

Configuring the Signal Type

Color Light

To start, let's configure the color light Signal Type (cl_high).

  1. Select "cl_high" in the Signal Types list.
  2. Select "Stop" in the Rule Name list.
  3. Pull up our D&H Signal Aspect Chart from earlier and examine the box for the Stop aspect. As expected, Stop is shown with all red signals.
  4. In each Bodygroups field, type "1".
  5. Press Apply to Selected. You should now notice each preview model turn on and show a red light.

You have successfully configured the Signal Type cl_high's aspect for Stop. Whenever a signal with the cl_high Signal Type is ordered to show a Stop signal, this is what it will look like.

Now, repeat the process for all the other Rules in the Rule Name list. If you don't know what bodygroup to choose to replicate a certain color, you can always consult the Bodygroup, Animation, and Skin (BGAS) guides for the signal models chosen. Additionally, you can Copy and Paste a bodygroup setup using the Copy Data and Paste into Selected buttons.

Imgur

Imgur

Some Rules may be identical for the same Signal Type. For example, "Stop" and "Stop and Proceed" will both show up as three reds - The "Stop and Proceed" signals are discernible by the number plate affixed to the signal mast, which indicates a permissive signal. We have already partially added provisions for that by adding the "abs" tag; we will finish that later on.

Color Light Dwarf

Next, we'll set up the Color Light Dwarf signal. The color light dwarf signal is a single model, so just set the topmost signal to models/trakpak3_us/signals/colorlight/dwarf_ryg.mdl and select the "cl_dwarf" Signal Type.

Imgur

Now, we just repeat the process we did for the high signals... except, there's a problem. Dwarf signals can typically only show reduced-speed aspects, which is why this one has only one head. For example, the dwarf signal should be able to show Medium Approach and Medium Clear, but not Approach or Clear (regular). To correct this, we'll be taking advantage of the Rule Override feature.

To start with, set up all the indications the dwarf signal should have no trouble showing: Stop, Stop and Proceed, Medium Approach, and Medium Clear. The color light dwarf signal works a little differently from the high signals; instead of just setting the first bodygroup, you have to set three of them, because the lights are independently controllable.

Color Bodygroups
Red 1 0 0
Amber 0 4 0
Green 0 0 6

Imgur

Now that we have the good indications down, we can set up the overrides for the indications that it can't show: Approach, Medium Approach Medium, Approach Medium, Advance Approach, and Clear. We'll start with Approach. You don't need to fill in any of the boxes, just set the Rule Override combo box to a valid indication, in this case "Medium Approach", and hit Apply.

Imgur

Then, just repeat for the other invalid indications. You want to pick the least restrictive indication that is guaranteed to get the train to the next signal safely; in this example, the indications that would require the train to approach the next signal at reduced speed (Approach Medium + Medium Approach Medium) default to Medium Approach instead, because the rules for this signal system imply that the train could speed up if given a Medium Clear... by having the train be prepared to stop at the next signal, they are definitely going to be going less than medium speed.

Invalid Indication Overrides To:
Medium Approach Medium Medium Approach
Approach Medium Medium Approach
Advance Approach Medium Clear
Clear Medium Clear

Upper Quadrant Semaphore

Now, let's configure the semaphores. You'll also want to change the preview models: paste models/trakpak3_us/signals/semaphore_uq/ryg.mdl into each of the text boxes and press Enter to change the model to a semaphore.

  1. Select "uq_high" in the Signal Types list.
  2. Select "Stop" in the Rule Name list.
  3. The colors for the semaphores in this case will be identical to the color light colors, so just copy the values over. If you want, you can hop back and forth between the "cl_high" and "uq_high" and use the Copy/Paste functions to make the job quicker.
  4. Add the Animation Cycle value for each position:
Lens Color Blade Position Cycle Value
Red Horizontal 0
Yellow Diagonal 0.5
Green Vertical 1

Animation Cycle is a normalized (0 to 1) value representing how far along the animation sequence the model should be at. 0 is at the very start, 1 is at the very end, and intermediate values are partway through (0.5 is halfway through, etc). All animated signals use the same animation sequence (named "range") for consistency.

  1. Repeat the process for the rest of the rules as needed.

Imgur

And don't forget to save!

Logic Editor

Now that you've set up all the Rules, Signal Types, and Tags, it's time to make the Logic Function. The Logic Function is a series of Conditionals (If-Then-Else statements) that evaluate track conditions, other signals, tags, and other controls to calculate which Rule the signal should show.

Use the tabs to navigate to the Logic Editor window.

Imgur

SigEdit's Logic Editor uses a Tree/Node system to show the nested conditionals in an intuitive way. There are four types of nodes in the Logic Editor:

  • START. There is only one of these, and you cannot place or remove it.
  • IF (Conditional). These nodes will evaluate a set of conditions and continue on to a Then node (if the condition is true) or an Else node (if the condition is false).
  • THEN/ELSE. These are placed automatically and attached to a Conditional node.
  • Rule Return. These are attached to a Then or Else node. When the logic reaches one of these, the signal will display the associated Rule.

Conditionals are the backbone of the Logic Editor. Conditionals can check Signal Parameters and Tags, and allow for simple AND/OR logic to join them. The Signal Parameters available are:

  • Track Occupancy. The signal block governed by this signal (if one exists) is either OCCUPIED or CLEAR.
  • Route Diverging. The switches governed by this signal (if any exist) are either set up for a DIVERGING or MAIN path.
  • Route Speed. The switches governed by this signal (if any exist) have a defined maximum speed at which trains are allowed to pass through them. Each speed has a numeric value, and it is possible to compare them like any numbers.
  • Next Signal Rule. The next signal after this one (if one exists) may be showing one of the defined rules for this system.
  • Next Signal Speed. The next signal after this one (if one exists) will have a defined speed limit associated with it. Each speed has a numeric value, and it is possible to compare them like any numbers.
  • Next Signal Diverging. The next signal after this one (if one exists) are either set up for a DIVERGING or MAIN path.
  • CTC State. Dispatchers can issue commands to signals by setting their CTC state, which can be HOLD, ALLOW (Includes ONCE), or FORCE.

Additionally, the Logic Function is capable of processing Tags. Signals are given tags in Hammer by the mapper and give extra information to help choose a rule to display. In our example, we have just one tag:

  • abs will be used to designate a signal as an ABS (permissive) signal, which will display Stop and Proceed instead of Stop.

Let's start by setting the first conditional. Conditionals that are evaluated first have priority over ones that are done later. We're going to want the first conditional to be true in the most restrictive circumstances: If the Dispatcher wants to hold a train, if the track ahead is occupied, or if the route speed requires you to stop (this shouldn't normally be possible, but just in case).

  1. Select the first conditional node.
  2. Select "CTC State" in the Signal Parameters list. Select "Is" and "HOLD" in the dropdown boxes below it.
  3. Press the Add Parameter button.
  4. Press the Add OR button.
  5. Select "Track Occupancy" in the Signal Parameters list. Select "Is" and "OCCUPIED" in the dropdown boxes below it.
  6. Press the Add Parameter button.
  7. Press the Add OR button.
  8. Select "Route Speed" in the Signal Parameters list. Select "Equals" and "STOP/DANGER" in the dropdown boxes below it.
  9. Press the Add Parameter button.

The conditional node should read "IF ( CTC == HOLD ) or ( OCCUPIED ) or ( SPEED == STOP/DANGER )". If you made a mistake setting the conditional, press the Clear Condition button to reset the conditional and start over.

Now let's add another conditional to let the signal pick between the absolute Stop and the permissive Stop and Proceed. To do this, we will need to check for the presence of the "abs" tag.

  1. Select the first conditional's "THEN" node.
  2. Press the Add Conditional (IF-THEN-ELSE) button.
  3. Select the new conditional node.
  4. Select the "abs" tag in the Signal Tags list.
  5. Press the Add Tag True button.

The conditional node should read "IF ( TAGS.abs )". If the signal has the "abs" tag (which stands for Automatic Block Signal), we want it to show a Stop and Proceed aspect instead of a Stop aspect.

  1. Select the second conditional's "THEN" node.
  2. Select "Stop and Proceed" in the Rule Name box.
  3. Press the Add Rule Return button.
  4. Select the second conditional's "ELSE" node.
  5. Select "Stop" in the Rule Name box.
  6. Press the Add Rule Return button.

Imgur

That takes care of all possibilities for the most restrictive track conditions. Now, we add the logic for the less and less restrictive track conditions. Because this is a speed signaling system, the logic function should process the lower speeds first and go up from there. Now that you have the basics of node addition down, I'm going to show the steps at a higher level.

  1. Add a third conditional to the first conditional's "ELSE" node. Set the conditional to check if the Route Speed is Equal to MEDIUM.
  2. Add a fourth conditional to the third conditional's "THEN" node. Set the conditional to check if the Next Signal Speed is Less Than MEDIUM.
  3. Add an aspect return for "Medium Approach" to the fourth conditional's "THEN" node.
  4. Add a fifth conditional to the fourth conditional's "ELSE" node. Set the conditional to check if the Next Signal Speed is Equal to MEDIUM.
  5. Add an aspect return for "Medium Approach Medium" to the fifth conditional's "THEN" node.
  6. Add an aspect return for "Medium Clear" to the fifth conditional's "ELSE" node.

Imgur

Now for the full speed aspects.

  1. Add a sixth conditional to the second conditional's "ELSE" node. Set the conditional to check if the Next Signal Speed is Less Than MEDIUM.
  2. Add an aspect return for "Approach" to the sixth conditional's "THEN" node.
  3. Add a seventh conditional to the sixth conditional's "ELSE" node. Set the conditional to check if the Next Signal Speed is Equal to MEDIUM.
  4. Add an aspect return for "Approach Medium" to the seventh conditional's "THEN" node.
  5. Add an eighth conditional to the seventh conditional's "ELSE" node. Set the conditional to check if the Next Signal Rule is "Approach", AND the tag "adv" is true.
  6. Add an aspect return for "Advance Approach" to the eighth conditional's "THEN" node.
  7. Add an aspect return for "Clear" to the eighth conditional's "ELSE" node.

When all is said and done, every single THEN and ELSE node should have something attached to it.

Imgur

(Parts of the logic tree collapsed so it would all fit in the window.)

Once your logic function is complete, press the Write Logic Function button to compile this code, and of course, save.

Some last thoughts before we leave the Logic Editor:

  • This signal system does not have any Restricting aspects, nor any way to show Stop and Proceed except by using a number plate. As a result, there's no safe way to allow the CTC FORCE function to be used. Normally, the very first conditional should check if CTC State is "FORCE" and prescribe a Restricting aspect accordingly; the Hold/Stop aspects normally come after that.
  • There is no way to move nodes, except by deleting and manually re-making them.
  • Different signal systems may use different Signal Parameters. A route signaling system, for example, would use the "Route Diverging" and "Next Signal Diverging" parameters instead of "Route Speed" and "Next Signal Speed".
  • You should try to avoid using the "Next Signal Rule" parameter whenever possible. Because signal rules are referenced by name, this may result in incompatibilities with other systems.
  • You can collapse and expand nodes to keep the workspace cleaner while you're working on the Logic Function.

The Logic Editor is one of the most complex parts of making a signal system; keep practicing, and eventually you'll become a pro at it.

Signal Simulator

By this point, your custom signal system should be ready to use in a map! The last part to this tutorial will show you how to test everything without needing to set up a map to do it. Use the tabs at the top to navigate to the Signal Simulator window.

Imgur

The Signal Simulator allows you to combine every set of conditions at your disposal and see how the signal will respond. As in the Signal Interpretations window, there are configurable preview models for you to set. On the left, you have the "Local" signal, and all the track conditions that apply to it; on the right, you have the "Next" signal, whose only job is to provide Rule and Route Speed info for the Local signal to process.

Additionally, the text in the bottom-center will indicate if your Logic Function is valid or not.

Have fun trying out different signal combinations and playing with your new system!

Imgur

Usage in Maps

To allow this signal system to be used in a map:

  1. Create a new folder in addons/<your addon>/lua/trakpak3/signalsystems/ that shares your mapname. If your map name is gm_example then the folder should be called addons/<your addon>/lua/trakpak3/signalsystems/gm_example/.
  2. Copy the signal system's .txt file from data/trakpak3/signalsystems/ to the new folder you made in step 1.
  3. Change the file's extension to .lua.

For a tutorial on how to set up the signals in Hammer, see the Hammer Tutorials section.

⚠️ **GitHub.com Fallback** ⚠️