How to compose signals

Signals are often made up of components. There are three different ways to implement this in RW. Things to consider are
  • the number of combinations
  • the degree of perfection of the signal appearance
  • the ease of use for the route builder
  • the roles in the creation process.
For the number of combinations consider the following simple UK example: Junction signals can be 2-aspect, 3-aspect, and 4-aspect (3 variants). The fingers on them can come alone or in any pairs. There are also many triple-combinations, not to mention of the chance to maybe see a combination with more. 6 fingers give 6 single-finger versions and 15 different pairs which only needs some 9 combinations with 3 or more fingers and we have the impressive number of 30 finger combinations. The interesting bit is that this figure is multiplied with 3 to give the total number of signals to be shown, 90. In case we had two different post designs, that would double the 90 again.

For the degree of perfection, I mostly think of self-shadowing and support structures for the optional parts. If the signal is all black, you don't worry too much about the shadows, but many countries paint their signals in more or less light grey. For the fingers, there is some chance that two neighbouring ones are mounted together in one panel, which will make a noticeable difference from two separate fingers.

Some people argue that only the front perspective from a moving train would be important. But even if you say you are only driving, you might be driving a shunting engine which might halt near a signal, and certainly it will pass many signals in reverse direction at slow speed. So the shape details of signals are not generally useless.

Regarding the ease of use for the route builder, one has to weigh two different aspects.
  • Effort to position the signal combination
  • Length of the signal item list
Clearly, the two are antagonists, unless you use a signal composition assistant which is not implemented in RW. So, you either have a short list of components (in our case, 3 heads and 6 fingers), and you ask the user to arrange them manually at each site; or you have a very long list of prefabricated combinations (90 items minimum in our case, instead of 3+6=9 separate items).

Only in bigger teams, the following roles in the creation process need to distinguished.
  • 3D artist creating the shape, knowing enough about signalling to get the shape and the colours right
  • Scripter, knowing enough of signalling to get the control logic right
  • Configurer, not necessarily a programmer, but someone who knows how to set up a load of configuration files in finite time.
As shown below, some methods lend themselves more to shared roles than others.

Ways to implement signal combinations

1) Creation of all combinations in the 3D modelling programme. This has the large advantage that you can achieve perfect appearance by having correct self-shadowing of the combined shape. You can also easily adjust for deviations of certain combinations, like neighbouring fingers being paired.

The disadvantages are that the configuration work is done in the 3D programme, i.e., you need a script running inside this programme to create the combinations (before you apply the fine tuning); and you end up with a long list of items. It is also worth noting that only someone owning the source files of the assets can use this method.

2) Combining the signals in blueprints. You can do this by using the Asset Editor or by writing a little script which creates the combined blueprints. The advantage is that you get the combination work out of the 3D programme. The disadvantage is obviously the combination of no self-shadowing with the bloated signal list.

3) Combination in the world editor. By supplying all signal parts as separate signals in terms of asset categorisation and blueprints, you arrive with 3 + 6 "signals" in the list, of which 6 only make sense as part of another signal. (The fingers make only sense if mounted to heads.)

This vast advantage has to balance a list of disadvantages. There is no self-shadowing. The scripts are bit more complicated since the coordination between the head and the fingers is now performed via messages between them. And most importantly, the user has to perform several placement actions per signal.

This latter problem is eased by the fact that the complex combinations of signals are rare and the simple signals are frequently used. Also, frequent combinations could be implemented as under item 2 above, alongside the freely combinable part library.

Signalling assistants

Clearly, the user needs assistance in all three cases, not only to ease the work, but also to suggest combinations which are prototypical and warn of such which would not be used in the prototype.

In any case, one would define snap points for each signal and specify what could be snapped there. Then, the user only needs to select what to use, and no where to place it (except for deciding between two or three alternative locations, in case there are some).

For (1), such a tool would be implemented in the 3D programme. For (2), a separate tool, maybe with a GUI presenting a preview of the aspect, would create blueprints. For (3), it would modify the tracks.xml file which is difficult. At the same time, this latter case is the only one where the user can be consulted with respect to signal distance, too. In countries with speed signalling and strict rules for signal distance, this is an important aspect. Also, this is the only way to put an end to misplaced links and forgotten paths and switches.

Conclusion

