Getting rid of derailment view

If you give Railworks to a young person, there is some chance that the cool animations of the funny flying wagons catch the attention of the recipient a bit too much. This is how you spoil the fun.

In Assets\Kuju\RailSimulatorCore\Cameras delete DerailmentCamera001.bin (or move it to some backup). Make a copy of TrackSideCamera001.bin and name the copy DerailmentCamera001.bin.

Remove write protection and edit it (using RW Tools). Change the lines for Near/Far Camera Offset to this:

700.0000
750.0000

For each of the two lines, you make two changes:
a) increase the number from 70 to 700 or whatever you like.
b) delete d:alt_encoding="...."

Without part (b), part (a) is useless.

May well be that only the NearCameraOffset is relevant and the FarCameraOffset is irrelevant, or vice versa, I did not try it out.

In addition, I set StepAhead to 1000.0000, but I guess that this was irrelevant.

Restart the game (from Windows, clicking "play again" is not sufficient to reload the modified files) and run some train across a suitable track end. Be sure to attain some speed because RW kindly stops your train without error message if you are really slow.

You will still see the derailing train for the same duration, but the perspective is pretty boring. Increase the distance if you think the view is still too interesting.

Since you will turn off updates anyway for this installation (to save yourself from some of the phone calls), there is no risk of undesired restoration of the original camera settings.

Like all such "adult saves child from the bad by hacking his computer", this hack does not spoil the fun for a well informed young person. But it will distract the true novice from this fun for a while. And after a while, doing something useful with railways should have become more interesting than crashing trains, our you lost your case anyway.

Straight frogs - a step forward

The condition for a straight frog to render is that the curved part and the straight part of the diverging track are sections of the same track ribbon. Until today, I only knew two methods to establish this: Use the crossover tool or hack the XML files.

Now, I discovered another thing: The separate ribbons for each track section are only created if "snap to terrain" is on. Even if you lay level track on level ground, this separation takes place. But if you turn it off, all track pieces laid before you click the right mouse button form one ribbon, which results in a correctly rendered frog.


For converging track, you need a modification of the usual strategy to yield the benefit from the new insight. Instead of having the parallel (loop) tracks run beyond the diagonal which leads back to the mainline, you need to cut them off before they touch the diagonal. Then, you extend them by a short straight, then press Ctrl and snap a curve to the diagonal.

You need to practice a bit with your favourite track geometry to find out how far you need to take straight. Since the frame shown before placement is much wider than anything you see afterwards, it is a short trial-and-error exercise. But after a while, you memorized the look of the frame corner relative to the rail and sleepers of the diagonal track, and then you will be able to create converging straight frog switches with some 5-10% precision in the radius.

In Rail Simulator, you can use the same technology to get roads where the cars don't vanish. In Railworks, the problem was solved by RSC, so there is no benefit from undivided track ribbons.

Thoughts on route merging

Since it has resurfaced recently, these are my thougths on route merging in a nutshell: Basically, plan first instead of being sorry later, it is actually pretty easy, as you will see.

If you create a few route fragments just yourself, and there is a remote chance that they ever get merged, simply make one route blueprint, with one route origin, and use that for all your projects.

As long as you don't go 100 miles east or west from the origin, any projection issues do not really become an issue and even then I bet you won't notice too much, unless you compare your route to different precise sources. Therefore, I bet that the main station in your favourite town makes a fine route origin for all you projects. Or any point in that town, or anywhere else in the region. The important thing is only that you don't start a second route with any other origin, unless it is in another country.

This origin defines nothing more than the location of your tile 0/0. You need not even populate it, and you can move the scenario marker of the freeroam scenario where you want. So, really, just get along with your personal standard origin.

Merging two routes of yours will bring along quite some problems, but at least the tiles will fit together.

If you are serious about considering a merge, you will have used the same track rule in all candidates, or close derivations thereof.


