Page 1 of 2

Advanced circuit network conditions for train behavior in 1.1

Posted: Mon Oct 26, 2020 1:16 pm
by KoblerMan
Hi everyone,

I really like having a good excuse to break out the combinators for Factorio to optimize the heck out of my setups, particularly with trains. :D

A lot of us who have done this before know that you can disable your train stations until they have a full load of cargo, at which point they will enable and essentially call all of the available trains with that stop on the network. Furthermore you can set conditions that the station will disable when it is occupied so that all of the other trains have the ability to path to new stations.

Right now this is relatively simple to do; you just have one combinator each for checking one row of chests that loads into one wagon, tick over when it contains a full wagon's worth of cargo, and then send that signal along. At the end of this signal you have another combinator which will compare this number and if it's equal to N, where N is the number of wagons on each train, it enables the station.

However, this is a very simplistic design. It doesn't account for the fact that you only need one full train load for the station to enable, which might call multiple trains over. But then again, it doesn't need to be any more complex than this - because in 1.0 and earlier, trains are agnostic to how many of them can queue up at one station anyway.

According to the latest FFF, the new train stop limit mechanic which can be modified by the circuit network has some HUGE implications for optimization. To put it this way: theoretically, you could have a train stop that instead of enabling/disabling, will keep the limit at 0 until it has one full load of cargo, then when it has a full load, increase to 1, then 2, etc. The end result is having a train stop that only calls the number of trains needed to empty out the station's stockpile. This would be a very elegant solution in comparison to the aforementioned, sloppier station behavior.

In the interest of getting a blueprint designed for this new type of station, I got to work on building out this new logic in anticipation for 1.1. Specifically, the intended behavior is to have one combinator for each row of chests, then have each of those count how many wagon loads are available instead of the binary "there is one or more wagon load here". This in itself is trivial, since each wagon can hold 4.0k ore, you can simply take the input of all the chests and divide it by 4.0k, and the output will be 1 for one wagon load, 2 for two, etc.

However, I ran into a problem. How do I take N signals (where N is the number of wagons per train), and operate on them to determine what the lowest number of each one is, and set the train stop limit equal to that? This prevents a scenario where an uneven number of wagon loads in each row of chests causes more trains to arrive than resources are available. In my case, I use a 2-4-0 train convention, so each station has 4 wagon slots. I set each slot to A, B, C, and D respectively. I want to compare each of these signals against each other and pick the lowest number. I spent a good hour doing trial and error and could not for the life of me figure this out.

I googled the problem and the only thing I found was a post on arduino.cc detailing how to do the same thing with an arduino:

Code: Select all

lowVal = myArray[0];  // just to start it off
for (byte n = 0; n < 4; n++) {
   if (myArray[n] < lowVal) {
        lowVal = myArray[n];
   }
}
I might be able to figure out how to abstract this to circuit network logic if I really tried. But, ultimately I'm not a developer, and I've never coded anything on an arduino. Ultimately the goal is to find a solution that uses as few combinators as possible to achieve this.

Does anyone have any ideas on this? Thanks! :)

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Mon Oct 26, 2020 1:30 pm
by Gamatron332
Hi also haven’t done much coding but I think what your looking for is a if/else setup. I’m gonna switch your wagons to numbers because I want the letters for somethings else. Ok here we go.

My idea is to used 3 if/else statements to compare and find the lowest chest set. Well call your chest sets 1-4.
The first if/else compares sets 1 and 2 , the second one compares 3 and 4 , and the final one compares the output of the two. Here’s my thought for the if/else combinators.

First, you have a combinators saying if 1<2 output A then you have another combinator saying if 1>2 output A. A should be whatever is the lowest. Then you’ll do the same for 3 and 4 except outputting B. Now the signals should be on one wire. Finally simply do the same comparison for A and B and output a signal that should be the minimum wagons necessary.

This may not work because the if/else combinator might not output the correct number onto the A and B signals but this can be fixed by converting it with a combinator that’s says input + 0 = AB :)

Hope that helps

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Mon Oct 26, 2020 1:37 pm
by Gamatron332
KoblerMan wrote:
Mon Oct 26, 2020 1:16 pm
Forgot to quote you to get the attention

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Mon Oct 26, 2020 2:17 pm
by KoblerMan
Gamatron332 wrote:
Mon Oct 26, 2020 1:30 pm
Hi also haven’t done much coding but I think what your looking for is a if/else setup. I’m gonna switch your wagons to numbers because I want the letters for somethings else. Ok here we go.