If a signalling scheme knows many combinations, option 3 is the more feasible one, otherwise option 1 provides better look and nearly the same disadvantages as option 2.

Parsing and modifying tracks.xml might seem a bit far out from today, but it is a precondition for more comprehensive route builder support.

Signals and speed limits

The Wiki says "Signal scripts can receive speed limit information and make use of it, but they cannot define a speed limit themselves." The more detailed story is this.

Signals cannot alter the track property speed limit (actually a pair of speed limits, for passenger and freight traffic). This speed limit is what you see in the F3 display.

Currently, signals can query the track property speed limit only when the train is no more than 100m from them. Then, it is too late to change the signal aspect, but time is right to query the train speed (they can do that), and compare these two speeds.

Alternatively, a signal can always compare the train speed against some value defined in the script logic (like 40 km/h for German Hp2).

While the signal cannot modify the F3 display, it can send the train a signal (while it is within 100m). This typically is an "overspeed message" which leads to applying the emergency brakes. It will also be communicated as such in the logfile, to contrast it from overrun signals etc.

Showing dynamic speed limits is not a problem by itself. I.e., you can show 70 km/h for one route and 40 km/h for another and nothing for the straight track. But the information what to show needs to be encoded in the signal script which potentially leads to loads of signal variants.

ERTMS, ECTS, PZB, LZB, etc

The current state in RW is this.
  • You can have pointwise transmission of information from track infrastructure ("signals" in RW) to trains.
  • You cannot have continuous transmission of information from track infrastructure to trains.
  • What you do with the information in the train depends on the engine script.
  • There is only one custom message with one parameter for all forms of information transformation from track to train.
  • There is no way to transfer information from train to signals (or other track infrastructure).

The resulting situation is this.

Pointwise transmission: The default signals implement a simplified version PZB which just implements the momentary speed check, not the continuous one. They also implemented one TPWS which acts as train stop and speed sensor alternately. Dave (davveb at UKTS) is working on some engine scripts to get us further here.

Continuous transmission: No possible, because signal only talk to trains when they are no more than 100m from the track link. This means that if you were determined to have it now, you would need to place transmitter objects every 200m on the route. RSC are positively aware of the issue, and have a very long list of things to do.

Of course, there is nothing like wireless communication at all in RW, such as ERTMS 2 or US dispatching via radio, or UK electronic token systems. This looks to me like a bit more advanced than the continuous trackbound transmission in terms of software redesign (just my guess).

On a sidenote, RSC announced that wagons can have Lua scripts, too, now, but documentation on the API is not yet available.

Whether we end up with an international standard matching ERTMS or whatever these organisations call themselves today depends on whether someone will implement it. An interesting factor here is also standardisation within the community. If RSC insist on squeezing all the information through this one custom message, we will need some community standard like this unified track pieces database for MSTS.

At the same time, our dreams are limited by the fact that merging of routes is not supported in RW, which means that for long, international routes, building them will be a project of its own (maybe reusing scenery items), and this route will have its own signalling, where you can rule out conflicts between implementations by adapting the scripts.

Hiding signals in the map

Tired of the mess of bulbs in the map? As long as you can decide which signal class is the more important, here is cheap help.

If you give an argument outside the range of 0 to 2 to the system call Set2DMapSignalState, the signal is not shown, simply. 0, 1, 2 are green, yellow, red respectively. I have not found a way to show anything else for a signal. But at least, I know how to hide these bubbles.

Now if you have 3 stop arms of a semaphore (mounted on separate dolls), you could hide those showing red. Then you have yellow for any arm open with distant arm closed, green for any clear with distant arm also announcing clear, or nothing if all arms show stop. This, of course, is a bit sad, but there are some track diagrams that do work like that. There are others that don't, but better no red than a mess.

Even better if you have a main signal and an auxiliary signal like a call-on arm. Then you can work out their roles redictively, like main signal only shows clear, call-on arm show -- well, yellow? -- when open or red.

How to signal a route

After bugging various people on various occasions with various subsets of the stuff below, I brought it all in one place, hopefully.

Basically, you need an idea of (1) how it is done in the prototype, (2) how RW treats signalling, and (3) where the major pitfalls are.

High level

Blocks should be of similar size. Calculate the maximum occupation time and communicate it to scenario authors. This is calculated as the distance from the signal at the start to the furthest remote link (the ones with the number on the arrow) of the signal at the end plus the maximum train length, all that divided by the usual travel speed in this block. Minimal intervals for scheduled trains should be a few minutes more than this figure, at least.