If you are considering a team project, you need to discuss a lot anyway, our you will not reach your target for sure. One of the many things is the route origin, the track rule, and who becomes master of trackwork. In theory, it is possible to merge different tracks.bin files. But there is risk associated to it. Any you need to understand the details of the XML structure.

Even more important, I believe that trackwork developed by different people will look different and going over it later will show the difference. Also for the signalling, if there is no one with a master plan how to signal the route, and if this same person does not check each signal location for himself (read: do it himself in practice), then scenario authors and/or drivers will be ungrateful later. So, while it might be tempting to lay the track together with the scenery, I feel that this is one of the many occasions where as a serious route developer you must not let the cosy toy feeling of the World Editor carry you away.


Further reading: A thread at UKTS, over a year old but still current, containing one of Adam's best posts.

Handy Key Presses for Track Laying

By chance, I discovered two handy and undocumented functions of the World Editor for laying track:

In both cases, you start track laying as usual, expanding the track ribbon. Before you click the left mouse button to really place the ribbon, you press either Shift or Ctrl and release them after you clicked.

Shift switches "camera follows track" on even if you have not select this option in the bottom left flyout. But if this function is selected in the flyout, Shift does nothing, i.e., it does not temporarily turn it off.

Ctrl toggles the "snap to track" function. I.e., if you press Ctrl and this function is not selected, then for this one track placement, the curve will snap to straights (which will turn pink in the process) to form a converging junction. If the function is selected and you hold shift, you will be able to draw a straight (showing yellow), deactivating the "snap to track" for this one section of ribbon.

Messages sent to signals on coupling

I just found out that the track occupation management of the game must have improved at some point in the past, without leaving any trace in any documentation.

On game start-up, “initialise to blocked” is sent once per consist, which means that a signal protecting 3 groups of wagons gets 3 messages.

When you couple up wagons, all the signals which protected that group and the train coupling to it first get an "occupation decrement" message from the system, faking their exit from the block. Then, all the signals protecting the joint train get an "occupation increment" message, faking their entry into the block from the far side.

Track links currently under one of the involved vehicles get the message with parameter "DoNotForward", which means that this message is just for that link, in contrast to the normal messages which need to be forwarded on remote links (numbered 1 and bigger).

These things put together mean that occupation management by the default scripts is far better than it seems by looking at scripts and documentation. Not only is the system aware of multiple groups of wagons on the same track initially, it also does the right thing in the advent of coupling and uncoupling by magically increasing and decreasing the consist count correctly.

The fact that also driverless consists send the "prepare for train" message is a little let-down as I see it currently, because it results in even more unnecessarily cleared signals.

Track Properties and AI

Part of the problems with the AI are related to track properties. The following is a collection of the hard and soft facts I collected over time.

Theory
The dispatcher has to find one solution of a complex search problem. The search space is constrained by the track properties set by the route author, the instructions of the scenario author, and the trains already placed. There are different possible cases.

On the one hand, a problem can be over-constraint. This means that there is no solution to it which fulfils all constraints. E.g., all routes are blocked. This is more likely to happen the more constraints you set forth, as a route builder or as a scenario author.

On the other hand, a problem can also be under-constraint. This means that there are so many possibilities that the memory or processing time is not sufficient to explore them all. AI typically uses rules of thumb, called heuristics, to cut a heap of those considerations. This generally leads to solutions which are less then perfect, but they are generated in short time while the perfect solution would take very long to find.

Nothing is known about the heuristics of the RW dispatcher. But it has been observed that he does not work too hard to find out when a blocking train will move on. Instead, he simplifies the situation for himself by assuming that the train will stay there and finds complex ways to shunt around it. While this could be a good cop out in hard cases, it is not desired in many cases where the heuristics claiming that the block will stay simply fails.

An important questions in evaluating heuristics are metrics for solution quality. Nothing has been revealed and nothing can be set by the user, and few people are aware of the issue at all. What makes a solution good, or unacceptable? This requires complex knowledge certainly not able to model in RW currently. E.g., a passenger train will not reverse into a parallel track even if it wins him 5 minute, because shunting trains with passengers in them may be prohibited, or because waiting for the station staff to perform the manoeuvre causes of loss of 5 minutes.