My idea is to used 3 if/else statements to compare and find the lowest chest set. Well call your chest sets 1-4.
The first if/else compares sets 1 and 2 , the second one compares 3 and 4 , and the final one compares the output of the two. Here’s my thought for the if/else combinators.

First, you have a combinators saying if 1<2 output A then you have another combinator saying if 1>2 output A. A should be whatever is the lowest. Then you’ll do the same for 3 and 4 except outputting B. Now the signals should be on one wire. Finally simply do the same comparison for A and B and output a signal that should be the minimum wagons necessary.

This may not work because the if/else combinator might not output the correct number onto the A and B signals but this can be fixed by converting it with a combinator that’s says input + 0 = AB :)

Hope that helps
I will give this a shot on my lunch break and report my results. Thanks for the input. I had considered something similar to this design, but scrapped the idea because I wanted a magic one-combinator solution, or using the "each" parameter to make it scaleable without adding complexity. But, I think the main limitation here is that each combinator can only operate on 2 signals at most each. :)

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Mon Oct 26, 2020 2:43 pm
by Gamatron332
KoblerMan wrote:
Mon Oct 26, 2020 2:17 pm


I will give this a shot on my lunch break and report my results. Thanks for the input. I had considered something similar to this design, but scrapped the idea because I wanted a magic one-combinator solution, or using the "each" parameter to make it scaleable without adding complexity. But, I think the main limitation here is that each combinator can only operate on 2 signals at most each. :)
Yeah my ideas got quotes complex before I just said”screw it he need a if/else function I’ll give him a if else function.” Of course my experience with combinators is limited so there is probably another far easier way to do it but this accomplished what was asked.

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Mon Oct 26, 2020 2:43 pm
by DaveMcW
Here is a scalable solution.

It works by calculating an average, then dropping every signal above average. If it runs out of signals, it sets the average to a large number and restarts.



min signals.png
min signals.png (204.13 KiB) Viewed 8617 times

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Mon Oct 26, 2020 3:00 pm
by Gamatron332
Gamatron332 wrote:
Mon Oct 26, 2020 2:43 pm
Yeah my ideas got quotes complex before I just said”screw it he need a if/else function I’ll give him a if else function.” Of course my experience with combinators is limited so there is probably another far easier way to do it but this accomplished what was asked.
See above post... man I need some time with combinators..

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Mon Oct 26, 2020 3:16 pm
by KoblerMan
DaveMcW wrote:
Mon Oct 26, 2020 2:43 pm
Here is a scalable solution.

It works by calculating an average, then dropping every signal above average. If it runs out of signals, it sets the average to a large number and restarts.




min signals.png
Thanks for the input! I'll try both methods now.

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Mon Oct 26, 2020 4:14 pm
by KoblerMan
Alright @DaveMcW, I've implemented your circuit into my 2-4-0 train station. It works amazingly, thank you!

I made a couple of modifications:
  • Compacted the design so that it will fit in a narrower space
  • Changed the information signal to the dot signal on all interfaces
  • Increased the integer value to the maximum, because why tf not?
Comparator blueprint:



Ore station blueprint:



Fluid station blueprint:



That will do it, thanks guys!

EDIT: Updated the ore station blueprint.

EDIT 2: Added the fluid station blueprint.

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Mon Oct 26, 2020 6:57 pm
by KoblerMan
Actually there is one edge case I didn't consider. What happens if one of the wagon loading zones doesn't have enough resources for one whole wagon? It simply does not send a signal at all. 0 isn't accounted for in the system. I can fix this by using another decider combinator for each row of chests, but is there a scaleable way to handle this?

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Mon Oct 26, 2020 7:42 pm
by DaveMcW
Handling zero ls always an issue when using EACH signals. The solution is to have a constant combinator generate a 1 for every signal, so it is never zero.

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Mon Oct 26, 2020 7:50 pm
by KoblerMan
DaveMcW wrote:
Mon Oct 26, 2020 7:42 pm
Handling zero ls always an issue when using EACH signals. The solution is to have a constant combinator generate a 1 for every signal, so it is never zero.
...And then I can have another combinator at the very end that subtracts 1 of the final output to balance this out.

