Allow setting the max value for the dynamic train limit

Post your ideas and suggestions how to improve the game.

Moderator: ickputzdirwech

User avatar
Hares
Filter Inserter
Filter Inserter
Posts: 339
Joined: Sat Oct 22, 2022 8:05 pm
Contact:

Allow setting the max value for the dynamic train limit

Post by Hares »

TL;DR
It would be nice to have the train stops allowing to set the maximal value for the train limit got from the circuit network.

What?
The train stop circuit setting "Set train limit" should have an additional optional integer field called smth like "but not more than..." which defines hard limit for the number of trains this station can support, even though the circuit network suggests the higher number.
Why?
Usually, the train stops have the so-called waiting area which allows more than one train to wait in the queue until the station is free. However, the number of waiting spots is usually limited to 2 or 3, especially for the train stop stacks. If the numbers of trains approaching is higher then the number of waiting spots, a potential disaster can happen in a form of train blocking path to other stops nearby or even by stopping the main train bus. Thus, setting a limit not exceeding the number of wainting spots is a must.

On the other side, if you have multiple train stops with the same name which is a normal practice, you want only stations with enough items in the inventory to be active or otherwise trains will always go to the closest one and wait 5 minutes until this almost-deplted mine can provide enough resources while the more distant ones have already stopped producing due to a full chests. Furthermore, just toggling enabled/disabled is not a solution either because that way the moment stop inventory exceeds the threshold 2-3-4 trains will start approaching while only one will be able to be fulfilled. Even more, the train stop will become inactive potentially locking trains on the middle of the rail network. Okay, let's just use arithmetic comb to divide the station inventory by a train inventory, and get the number of trains this station can handle... and oops, our full 12-chest-per-wagon station now requests astounishing 14 trains while only 3 staging slots (including the station itself!) are present!

Thus, the solution is born -- the combinators!
What we want is the following:
  1. Divide the station inventory by a number of items which could fit per one train
  2. Assume the result as the potential number of trains the train stop can handle (L)
  3. If the result (L) is greater than the number of waiting spots (M), use the last instead
By now, I can see two different approaches to do so
  • Option A: use multiple decider combinators to compare L & M and return the lowest of them, then cast the result to L. Pros: Works in any setup. Cons: Quite complex & uses a lot of combs
  • Option B: use a series of decider combinators each comparing the station inventory (I prefer to do so in stacks, but it can be in any format) to a multiples of train capacity, and each returning L=1 if the comparison is passed. I.e., "if S >= 40 then L += 1; if S >= 80 then L += 1; if S >= 120 then L += 1" etc. Pros: Requires minimal number of combs, easy to setup. Cons: Number of combs and manual inputs greatly increases with the number of waiting spots
However, there is a third solution to this problem.
Allow train stops to use the max-limit "from the box".
Tertius
Filter Inserter
Filter Inserter
Posts: 935
Joined: Fri Mar 19, 2021 5:58 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Tertius »

Even for 1.1, you don't need "a lot of combinators" to limit the maximum train limit. You need exactly 1 additional decider combinator, and one constant combinator, but you probably need a constant combinator anyway. This is not that much more complexity.

One arithmetic combinator is always required. It's the one to divide the station content (for loading stations) or the free space (for unloading stations) by the train capacity to get the potential number of trains the train stop can handle (L).

Another arithmetic combinator is also required for unloading stations. It's for multiplying the station content with *1 to be able to subtract station content from station capacity to get the free station space, which is the input of the division for unloading stations. You can leave this one out, invert some constant values and subtract after division, but this will make all your chests appear to have only 40 slots instead of 48 due to integer rounding. So I keep this in.

The only additional combinator to limit the station limit is one additional decider combinator.

Assume you want to limit the maximum station limit to 3. The trick is to first subtract the maximum train limit from the computed dynamic train limit. If the result is < 0, we're below maximum limit and output this negative value. If not, we don't output anything.
At the output, we add the maximum station limit again. If we didn't output anything before, we were above the limit, so we now get the maximum limit. If we did output a negative value, it is added to the maximum limit, so it's actually a NOP for the result of the division, so we get the dynamic limit here.
And that's the whole computation.

In the example below, the configuration takes place in the constant combinator. L is the maximum train limit, M is the negated maximum train limit. You have to always set M to the negated L value. Blue is the train content. S is the station capacity. Required only for unloading stations. The other values are a help for me to remember stack sizes. They're not relevant and not output. With one exception: for the loading station, there is one M=-1 signal in the bottom right corner. This must not be deleted. This is to compensate one blue / blue = 1 division result from the * / blue division. This saves us one combinator (the one that multiplies with -1 for the unloading station).
There is also one additional combinator in the setups for active chest balancing. This one is independent and can be left out. It isn't needed for computing the station limits. If you keep it and change the number of the wagons of the station, don't forget to update the chest count in this combinator.