This means that even though everyone would wish for a clever automatic genius, arriving there is a tough challenge.

An important factor RW AI is the train density. For moderate density, i.e., about 2 clear blocks between succeeding trains, many weird solutions do not get on the table at all. But people want to see dense operation, with waiting for opposite movements and then, finding a solution gets hard and harder.

Of course, there should be an ideal golden path in the middle between over and under-constraining. There are two things to consider in this quest.
  • Optimising the trade-off between desired guidance and undesired limitation cause by each information bit attached to any piece of track.
  • Perfect communication between those who make the rules of usage and those who need to follow them.

Practice
  • Marking a track as passenger locks out freight trains.
  • Likewise, marking track as freight locks out passenger trains.
  • Of course, uni-directional track locks out traffic for the other direction.

Note that freight and passenger exclusively refers to the train type selected for the driver icon in scenario editor, and nothing else.

Unfortunately, these are all the hard facts that I really can establish.

Track type yard remains a miracle. While I had the impression that it is avoided, it is clearly not a stop block for any train type. In one case, a freight train preferred 15 mph yard track over 50 mph mainline, while the same train from the same location took the mainline to reach the same destination when classified as passenger train.

Also line speed versus route length is a soft factor. I saw AI crawl along a speed restriction zone when the mainline just beside was clear and unrestricted. But I also saw AI prefer the faster track. I guess that the AI does not consider acceleration and deceleration losses. A short limit of 10 mph does not impress it, but a long one by just a few mph less makes it reconsider the route.

Sometimes I feel the the number of switches to pass is a factor. I saw AI take the loop when the clear mainline had a few more switches to other sidings in it.

A note on the hard blocks mentioned above: A a short piece of such track is sufficient for the result. This means that there is no need for miles of it. Therefore, keep direction restrictions out of places where someone might want to shunt, which is easy for route track. At the same time, make the marks long enough to be clearly seen when flying along the route. And do document them.

AI speed
This is calculated by the following interesting formula:

Line speed * (100 + tolerance) / 100 * performance

Line speed is the speed set in the track rules or by marking the track and setting the speed for this stretch. The choice of primary or secondary speed limit is decided by the train type defined in the scenario editor.

Tolerance is pegged to 60%. It is not the MaxSpeedTolerance defined in the XML of the track rule, as I believed earlier. That figure only influences the sharpness of easements, but not the speed of I, as later tests showed.

Performance is the % figure defaulting to 75% which you set for each intermediate destination.

If you want to experiment, start a scenario without being bound to a train, press F3 and then click on an AI train at an interesting place. It will shut off the power, so you need to take a quick look at the F3 display to see the value from the speed will steadily decrease. You also see the current speed limit, which can be well below the actual speed.

Given the uncertainty described above, using exactly one track class everywhere sounds most advisable, if only to rule out another factor of uncertainty with regards to AI behaviour.

Signals and their interaction with the game

I has been said before that signals are route decorations. In the following, I wrap up their relation to trains, F3 display and map, based on recent tests confirming old knowledge.

Signals' awareness of trains
On game start-up, a message is sent to the next signal ahead of consist, to tell it “prepare for coming train”. Also, for each consist, a message is sent to the next signal on either end saying “initialise to blocked”, meaning “protect this train”.

Note that both messages may end up at signals which are not stopping signals. It is the responsibility of the scripter to pass them on to where they can be acted upon. (For example, distants and AWS ramps cannot protect anything on their own.)

Signals' awareness of editing
When you enter scenario editor (not just world editor), all signals receive message 0 - RESET_SIGNAL_STATE. After that, they receive the same messages as after game start-up. On exiting the scenario editor, the same thing happens again.

In contrast, on game start-up, function Initialise is called very early and the above messages are then received.

