PrefaceThis guide aims to explain how to set up simple and reliable two-way rail systems, how to signal/schedule them to avoid deadlocks and some techniques to address throughput issues.
Hopefully this will cover the most common pitfalls but if I've missed something, or if something is unclear, please let me know and I'll try to include/fix that.
Step 0: But why?The main motivation for using two-way rails is that they're cheap and super easy to build, especially before bots and blueprints. Compared to one-way dual-track systems you'll save about 50% on the rails an probably at least 75% on signals, not much in the grand scheme of things but noticeable during the initial setup.
The main drawback is, of course, throughput. A pretty basic one-way dual track system will likely support at least 10x the throughput of a two-way system, a well designed one will support even more. That said, a two-way rail system will get you really far, by the time you may start to need to upgrade to a serious dual-lane system you'll probably have a small army of construction bots at your disposal to do the upgrade anyway.
Step 1: Forget rail signals existAs automatic trains can only pass signals if they're on their right, a two-way stretch of track needs either opposing signals or no signals. The example below shows two different two-way tracks.
If signals are only placed on one side the track becomes one-way. If signals are placed on both sides but not opposite to each other the track becomes a "no-way" track: it can't be used by automatic trains but still traversed manually.
Now that we have two-way track it's time to cover a simple signalling rule* that will remove almost all risk of deadlocks: The only signals you are allowed to place on two-way tracks are chain signals. Or in other words: Rail signals may only be placed on one-way track. The reason for these rules is to avoid deadlocks like this:
We also don't need rail signals at all to build basic systems, chain signals can cover all our needs, which is super amazing as we can skip one assembler. Chain signals even work fine for train stops:
This is actually all we need to make a really basic, but reliable, train system, so let's do that.
Example: The worst reliable system ever
That's basically it, just connect these station pieces to each other with track and you're done, no more signals needed. The only thing you have to be careful of is that you don't have more trains on a route than you have train stops: If you have a route between two train stops you can only have one train on that route. If you try to use two trains they would both be stuck at the stations waiting for the other to move.
The throughput will be absolutely abysmal, only one train can actually travel at a time as everything but the stations is the same block. The example shown can fit 3-car trains.
While this system is not really that useful we can use it as a base to build on.
Step 2: PartitioningThe simplest way to increase the throughput of our system is to use chain signals to partition it into different pieces. As we use chain signals we still avoid the earlier mentioned deadlocks but we can now allow trains that don't use the same pieces of track to run simultaneously.
The effectiveness of this varies heavily depending on how you've organized your train system, usually we're looking at at least 2x over all performance increase. Let's see how this could look in a system.
Example: A more reasonable train system
By applying partitioning to 3- and 4-way intersections and splits/merges we get a system that can look like so:
The same scheduling restrictions as for the last system still apply, more stations than trains, which is kind of a bummer.
While this system is probably enough to pretty comfortably launch a rocket it does not really allow flexible scheduling, care to guess what we'll look at next?
Step 3: More trains and flexibilityTo increase the number of trains we can have on each route we need to add additional spaces where trains can park while not at a train stop, aka stackers or waiting bays. While it is possible to implement two-way stackers it requires a more signals, can cause deadlocks if done incorrectly, and has basically no gain. What we'll do instead is to use "regular" one-way stackers, that way we can ensure that there is always a path from -and to- each station.
You're now going to have to remember that rail signals exist as we'll need them to construct our stackers. The idea is to place a single rail signal at the start of each waiting bay, everything else is still chain signal only. As the stackers will be one-way we can use rail signals without worrying, we have to make sure that there is a separate path to and from each station.
Example: Stations with stackers
The stations below each station has room for 3 trains, one at the station, one waiting to leave the station, and one waiting to enter the station. This means that for a path between two stations we can now run 5 trains instead of only one as we have 6 places trains can be instead of two. Also note that we also only use two rail signals per station, one for each extra waiting bay. The small arrows highlight the rail signals while the big arrows indicate direction of travel.
Step 4: More throughputWhile there are techniques that can increase the throughput of two-way rails we will not look at them in this guide, they are an excellent source of deadlocks if implemented incorrectly. The more reasonable approach to increasing throughput on our system is to make busy parts of it dual-lane one-way track. Note that only small pieces of the system needs to be made dual-lane to greatly increase throughput.
The main limit on throughput is that only one train can use a particular path at one time, if a train from a far-away outpost wants to travel to the main base it will block all traffic to/from the main base for the entire journey there. The way to get around these kinds of long waits is to add some splits where trains can wait and meet while en-route.
There may still be parts where there is too much traffic to handle, usually close to the main base, those parts will simply have to be made dual-track.
Further throughput improvements will be on the one-way dual-track system which is outside the scope of this guide, you'll have to look elsewhere for that.
Step "GOD DAMN IT!": Common pitfallsPart of tracks are accidentally made one-way due to missing/stray signals.
Part of tracks are accidentally made "no-way" due to misaligned signals.
If it's still not working you may want to take a look at this good guide for general train troubleshooting.
NotesThat is pretty much it, if anything is unclear/can be improved please leave a reply and I'll try to explain/improve this guide.
Some good resources on trains
Train automation tutorial. It may look a bit old but it is, in my opinion, one of the best tutorials on trains out there.
All things deadlock is a great resource for in-depth information on different kinds of deadlocks.
Tools used to make this post
Text plates for text and arrows.
Screenshot camera for taking screenshots.
Creative Mode for ease of build.
Thank you for reading and have a great day!
*There are exceptions to this but, if you know how to safely apply them I doubt this guide will cover anything you don't already know.