To actually use and configure the blueprints, you need to set L to your maximum train limit, M to the negative of that, blue to the train capacity, and S for unloading stations to the maximum station capacity. That's it.
Keep the one additional M=-1 as it is for the loading station, don't remove or merge it.

Working examples:
Screenshot 2023-11-28 183421.png
Screenshot 2023-11-28 183421.png (1.37 MiB) Viewed 4159 times
loading station:

Unloading station:
Last edited by Tertius on Sun Dec 17, 2023 9:35 pm, edited 1 time in total.
Illiander42
Filter Inserter
Filter Inserter
Posts: 521
Joined: Mon Feb 05, 2018 10:01 am
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Illiander42 »

Is that design going to get smaller when we get 2.0 complex combinators?
Tertius
Filter Inserter
Filter Inserter
Posts: 935
Joined: Fri Mar 19, 2021 5:58 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Tertius »

As far as I see, not with the currently presented combinators. There is no "return a value, but clip it to <constant>" functionality in the arithmetic combinator.

My proposed solution is even the same in 2.0, because the current combinators implement only the THEN part of a conditional statement and return a hardcoded nothing for the ELSE part. If we want ELSE, we need to duplicate the combinator, invert the condition and define the ELSE output.
And we're not able to return a constant value different to 1 if we want to return a constant value. We always have to multiply this 1 with the constant we wanted to return in the first place. This, combined with the missing ELSE, makes advanced combinator usage somewhat tedious.
User avatar
Hares
Filter Inserter
Filter Inserter
Posts: 339
Joined: Sat Oct 22, 2022 8:05 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Hares »

Tertius wrote: Tue Nov 28, 2023 5:39 pm In the example below, the configuration takes place in the constant combinator. L is the maximum train limit, M is the negated maximum train limit. You have to always set M to the negated L value. Blue is the train content. S is the station capacity. Required only for unloading stations. The other values are a help for me to remember stack sizes. They're not relevant and not output. With one exception: for the loading station, there is one M=-1 signal in the bottom right corner. This must not be deleted. This is to compensate one blue / blue = 1 division result from the * / blue division. This saves us one combinator (the one that multiplies with -1 for the unloading station).
There is also one additional combinator in the setups for active chest balancing. This one is independent and can be left out. It isn't needed for computing the station limits. If you keep it and change the number of the wagons of the station, don't forget to update the chest count in this combinator.
I've deployed that blueprint, it doesn't work.
I've put =8 stacks of plates to each chest, 800 items per chest, 4800 per wagon. Result is 0 trains. Didn't work either when I put 2k items per chest.
Tertius
Filter Inserter
Filter Inserter
Posts: 935
Joined: Fri Mar 19, 2021 5:58 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Tertius »

omg, you found a bug. It seems I did some last minute change and didn't check if I didn't break anything.
In the loader station, the inputs of both arithmetic combinators must be connected with green wire, not the input of one with the output of the other.

Fixed blueprint:


Don't forget to adjust the blue value according to the stack size. 16000 is for ore, 32000 would be for plates.
User avatar
Hares
Filter Inserter
Filter Inserter
Posts: 339
Joined: Sat Oct 22, 2022 8:05 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Hares »

Okay, your design indeed works but requires a pre-calculation and multi-value setup depending on the train limit. I can reduce the setup to a single input (only "M" for max trains, and "S" for item stack size) but that will require additional combinators. Since I usually vary the waiting area size I cannot use your setup (even though I would definitely use its idea in other circuits / use cases). In other words, you traded simplicity for optimization.
Tertius
Filter Inserter
Filter Inserter
Posts: 935
Joined: Fri Mar 19, 2021 5:58 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Tertius »

I try to create setups with the minimum possible amount of combinators while still retaining usability. As long as I have a single point of configuration (in this case the one constant combinator), it's ok for me. Constants are ok for me to pre-calculate manually. I set them once when I build the station, then never touch it again.

While creating some logic, I ask: "is this comparison required? Is it required these two arithmetic calculations run on 2 different combinators, or can I combine them into one?" If I have one > comparison and one < comparison, I investigate if I can combine both by first multiplying one value with -1, then merge the signal and add/subtract some base value to both, then compare both with EACH > 0 or EACH < 0. Sometimes, it's possible to reuse some -1 multiplication that's required anyway, so in the end one combinator can sometimes be saved.