This means, that signal scripts should call Initialise when they receive the RESET_SIGNAL_STATE message. This was the case for KRS, but for RW, the call was commented out and I have not got around why. Maybe because it only cures half of the problem as explained in the next paragraph.

The bad new is that in route editing mode in world editor, you can move around signals and their links (and also add and remove some) and in this case, the signals are not reset. Therefore, even with careful programming, the signals cannot adapt to the new situation after this type of modification.

F3 and map
Signals explicitly set the colour to show in the map, choosing from red, yellow, green and invisible without any requirement to correlate this with the aspect shown by the 3D shape.

The F3 display shows the same colour. For invisible signals, it shows the colour of the next signal and on also the distance to that one. Only signals classified as stop signals in the blueprint are considered here.

The distance shown in F3 refers to link 0 while the position shown in the map is that of the signal shape.

Player trains and signals
Signals may send messages to trains within 100m of their links. Note that there is no need to synchronise them with an aspect shown. For example, the TPWS ramp does not show any aspect but sends nasty messages.

I am pretty certain that when the player hits TAB, the request goes to the dispatcher who decides whether he would run an AI train into the next block, and this determines acception or denial of passing the signal at red. For sure, the signals (currently) are not even informed about the whole action, let alone asked.

AIs awareness of signals and trains
AI organises the route in blocks delimited by the link 0s or the stop signals. It only sees engines with driver icons. If one of them is inside a block, no AI train will go there, even if that engine would be located well behind the final target of the AI train.

AI trains do not receive messages sent by signals. They are not bothered by anything else the signals do, either.

As a consequence, on a correctly signalled route, signals will protect wagons and unmanned engines against player trains, but AI will plough through.

On a balance, you will not be able to lure AI into an occupied track by call-on signals and the like. You need to insert an invisible block signal beyond the marker where you want the AI to go.

Interestingly enough, this is only for the direction of the AI train. If you put a train just behind the signal for the AI, up to which it goes, this other train could proceed to the destination place of the AI train without violating any signal. But AI does not care about such issues.

One thing it worries about is when another train is straddling a link of a junction signal which the AI has to pass. Then, the AI train slows down and as soon as it passed link 0 of that junction, it speeds up again. Move the other train off the link, but still not separated by any signal from where it could collide with the AI train, and the AI does not hesitate anymore.

The AI ignores the signals, what should I do?
Despite all the frustrating signals I made above, I must say that a big number of signals would actually work in practice, if they were the right versions in the right place, had their links set up correctly and if the game was reloaded after modifications of route or scenario.

So, if you find a signal still shows a stop aspect while the AI train passes it, and if this signal is meant to be a bog standard signal, no permissive stop or call-on or approach from red, check the following.

From link 0, follow the route of the train to the next stop signal.
  • If the signal has several links, then are all the switches between link 0 and the far link through which the train passed set? (*)
  • So you find switches or crossings, those should have been protected.
  • So you find a consist without a driver, add one or remove the consist. AI limitation, not signal issue.
  • So you find a stop signal for the same direction before any of the above, check the XML file of the “bad“ signal to see whether this is classified as stopping signal.
  • Did you see the signal work on other occasions (i.e., did you witness all aspects being displayed under plausible circumstances, in another location). If yes, I forgot something on this list. If not, it is time to look into the script. If you are lucky, the name of some light is wrong and the signal died while trying to switch it on or off. Otherwise, err, you are not so lucky.

(*) It is pretty like that the route is set for AI trains, but at least for player trains, automatic trailing switches set against them do not end the game, but certainly they do cause the signal protecting them to show stop. So maybe there are situations in which you can change some switch before an AI train without the dispatcher setting it back immediately (or locking it in the first place). I only did one experiments and there, the dispatcher always set it back whenever I set it for my train.

Note: Modified sentence on Prepare For Train (message is also sent for driverless consists).

See also this follow up.

Sending several values in one message

Until recently, I maintained that modulo nor string functions would work, although Dave told me otherwise. I just did not get around testing it. Now I did and I found that both the string and the integer method work. These are the details:

The string method
You fix the number of digits (or otherwise characters) that every part will occupy. To piece the parameter together, you use the string concatenation operator “..” (two dots). To decompose the parameter by the receiver, you use the substring method.

string.sub(text, first character, last character)

Characters are counted from one. Note that the last argument is the index of the last character to include, not the first one not included nor the length of the substring.

I always add 0 to such terms to make sure that Lua stores them as numbers, not strings. I believe that I had bad results one time from comparing strings containing digits with numbers.

The integer method
After determining the maximum value of each component, you multiply the parts. For simplicity, lets use 99 as a maximum value for A, B, and C. So the parameter is

A * 10000 + B * 100 + C

On the receiving side, you use the modulo operation together with integer division to separate the parts. The way I found to be working in this Lua implementation is this.

A = math.floor( parameter / 10000)
B = math.mod(math.floor( parameter / 100), 100)
C = math.mod(parameter, 100)

In plain text, B is gained by first stripping off the two digits on the right using math.floor and division (because the division alone yields a real number) and then stripping off the two digits on the left by using math.mod.

Comparison
The main limitation of the numeric method is that numbers are represented as 31-bit bases which means that the maximum number you can represent without getting rounding phenomena is 2,000,000,000. If you need more digits, you are better off with the string method.

I believe that the numeric calculations are faster than string operations, but this is just a believe.

I did not test the string formatting function. Instead, I add a number to the result from the numeric method which is just a bit bigger. That way, I can be sure about the string format, with very simple calculation steps. In the above example, I would add 1,000,000, giving 1AABBCC where AA etc are the digits for A etc, so you can always get them by doing

A = string.sub(parameter, 2, 3) + 0

Impact
For the communication from the signals to the engine, this is good news, of course. Now, we need a standardisation body to keep the formats of different contributions compatible.

For the inter-signal communication, I am not so sure of the gain of composite messages over a series of simple messages (with ready-to-use parameters). All I observe regarding timing and delays is that either you run LogMate and accept the occasional hanging, or you don't run it and there is no hanging or jerking.

In Search of a Straight Frog

In a switch, the curve can end before or after the frog (or V formed by the inner rails). If it ends before, the rails from which the frog is formed are both straight, which reduces manufacture effort, eases track maintenance, and increases the durability. But dragging out the curved part through the frog and beyond allows for smoother curves. Consequently, straight frogs are a popular choice for yards and inexpensive trackwork while curved frogs are preferred for loops regularly passed by trains.

Until today, I believed that RW simply does not render frogs in straight switches. Either the curved ribbon extends past the frog or you don't get one (and no guiderails either). Then, I saw it render straight frogs in crossovers.

After getting rid of the blocks in flangeways, I had some crossover renaissance. But creating regularly shaped trackwork using them proved very tiring.

Then, I dug into the track XML data to see what was so special with these crossovers.

Now, I know two options, both of which are not exactly attractive, but much more than I had this morning.

The task at hand is the construction of a rake of loops, 4.5 apart, connected to the mainline via 1:9 switches with a radius of 190 m. The curve of this switch is 21.0 m long (rounded to 0.1 m). The length of a 1:9 diagonal from one track centre to the next is 40.8 m for 4.5 m track distance.