At portals, extend the branch by a few miles of plain track and place proper block signals (about two per direction). This will greatly help scenario authors debug their scenarios in case of congestions.

Make the speed limit which is set as a track property (and in the track rule) somewhat consistent with the signal distance. See here (and Mark's pointer to his handy measuring tool a few posts down) for more on the topic.

Don't worry too much about the finer details, just try a full brake application (not emergency brake) at maximum speed in a few places with a selection of trains and note the braking distance. Then add some 30% or 50% and people will love you. The important thing is fundamental awareness of the issue to avoid player frustration.

Be sure to have some space between the signal and the next switch. Rules vary widely (two quick figures: 6m - 200m), but basically, the signal is meant to keep trains from running into switches which are not set for them and/or collide with trains there, and this means that the train must safely halt before such points, and safety margin is a good thing to have. At the same time, many station layouts simply don't allow for big margins, compromise like they do in the prototype. And remember that the length of the safety margin should fit the speed of the train, in principle.

Medium level

The track network must be spanned by complete networks of signals for each possible direction of travel. This means that every remote link (with a number on the arrow) must point to a link 0 of another signal without a switch in between. For single link signals, the unnumbered link 0 must point to the next link 0, again without a switch in between.

There should be no occasion to drop off wagons within the links of a junction signal, i.e., don't place your remote links deliberately far.

With the default signals, you must keep the shunting in "yard areas". These are reached via "yard links" and left via dedicated "yard exit" signals. Yard links are the last links of signals having 1E or 2E in the name (and you guessed it: 1E signals have 1 such link and 2E signals have 2).

Be sure to have each and every track in every station marked, be it platform, siding, destination. Also those that you find irrelevant, other may not. Granted, there are scenario-based markers, but how are you going to communicate about the trackwork without a reference name.

I also suggest placing a destination marker on each route track near the station, it may help the scenario author to make his orders very clear if the dispatcher needs it.

Low level

Be sure to have the remote links beyond the curved part of any switch. Look at the ribbon frame, not the blades. The logical "node" of the switch in the abstract track network is where the curved ribbon meets the straight track pieces.

Be sure to have the remote links before any further signal. They need to send information in the direction of the arc, so if link 0 of the next signal is behind them, you cannot expext things to work.

Any AWS & TPWS goes before link 0, i.e., on the side of the arriving train. The arrow of these objects must point to link 0 of the signal to which they refer.

Be sure to pick the right signal. Refer to Mark Brinton's guides and/or the Wiki for details, they do not fit in any blog post. As a general rule, link 0 goes next the signal post, link 1 goes beyond the switches in the "most important" track, link 2 and following go to lesser tracks. If you have 4 tracks beyond a junction, you need a signal with 4T in the name.

When you place a signal shape, you need to rotate it by dragging the mouse to the side until the orientation roughly fits. If you get this wrong, just delete the signal. You can rotate it and then click on the links hoping for them to switch directions, but it is safer to redo this one signal.

References

Mark Brinton's guide, part 1 and part 2

The RW Wiki (unfortunately still lacking the illustrations as of this writing):
Signal Asset Glossary
Setting Up and Using Signals

The dark side of the --include statement

We all know that the only way to include shared files in RW Lua scripts is the --include statement. However, this has the nasty behaviour of not including the quoted file where the --include statement is found, but appending it to the end of the current file. This can be very nasty if you use it like this.

Colors.lua:
WHITE = 1
RED = 2

Main.lua:
--include=Colours.lua
myColour = RED

This is translated to:
--include=Colours.lua
myColour = RED
WHITE = 1
RED = 2

The lovely Lua implementation in RW says nothing about RED being undefined in the second line. It assigns nil to myColour and two lines later, it assigns 2 to RED.

The workaround found by Kuju is this: All signals must define a function Initialise. Now, this function is called after the whole Lua file is read, which means that all the values which you assigned anywhere outside any function are already assigned.

At the same time, you must beware of doing something with the world in Initialise, all you are allowed to do is setting internal values. Sending and receiving messages happens much later. If you want to see how much later, put a Print statement into the Initialise function and the block in Update which is only executed once (after "if gInitialise then").

Back to our problem, the solution now would look like this:
--include=Colours.lua
function Initialise()
myColour = RED
end

Now, this assignment will only be executed when RED has the value 2.


There is another problem with the --include statement: If one of the included files is missing in the first attempt, and you just add them (or rename them to fit, etc.), the blueprint editor adds the "late" files to the end of the resulting script, irrespective of the order of the --include statements.

You can prevent this from happening by deleting the scripts folder under Assets, then all these files are redone in the correct order. Alternatively, you can strictly separate initial definitions on the top-level from using them in Initialise to set further values. It is a bit tiresome, but then you need not worry about the behaviour of the blueprint editor.

Keep the last track piece clear

KRS had the following problem: If you put an engine on the last piece of a terminal track, you hit a bug in the code which does nothing but issuing a complaint in LogMate that it "cannot back propagate". However, this consumed time and if you happened to trigger this for a lot of track pieces, you ran into serious trouble.

Will not happen, you say, but you forgot about turntables. They have a large number of short tracks leading from them, typically just single straight pieces, and many of them hold an engine. Turntables had a reputation for creating weird problems. Adding a (really) short piece of track at each track end cured the problem, as far as I remember the feedback from people.

Now in RW, this error seems to have mutated to a fatal scenario loading error, where the game talks about "Invalid Constist Error". I looks like RSC wanted to rule out the above bug by forbidding the placement of trains on the critical track piece. But this last piece can be really long, if the route builder does not know about the issue.

The workaround for the time being is that all route builders split and reweld the last piece of track near the buffers, or add a foot of track there. That way, no one can place anything in the critical place and it does not matter if the bug currently leads to slow game performance, crashes, or refusal to load a scenario.

Child elements

Not everyone knows that any object in RW can have an unlimited number of child objects. These are simply other objects (more specifically, blueprints from a restricted subset of all the available ones).

Uses include:
  • Signal panels attached to a post (which acts as the main element, but it could be the other way around just as well).
  • Plates and other supplements attached to rolling stock (or station buildings).
  • Freight items (called FreightAnim in MSTS)
  • Lamps (tail lamps, head lamps)
  • Sounds
  • People (staff, passengers)
  • Editor-only objects to show information or a bounding box to the routebuilder without disturbing the appearance in the game. Thanks Rail Similarity.
There are four ways to attach a child to a parent.
  1. The official way. You have the source of both parent and child. You start the Asset Editor to show the parent and interactively position the child with the mouse.
  2. The hacker version of (1). You add the reference to the child by editing the XML file which is the blueprint. This saves you the hassle of using the Asset Editor and often you will know the exact location from your documentation on the model (or by clicking on some vertex in the model in your 3D modelling programme). As long as you do not want rotation, this method can save time and nerves. See here for details.
  3. The unofficial way. You do not own the sources of parent and child and still want to combine them, which is perfectly reasonable in a wide range of cases from the above list. You convert the BIN file of the parent to XML and add the reference there. Don't forget to convert the XML file back to BIN. See here for details.
  4. You use RW Tools to do (3) in a user-friendly way.

Simulation for me

There are many heated debates on what is simulation. All good definitions contain the fact that you always depict only a part of the whole, and that it is a model and not the real thing. While these two things are limitations, they give you the big benefit that you can have a simulation of something that you cannot have for real.

This is what I love in simulation: I can afford it.

A cannot afford a real steam engine. I cannot even afford a scale railway layout depicting a 100 km route (which would be just a model itself). But I can afford a simulation of lots of complete trains and long routes.

The other good news is that they sell you mightier and mightier computers for the same money every year. So you can simulate more and more, or have more and more details in your simulation of the same thing, simply by letting the time flow by.

To me, it is something like a historic challenge of our time, to take this powerful tools (the computers and modern software development technology) and apply them to a very noble purpose:- making the ever increasing amount of knowledge/information/data accessible to a wide and diverse audience.

Besides networked freely accessible media, simulation plays a key role for me. Knowledge progresses in big leaps while our brains are nearly the same as 200 years ago. So what we need is a mapping of abstract rules governing complex systems to something we can look at, turn in your (virtual) hands, try out, decompose and rearrange, and explore in all kinds of fashion, and each one to his own accord, at his own speed, and at a time of his choice.

I am well aware that most people just want to be entertained. But entertaining yourself by driving an engine or creating a route, or just looking out of the window of a virtual train while riding through an unknown country is a much more active and thus much more preferable way of passing your time than just watching a movie or reading a book. And you will ask questions about what you see, and to answer them, you will certainly resort to books and movies, just to pick the bits out of the vast information heap that suit your own demand at that moment.

So, there is -- of course -- a need for structured background information, but as entry points -- and to help you process the complex aspects -- you need simulation.

For me, the visual presentation is an important motivation to deal with an issue. While I am interested in complex things, I love to look at nice pictures, too. Often, I find it very gratifying to look at a visual representation of a complex problem I solved. Thus, the combination of both, detailed simulation of complex subjects and detailed, attractive visuals, is what I strive for.

Books can give you very detailed information, but only a very poor fraction of the images you want to see. Movies give you a stream of images you cannot control, and very little information in general. Detailed graphical simulation gives you lots of pictures to view under your own control, and if the nature of what you see is modelled in a detailed way, you get a fair chance to explore the background knowledge behind it.

My focus

My interest is simply "how complex things work". Not just any complex things, but things that either seem important to me for some reason, or exhibit some aesthetic attraction on myself.

In practical terms, and as far as railway simulation is concerned, this means the following.

Steam engines show how they work to a larger extend than other traction systems. Also, this traction poses much bigger challenges to the engine designer than other tractions. At least that is my view, and for sure, there is more to see in steam engines.

Route design in the prototype means finding a compromise between desired connections, existing geography, financial constraints on the investment, and economic background of the region defining the amount and type of traffic on the route.

The time starting at the dawn of industrial age greatly influences our lives and what you learn in school is but a few crumbs of the cake. Railways were at the heart of the development for most of that time, and where they were not, the developments influenced the railways, e.g., by shaping traffic patterns.

Railways were among the first technical systems which raised attention for the fields of safety, resource management, and public infrastructure policies. They were not the only ones, but dealing with railway history means dealing with the development in these still hot areas.

Dealing with railways in different countries draws your attention to differences in the economic, geographic, social, political background.

Now, if you deal with railway history, you automatically get all these interesting things served on a silver plate for you. How boring was the geography lesson when we had to learn the names of the rock material of an endless list of mountains in an endless list of countries no one wanted to know about anyway. But if you are attracted by a certain railway line, you start asking why they built this bridge that way and that tunnel at that location, and you plunge into complex background that you would never want to know otherwise. I myself am not a bookworm just for the fun of reading books. I want to process the stuff I read, I need to digest it or it explodes my head. I would feel very bad about just stuffing it all into my memory and letting it rot there.

This is where simulation comes at my rescue, which is the topic of the next article.

On a pragmatic level, I think that today's computers are well suited for simulating and rendering machinery and buildings. In the future, they might also be up to modelling natural things like plants, but for the moment, you need to compromise in this field. I am also interested in simulating plants and animals, as well as human behaviour throughout the ages, but this will have to wait for a decade or two.

Why I started this blog

My general situation is this: I have a load of ideas, and not so much time to implement them all.

I feel very much at home at UKTS and I abused this forum as my preferred idea dump for years. Since I often love to trigger some discussion, use, development etc related to these ideas, a forum is great for it. In contrast, I am not at ease with the comment feature of blogs. I suggest that if you want to drop me a simple note, do it in a comment in the blog; if you want to discuss an idea, start a thread at UKTS referring here, I will certainly notice (or drop me a note so I notice quickly).

The one deficit of a public forum is that because of its very nature, your thoughts must get buried in the sum of contributions. The other point is that some of my blurbs are just that, and all that follows is a few people saying something polite about it and that was the history of that single-statement thread which subsequently fades into oblivion.

Finally, I have a lot of information bits lying around in drafts of massive documents that never become complete. And when such documents are complete, all they do is impress a few people, but the chance that someone reads 30 or 60 pages are small. I have a vague hope that 1) I might publish useful fragments over the coming month or so, and 2) people might actually digest them, and 3) search functions might bring it to the attention of a somewhat wider audience. But I must say that my topics generally are not exactly funny for a wider audience -- more on that in another article.

Therefore, this blog will be a complement to my continued activities at UKTS, providing a cross reference of old ideas of myself and others; and it will contain a series of new articles on technical stuff floating around my brains and my harddisk.