In the given loader station, every combinator/every calculation they do is required and you cannot remove one to optimize. Every combinator does something different that cannot be merged with another. One combinator calculates the average of chest content for chest balancing. One combinator calculates the number of trains that can be filled. And one combinator makes a decision if the number of trains is above the intended limit. Even the enhancements announced for 2.0 will not enable us to use less combinators.

Re-adding combinators just for ease of configuration is a waste ;) It will calculate the same value for the lifetime of the map.

However, it's tempting to calculate constants with the 2.0 enhancements, since it seems you're given the stack size of items with the new selector combinator. This, by the way, is probably also a way to enable us to differ between item signals (ore, plates) and virtual signals (A, B, C), which is currently not possible. But since we're not given the amount of entities connected (we need the number of chests, or in general the amount of stacks), there is still some manual configuration required.
User avatar
Hares
Filter Inserter
Filter Inserter
Posts: 339
Joined: Sat Oct 22, 2022 8:05 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Hares »

If you want a scalable setup which requires to know # of chests, you can make so each chest appends 1 to the overall amount (or 6 per chest group). I do so quite often when I'm unsure what the final number will be, or when I need to do some binary encoding.

Also, a side note, with a DC2.0 there's now a way to output a constant different from 1. All you need is to make sure a constant is on the one wire (i.e., red), and the condition is on the other (i.e., green). Then: "If (condition on green) then output ALL (red asterisk) from red".

P.S.
I got your point two messages ago, you don't need to explain it again. )
However, I personally don't like predefined calculations and try to avoid them (because I usually mess them up).
Tertius
Filter Inserter
Filter Inserter
Posts: 935
Joined: Fri Mar 19, 2021 5:58 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Tertius »

Hares wrote: Mon Dec 18, 2023 2:53 pm I got your point two messages ago, you don't need to explain it again. )
Sorry, I didn't read everything again, and I don't remember all I write. However, it's nice to see I came to the same conclusion as my other me at that time. :mrgreen:

In the meantime, I actually created a suggestion to read the amount of entities connected to a circuit wire: viewtopic.php?f=6&t=110268
FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2768
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by FuryoftheStars »