Innovative usage of the crossover tool
  • Lay some 500 m of straight track for the mainline.
  • Create a crossover to the right (since the loops will be at the right). Radius 190, length of curve 21.0. To make sure this radius is used, you need a track rule specifying it.
  • Unfortunately, the crossover tool only works on parallel (or very near parallel) track. Therefore, we only get one loop of it. The technique to produce it does not scale to a higher number of tracks.
  • Therefore, delete the curve at the far end of the crossover. Extend the straight track by some long straight, for working purposes only.
  • Move this new straight to the left, by some 20 m, without rotating it. It will help to inspire the crossover tool end then be deleted.
  • Now, add 40.8 m straights to the diverging straight (in place of that straight that we just moved to the side). Their number is equal to the number of loop tracks.
  • Now, select the crossover tool, place the gizmo exactly at the small red triangle separating two of these 40.8 m sections and create a crossover to the temporary track on the left. Curve radius is 190 again, and length 21.0.
  • After you did this for all the tracks, you delete the temporary track (which now is fragmented into 40.8 m pieces, and the curves connecting to them, leaving nothing but a range of nice switches with parallel tracks of equal length.

Fine, now we only need the opposite and then connect the two. Then, you find out that this simply does not work. The parallel tracks we created are never as exact enough. The will be off by a small number of centimetres, but this is enough to keep RW from joining the track. What is worse is that RW refuses to make such minimal S curves to compensate the small deviations.

You may be able to drag up a 1:100 curve (I hardly managed to created "flatter" ones), but the curve with "snap to track" (where the found target turns pink) does not work at this angle. RW always creates straights, which then do not join, exactly because the are a little apart. I also tried splitting and welding the straights of such an extra-sharp X. Sometimes it works, sometimes not.

Of course, there is not problem with using the join tool to simply make the straights ahead jump that centimetre or three, no one will notice. But what about the other end?

For converging switches, the recommendation I follow is to have a diagonal track across the whole rake and insert curves using "snap to track". If you pick a trackrule that has a somewhat smaller minimum radius, with some practice and patience, you will end up with a row of converging switches in the range of 185 to 195 radius, to approximate 190. However, these switches are of the "usual" type, not rendered as such and marked by a big red rectangle.

So you revert to the crossover method for both ends.

A clever variant is to make sure the parallel lines from the second end cross those from the first one, then you only need to find the place where they perfectly overlap and insert a piece of straight track there, after you cut them back. Less nasty than parallel track, 3 cm apart.

Still, all this is just too much pain in my view.

Poking into the XML
The track layout consists of ribbons which again consist of segments. The difference between a correctly rendered switch with straight frog and on that is not is this: The diverging branch of the switch is formed by a single ribbon, having two segments, first an arc (curved part), and then a straight. The crossover tools creates them that way. In contrast, when you create a curve, followed by a straight, the editor creates two separate ribbons with one segment each (at least when you are near other track or a switch).

Apart from fixing the core game, the solution is this:
  • You locate the two ribbons in Tracks.xml (easier in RW thanks to showing part of the ribbon ID in the editor), and in the corresponding file in Track Tiles.
  • You cut the cCurveStraight bit from the straight ribbon in the Track Tiles file, delete the now empty hull, and insert the cut out bit after the end of the cCurveArc segment in the curved ribbon.
  • In Tracks.xml, you remove the definition of the straight ribbon, noting its length before; then the node which connects the straight ribbon with the curved one.
  • Then, you look for the remaining mention of the straight ribbon and replace it by the key of the curved ribbon.
  • Then, you add the length of the straight to that of the curve (still in Tracks.xml). Also replace the old length by the new one in the rest of the record, namely for the height and track properties (track rule) information.

Sounds like work, because it is. But at least it has some potential for automatising, which gluing nearly joint track together has not.

Clearing Blocked Flangeways

We all love the crossover tool for creating those lovely frogs where the diverging track is continued through the flangeway of the straight track, looking truly stupid. By chance, I found out that this has to do with the opposing switch. Therefore, decoupling the two switches of the crossover solves the problem.

This is how I do it:

Case 1 - with intermediate straight. In this case there is a single straight between the two curved ribbons of the switches. Select the split tool and click somewhere in the middle of this straight. If only one of the two buffer stops appears, don't panic. Select the weld tool and click on the grey cube that will appear where you split the track. Reload the route to see the result, overcoming the usual track rendering issue. You should see two perfect switches and no buffer stops or track gaps at all.

Case 2 - without intermediate straight. In this case the two curved ribbons directly connect. Using the split tool again, cut off a bit from one of the two ribbons. Be careful not to cut into the guiderails and don't make the bit ridiculously short. 1m is fine. Like above, the result will look like a mess. Just pick the weld tool, click on the one cube showing where you cut, once. Then reload the route and enjoy.

Even tough I applied this method often with success, I urge everyone to keep backups of the Networks folder outside the Steam folders. Keep a series of version, so when you find a problem, you have several steps to go back and retrieve a version where the problem has not yet appeared.

Route Building Do-s and Don't-s

My personal selection of Do-s and Don't-s in route building, all documented elsewhere, just to pass on recent experiences.

Do not create scenarios before track-laying is closed.
Who can resist to run a train on his nearly finished route? And who can resist some fine tuning later, tearing out something here and adding something there? Only problem: If you used something in a scenario, you should not tear it out or RW will issue the maximum penalty, "something bad happened, you will so see your route again".

If this happens -- or better, before -- move all scenarios to a safe place or better don't create them.

Clearly, there are compromises, just create free-roam ones with a starting place that will not change in the life of the route.

Do not believe what you see after deleting track
In particular when you delete pieces of track that formed or might form a junction, RW sometimes, but not all times deletes one more than you selected. Do not place a new piece to close the gap. Exit and reload the route and the missing piece will be back.

Do not expect signals or AI to work after you modified either anything scenario-related, or any signal. Just reload, it is the lesser of two wastes of time.

Do not remove parts of double or single slips.
I remembered that as a valid technology, to create a slip and then remove the crossing pieces, to obtain a regularly shaped curve. Don't do it. RW gets angry about the missing pieces of the slip and you sit debugging Tracks.xml.

Do make backups.
The most critical file in my view is Tracks.bin. Since the above mentioned crisis, I do a simple Ctrl-C, Ctrl-V in the Networks folder of the route I edit, whenever I cycle to "play again" and back, which is what you need to do if you want to know if your route still loads.

Pressing the play button in the world editor does not to the checks that are done on loading. I.e., you can "test" your route, then edit some more, etc., and the next day you find out that a lot of work is lost.

If you click "play again" on the main menu, everything is initialised as if you would have started the game, if you can load your route now, you will be able to do so tomorrow.

Praise of the Scenery Viewer

Normally, when I call RW a scenery viewer, I am a naughty anorak lamenting about some feature missing or the prototype being poorly represented.

Today, I must say that this is the best living 3D postcard I ever saw. It should see a bright future in the treatment of aggressive or hyperactive persons.

Sorry if you hate these people who just upload lots of screenshots and then not even their own work, but today I am one of those. I will make up with a very technical article soon, but first you must see my postcard collection.












Who needs a cinema when mother nature plays a movie for him, in what they sell as a rail works? No noise, no dirt, just peace and fresh air.



No Sir, I did not smoke anything, I just inh...





Somehow, this farmer got stuck long ago. Or he got suddenly depressed from going up and down the fields all day. The tiller looks already rusty, but the point on the tractor is still good. Now he must wait for the spring to release his machinery from the ice.
Genetically modified sheep, certainly in danger of pig flu now.
Shut up and look at the winter woods.

The dark side of the --include statement, continued

Another nice feature of --include is that the blueprint editor is too stupid to understand dependencies. Normally, if A contains the line

--include=B

and you change B, then A is updated by any decent compiler. However, the blueprint editor only copies over B from the Source folder to the Asset folder and does not compile the file A again, although that contains a now outdated copy of B.

The only workaround is to save A anew even if you did not change it, every time you save B. Pretty boring if you have lots of 'A's, which is the normal situation.

In practice, I debug the file in the Asset folder until I am satisfied (or tired), and then copy it back to the source folder. However, this is risky (click the Export button in the blueprint editor once an your debugging work is lost). And if your project is made up of a set of files, splitting the merged file after debugging is another tedious working step.

The other disadvantage of editing the copy in the Asset folder is that syntax errors lead to program crashes (of KRS or RW). In contrast, if you make an error in the Source folder, the blueprint editor may tell you about it on exporting, if you are lucky.

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.