I will experiment with this.

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Mon Oct 26, 2020 8:48 pm
by KoblerMan
I edited my post containing the blueprints so that it's updated with the new convention.

When 1.1 drops I will do this again, so that the logic modifies the train limit instead of enabling/disabling the station. I'll also make one for fluid loading.

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Wed Dec 09, 2020 5:21 pm
by Hildron
I tested your setup for setting the train limit. Unfortunately it doesn't work because while the loop for calculating the average is running, it is outputting higher numbers for some ticks. With how train limit and slot reservation works, this is enough that trains will route to the station even after the correct train limit is set (once a train has reserved a station slot, it will do so even after the train limit is changed).

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Thu Dec 10, 2020 2:50 am
by astroshak
I use one Arithmetic Combinator to determine the average load in the entire train’s loading chests (if its an 8 Cargo Wagon long train, with 6 chests only on one side, that’s 48 chests). I set the inserters loading the chests to only operate when the amount in their chest is <= the average.

I then have another Arithmetic Combinator that also takes the total ore/coal/w/e in the chests, and divides by the total carrying capacity of the train. 2k ore/wagon, 8 wagons = 16k total ore. The output of that combinator (signal T for me) is sent to the Train Stop. Two conditions on the train stop. The first is Enable when T >= 1. The second is the stop limit is equal to T. So if there are only two loads worth of ore, the limit is 2. If the chests are full, the limit should be 7.

Y’all might want to try something like that. I don’t particularly care for using the average in the chests to determine when to load more into them. However, without that, it became very complicated to try to determine how many loads were ready based on the amount in each 6 chest set (IE - per cargo wagon). The drawback to this is the need to use inserters to load the chests the train is loaded from; you cannot use bots directly or you throw the entire averaging off. The whole idea is that the lowest set of 6 chests determines the number of loads. The averaging (MadZuri on the entire inserter set) circumvents the need for that by ensuring they are all roughly equal, at the cost of speed.

Now that I think about it ... it might just be simpler to wire the six chests per cargo wagon together, and output their contents to an arithmetic combinator. Divide the total by the amount that one cargo wagon can hold, and output that to its own distinct signal. Do what was suggested above, and compare them by pairs, outputting the lowest signal. The last signal released could then be used as I use the T signal, when >= 1 enable the station, and set the limit to that number. This would basically be a variation on the OP’s initial situation (pre 1.1) with a bit of computing done near the locomotives.

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Thu Dec 10, 2020 8:13 am
by Hildron
astroshak wrote:
Thu Dec 10, 2020 2:50 am
Now that I think about it ... it might just be simpler to wire the six chests per cargo wagon together, and output their contents to an arithmetic combinator. Divide the total by the amount that one cargo wagon can hold, and output that to its own distinct signal. Do what was suggested above, and compare them by pairs, outputting the lowest signal. The last signal released could then be used as I use the T signal, when >= 1 enable the station, and set the limit to that number. This would basically be a variation on the OP’s initial situation (pre 1.1) with a bit of computing done near the locomotives.
That's exactly how I finally solved it.

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Thu Dec 10, 2020 10:10 am
by foamy
DaveMcW wrote:
Mon Oct 26, 2020 2:43 pm
Here is a scalable solution.

It works by calculating an average, then dropping every signal above average. If it runs out of signals, it sets the average to a large number and restarts.




min signals.png
Is there a clean way to do that for maximums? The minimum one works because Factorio truncates. I've tried bruteforcing it with a channel selection dictionary, but that doesn't save combinators over just stacking *Everything comparisons until you have a lot of signals, and is much slower to boot.

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Thu Dec 10, 2020 10:21 am
by DaveMcW
You can multiply everything by -1 to convert it to a maximum finder.

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Thu Dec 10, 2020 10:33 am
by foamy
DaveMcW wrote:
Thu Dec 10, 2020 10:21 am
You can multiply everything by -1 to convert it to a maximum finder.
Yep, realized that just now while I was fiddling. I feel kinda stupid for asking now :v

Thanks for your help!

Re: Advanced circuit network conditions for train behavior in 1.1

Posted: Thu Dec 10, 2020 2:50 pm
by burninghey
is there a final bp for this?