Hares wrote: Mon Nov 27, 2023 9:59 pm Option A: use multiple decider combinators to compare L & M and return the lowest of them, then cast the result to L. Pros: Works in any setup. Cons: Quite complex & uses a lot of combs
I may be missing or misunderstanding something, but outside of the combinators needed to calculate L (which, if I'm understanding correctly, even with your suggestion would still need to be done, right?), this can be solved in 4 combinators (maybe less if someone more proficient than me takes a look).
  • 1 Constant combinator outputting your M for the station.
  • 2 Decider combinators - both are connected to both the constant combinator and the output of your combinator setup that calculates your L. One compares L >= M, output M input count. The other compares L < M, output L input count.
  • 1 Arithmatic combinator whose input is connected to both decider combinators, set for Each * 1, output L.
  • Your arithmatic combinator then hooks to your train stop.


Notes:
  • For the 2 decider combinators, it does not matter which one has the "or =" comparative, so long as it is one and only one of them.
  • The arithmatic combinator not only casts M to L, but it prevents a 1 tick delay where the train stop potentially receives both L signals and thus combines them.
Attachments
Train stop limit max.png
Train stop limit max.png (528.6 KiB) Viewed 3783 times
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles | New Gear Girl & HR Graphics
User avatar
Hares
Filter Inserter
Filter Inserter
Posts: 339
Joined: Sat Oct 22, 2022 8:05 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Hares »

FuryoftheStars wrote: Mon Dec 18, 2023 10:52 pm I may be missing or misunderstanding something, but outside of the combinators needed to calculate L (which, if I'm understanding correctly, even with your suggestion would still need to be done, right?), this can be solved in 4 combinators (maybe less if someone more proficient than me takes a look).
Yes, you got it right. 4 isn't a big number but it's enough to be noticed, especially when you add conbinators for other things:
  • L calculation
  • Train size or stack size as a variable parameter
  • Anti-clock mechanism (increase L but not M by one if train is fully loaded but waiting on station)
  • etc
Since the train stop "head" space is rather limited, it can be a real problem.
FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2768
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by FuryoftheStars »

Huh, ok, I guess I don't see it as a problem, especially seems L is being calculated either way and you can move the 4 combinators around to where ever is needed, but if the devs want to implement it.... I'm neither for or against. I just don't really see the need. *shrug*

This said, too, it should be noted that with the 2.0 changes announced so far, the setup I posted can probably combine the 2 decider combinators into 1, but also the "Anti-clock mechanism" you mentioned should not be needed after 2.0 as well.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles | New Gear Girl & HR Graphics
User avatar
Hares
Filter Inserter
Filter Inserter
Posts: 339
Joined: Sat Oct 22, 2022 8:05 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Hares »

FuryoftheStars wrote: Tue Dec 19, 2023 1:35 am This said, too, it should be noted that with the 2.0 changes announced so far, the setup I posted can probably combine the 2 decider combinators into 1, but also the "Anti-clock mechanism" you mentioned should not be needed after 2.0 as well.
That anti-clock mechanism is to prevent when you have 2 stations (1 load, 1 unload) for 2 trains each, and 4 trains. All load stations are full, all unload stations are empty, but the trains do not depart because the train limits are full. This behaviour is not going to change (or is not confirmed at least) but was for sure mentioned in the comments. And, unlike the FFF-mentioned "train department issue" which I never encountered this is the problem I encounter quite often. However, instead of adding 1 to the L, I instead usually make sure that the # of trains in each group is less or equal to the # of loading stations.

(Train interrupts is A workaround for this clocking problem, but not THE solution)
FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2768
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by FuryoftheStars »

Ah, ok, that wasn't clear to me from the initial mention, apologies. I thought you were referring simply to the situation where the train is ready to depart, releasing the reservation and thus allowing another train to path to the station before space had actually been cleared for it. Either way, still doesn't change my thoughts on this.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles | New Gear Girl & HR Graphics
Bun-Bun
Manual Inserter
Manual Inserter
Posts: 4
Joined: Mon May 06, 2024 9:44 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Bun-Bun »

Tertius wrote: Tue Nov 28, 2023 5:39 pm Another arithmetic combinator is also required for unloading stations. It's for multiplying the station content with *1 to be able to subtract station content from station capacity to get the free station space,
I'm not following this part. I used an arithmetic combinator to subtract the content of the storage boxes from the total storage (in my case 86,400) to get free space and then inputted that to the arithmetic combinator that divides the free storage by train capacity.

Why would *1 be needed or all that inverse stuff? I feel like something has gone completely over my head.
Tertius
Filter Inserter
Filter Inserter
Posts: 935
Joined: Fri Mar 19, 2021 5:58 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Tertius »

Bun-Bun wrote: Sat Jul 20, 2024 10:47 pm Why would *1 be needed or all that inverse stuff? I feel like something has gone completely over my head.
In general, additions within the circuit network are free in terms of combinators. There is an implicit add for all connected wires. You just connect wires, and the resulting signals are the signals all summed up. So if you need to subtract some signal from different sources, you can use an arithmetic combinator for each of these sources to subtract, requiring one for each source. Or you can use a single arithmetic combinator and multiply your signal with -1, then just connect the resulting negated value to your multiple sources.
Signal separation is achieved with intelligent use of red and green wire, since the implicit add works for red and green as well, if they're both connected to an item.

My station examples make extensive use of this. For example the inserter balancing. It's also called "madzuri", after the player who first published it. The summed up content of all chests is divided by the negative number of chests. This results in the negative average of the chest content. Each inserter is connected to its chest, as well as to the negated average, so the average is subtracted from the chest content, resulting in the surplus or lack or items in the chest. The inserter condition only activates on lack, so the chest content stays reasonably balanced.

Often, you just subtract once, so it doesn't matter if you multiply with -1 and use the implicit add, or if you directly subtract. It's the same amount of combinators. However, if you use the multiply with -1 variant, you may later find synergy and can just reuse the negated result for something else, without requiring an additional combinator.
So multiplying with -1 became a habit for me instead of subtract directly.

The train limit computation in my station examples also makes extensive use of the implicit add, so the natural counterpart is using negated signals instead of directly subtract. It's all for using the least possible amounts of combinators. This is also the motivation of the OP by the way: not use (too many) combinators for trivial operations.
Bun-Bun
Manual Inserter
Manual Inserter
Posts: 4
Joined: Mon May 06, 2024 9:44 pm
Contact:

Re: Allow setting the max value for the dynamic train limit

Post by Bun-Bun »

Tertius wrote: Sun Jul 21, 2024 12:09 pm
Bun-Bun wrote: Sat Jul 20, 2024 10:47 pm Why would *1 be needed or all that inverse stuff? I feel like something has gone completely over my head.
So multiplying with -1 became a habit for me instead of subtract directly.

The train limit computation in my station examples also makes extensive use of the implicit add, so the natural counterpart is using negated signals instead of directly subtract. It's all for using the least possible amounts of combinators. This is also the motivation of the OP by the way: not use (too many) combinators for trivial operations.
Thank you for this detailed explanation. It makes perfect sense now.
Post Reply

Return to “Ideas and Suggestions”