Factorio

Factorio

View Stats:
Gnord May 4, 2022 @ 6:53pm
Named train stations
I'm finding that trains always pick the named station that is closest to them when making the decision to travel to named stations of the same name. So, if you have 10 stations, and 10 trains, you will discover that it's NOT distributing the outputs evenly. On the contrary, it's very likely there will be multiple stations that don't get serviced at all, despite there being more than enough trains to do so. If you over-compensate and make more trains, you can deadlock the system.

I like the idea of train stations sharing the same name, but the "greedy" train algorithm isn't really working for me, and I find myself wanting a round-robin, or dynamically-weighted option.

SUPER ideally, a station would know how "efficient" its train visits are (time stopped, start/end capacity difference, etc), and highly efficient train stops would rise in weight, and low efficiency train stops would decrease in weight. A train station that hasn't been serviced in a long time would rise in weight, until it's serviced, and so on. This could be handled pretty directly with a single weight that goes up or down based on the train's activity while stopped at the station. And then when a train picks an option from a set of named destinations, real time weight and distance combine to become inputs for a random selection.

In the meantime, I think I'm gonna have to disassemble all my identically named stations for now, and do a more rigid "every train goes from exactly A to exactly B", because too many stations just don't ever get visited.
< >
Showing 1-15 of 24 comments
THE kilroy May 4, 2022 @ 7:31pm 
Each station can have a "train limit" set so you could say 1 train only at a time is allowed to path to THAT individual station
Gnord May 4, 2022 @ 7:36pm 
Yes, and I did that. But it's not enough. I have "pickup" locations and "drop" locations, and no matter how I arrange the trains and train limits, the closest open drop locations are always the places where the items get dropped, regardless of how I set these. The drops that are far away never get picked because there's always a way for the trains to not pick the farthest away locations.
Gnord May 4, 2022 @ 7:43pm 
Even in the extreme case where there's "pickup + drop - 1" number of trains, it still doesn't work out as a full round-robin. In-transit trains don't occupy a spot, and so it can always find a way to ignore a destination.
Gnord May 4, 2022 @ 7:46pm 
But, back to my point about weights: Even if it goes to a location, it can drop zero items and only leave due to the timeout, effectively making that location a waste to drop at. (This can be influenced by the ignored station failing to produce a necessary alternate input, and again, soft-deadlock the trains (they're moving, but they're not "doing anything").

Making sure all destinations of a same name get serviced, even if there's only 1 train, would be helpful, and it should easily scale up, unlike the current system.
shadain597 May 4, 2022 @ 7:55pm 
I'm not the expert on vanilla trains, but I think in this situation people typically use train limits, stackers, and logic that dynamically sets the train limit based on the items found in the stations' input/output buffer chests. If that's still not enough, then you probably need to increase your supply throughput. If you are worried about making sure that each dropoff location gets a trickle of resources in the event of a supply crisis, well, I think the only practical solution is to have more unique station names and routes.
astrosha May 4, 2022 @ 8:14pm 
The game looks for the closest station, based on the number of signals it has to pass through to get there. So long as there is any option at all, the train picks the nearest station.

So, that leaves adjusting the options.

Train Stop Limits work well, provided that you have sufficient trains for the demands of all the stations. A 70 second round trip to pick material up, combined with a 15 second drop off, means that you have one train servicing the station every 85 seconds. If the station needs materials faster than that, it may require many more trains to meet the demands of this station alone. If you need too many trains (at your discretion) changing the station from a shared name to a unique name may be the better option.

The other alternative, especially if you are trying to use only a limited number of trains, may be to use circuit logic to enable the drop off stations in order, keeping them disabled otherwise. This will result in a thundering herd (depending on the number of trains looking for the next Enabled station) which is what the Train Stop Limits were meant to counter, but that's something you'd have to deal with here. However, by selectively Enabling stations you would ensure that the far stations would receive equal attention by the trains. You could even set it up to be that round robin you want.
The_Mell May 4, 2022 @ 8:43pm 
A round robin system would even make things worse and more inefficient because you would create unnecessary long train routes.
All that round robin does:
It depletes resource field with lowest resources first - no matter how far away.


If you just activate & deactivate train stations based on how full their buffer chest are, you can have a quite good balance already.

Train station has enough material to fully load a train: weight goes from 0 to 1
Train station has enough space to fully unload a train: weight goes from 0 to 1
It has not: 1 to 0

All that math about some weird defined efficiency improves little to nothing if your goal is to feed your factory. Even a relative simple fuzzy logic based on buffer chest filling is already a waste of brain & computing time. Not to mention train running inefficiency if they make partial deliveries.
The only thing where you want to improve this on/off-system is the train limit because there is no need for multiple trains to go to 1 station.

It's all a pyramid with your final product at top - and if some lower products are overproduced it only means your pyramid widens (a bit).
Yes, in a perfect world you could create a perfect pyramid but the moment a resource field runs low your world becomes imperfect.
A full belt with a backup is not a problem but an insurance for worse times. :KSmiley:


The really neat thing about same named train station is that you do not (need to) care about even out because your trains can work as a balancer (towards output) if you make sure that you've got enough resources put into your train network and you feature enough trains to transport them.
As long as your belts into your factory are fed who cares where that stuff comes from..?

If the answer is "Me." then go ahead and build yourself a system with balanced inputs...but please don't try to make up a thing where this is a 'must have'.
Where you could focus only at one problem, the output, you make yourself an unnecessary second problem by overthinking input in my opinion... :ksad:
THE kilroy May 4, 2022 @ 9:35pm 
If the goal is max material per hour than the answer is more trains(even without checking buffers) regardless of station names.

If the goal is always a full load upon arrival(no idle time), the answer is disable the station with circuits based on buffer chest content AND train limits so that 2 trains do not que for 1 load.

If the goal is literally take turns(not seeing a real benifit to it but nevertheless), you need to have individual names and set a really boring train schedule like, a-smelt-b-smelt-c-smelt. Or an even more elaborate curcuit system spanning all your network.

If the goal is to monitor the content of the mines,you CAN wire a miner up to see the available resources.(i dont think this is the answer but it might get you thinking)


With any of those options, if more trains is part of the answer and you are concerned it "can lead to deadlocks" you just need a more stable train network. Like an inline stacker at each station so a waiting train isnt waiting on the main rails,or a stacker before your smelter, again so a waiting train isnt blocking any path. Perhaps you are using roundabouts and not full intersections and that is slowing things down. Better rail signal practices,or maybe alternative routes. Dont be afraid of more trains.
kremlin May 4, 2022 @ 10:59pm 
What you want to do is wire your drop off chests to a decider combinator that outputs L = 1 when the drop off can take a whole train load. Something like (Resource) < 8000, provided you have enough chest space for 16000. Wire the output to the stop and set the stop to set the train limit based on it.
You're not using them correctly at the moment. You shouldn't have any stop that will allow a train to show up and drop nothing with a train limit above 0. It should not be possible for the train to decide to go there, if you're using train limits correctly.
Last edited by kremlin; May 4, 2022 @ 10:59pm
Gnord May 4, 2022 @ 10:59pm 
Hmmmmmmmm.... I always forget about the circuit network...
AlexMBrennan May 5, 2022 @ 1:55am 
SUPER ideally, a station would know how "efficient" its train visits are (time stopped, start/end capacity difference, etc), and highly efficient train stops would rise in weight, and low efficiency train stops would decrease in weight. A train station that hasn't been serviced in a long time would rise in weight, until it's serviced, and so on.
Those are contradictory goals - going to stations where the train can be serviced efficiently necessarily means that you avoid needlessly travelling to far away stations which you want to do for some kind of "balance" reason.

Unfortunately I don't think that this is a good use for circuits either because finding the minimum/maximum signals is going to require huge banks of combinators in addition to requiring one wire per resource to transmit all the penalties. I guess you could try multiplexing but that is going to use even more circuits and be even slower.
pinki.narf May 5, 2022 @ 9:49am 
For more intelligent trains, there's the LTN mod - there you name the waiting tracks, so that the trains don't have to fight over individual stops (I don't know if that would happen - my depots are called ... depot).
Every other stop gets the information whether it offers material (item signals > 0) or requests material (item signals < 0).
In addition, you can specify from which quantity a train should run at all - whether already at the first missing iron plate, or only at 4000 that fit into a wagon.

Before I set the train boundary by signals to zero, if the buffers at this stop were full - and there my stops were called 'load coal' and 'unload coal' and the coal train had 'only' the task to drive back and forth between load and unload - and stopped at the stop, if the next load/unload was not possible, because 'no train allowed'.

Translated with www.DeepL.com/Translator (free version)
RiO May 5, 2022 @ 11:24am 
There's a trick to doing prioritized resource drops with vanilla trains in a manageable, though somewhat sub-optimal way.

Setup your train schedules as:

  • "{resource} provider" until cargo full
  • "depot" until inactive > 2 secs (allow for refueling)
  • "{resource} priority requester" until cargo empty
  • "{resource} requester" until cargo empty
  • "depot" until inactive > 2 secs

And build requester stations and priority requester stations together, such that the priority requester station is directly in front of the regular requester station.

Use the regular wiring for train limits based on remaining station chest buffer for the regular requester station. But read the active number of trains going to the priority requester paired with it, and subtract that from the normal station's limit.

For the priority requester station's train limit set it to 1 minus the active amount of trains going to the regular station. Additionally, disable the station when the chest buffer has more than whatever threshold you define as constituting 'needs priority delivery'.


Now, how it works is trains must first consider the priority requester stations that are enabled and where a train is not already en-route to the regular stop paired with it (as that would lower the priority's limit to zero or lower, though effectively it can't go lower than zero and is capped there by the game engine.)

If all reachable priority stations sharing the same name are disabled, the train skips over that entry in the schedule and will then try to deliver its full load to the normal requesters.

If a priority station was reachable; enabled; and open - i.e. not at its limit; then it will first visit that station and then immediately path to the normal station directly behind it. Because the normal station will lower its limit by 1 when a train is at the priority requester station just in front of it. And as soon as that train departs, the limit is raised and the departing train schedules for the station that just opened up and wouldn't you know it: it's the closest station, so it gets picked.

99/100 times it'll work like that and the train will hitch forward; break and stop; and then immediately continue because its cargo is already empty. Only in some cases where things are evaluated 'the wrong way around' might the train departing the priority requester head for a more distant normal requester. Too bad; and that's where the sub-optimal part comes in.

But other than that; it works. 100%.


Also; for those of you playing modded games that are heavy in by-products that need priority consumption. You can apply the same pattern to provider stations as well, making the by-products be considered with priority when their chest buffer is nearing full.

You can also vary on the two-stations-in-a-row pattern by having dedicated waste-disposal trains that kick in once the chest buffer is nearing full and have a trash-disposal location linked into their schedule that is guaranteed to void the byproducts delivered as rapidly as possible.


(I've been using variants of this pattern with the Nullius mod.)
Last edited by RiO; May 5, 2022 @ 1:44pm
shadain597 May 5, 2022 @ 12:05pm 
Originally posted by RiO:
Also; for those of you playing modded games that are heavy in by-products that need priority consumption. You can apply the same pattern to provider stations as well, making the by-products be considered with priority when their chest buffer is nearing full.

You can also vary on the two-stations-in-a-row pattern by having dedicated waste-disposal trains that kick in once the chest buffer is nearing full and have a trash-disposal location linked into their schedule that is guaranteed to void the byproducts delivered as rapidly as possible.


(I've been using variants of this pattern with the Nullius mod.)
For modded games, I find LTN to be quite nice. With the combinators it's quite easy to set station priority levels, and I think you can even set separate station networks, though I haven't messed with that. I know that vanilla trains can pretty much do anything LTN does at this point, but (IMO) it's a bit less intimidating for players that have been avoiding doing anything complex with trains. Though I suppose I still looked up a video guide for how to use it, so, y'know, *shrugs*
Gnord May 5, 2022 @ 3:30pm 
What I did: Circuits.
Turn off stations destinations that are full. Works pretty well. It was necessary then to massively reduce the total number of trains, and sometimes they temporarily full-system-deadlock, when a train stops on the main throughway. But it's not horrible.

As far as weights, and responding to some counter-comments: One of the things I mentioned is that idle station weights increase over time. So eventually a low-service, low efficiency station WOULD get serviced again, because the weight would rise over time, based on time alone. Then it would drop again when the stop was inefficient. Plus, it's still random weights, so even at a low chance, it'll hit sometimes. But as far as the random selection picking high-efficiency stations a lot: YES. That's the point. If that station empties a train quickly, and then going forward continues to empty many trains quickly, that means it needs a lot of trains to stop there. With weights, it just dynamically adjusts how often it's randomly picked, and high throughput stations would want a lot of stops, moreso than a low efficiency station, which didn't transfer much, and timed out, and/or took forever to fully empty. :D

I am using mods, but I'm limiting myself to small mods, and mods that don't require big collections of libraries and dependencies. I want to mod it a little to solve a critical problem, but I still want it to be fairly vanilla. I also don't want to bring in a million changes all at once that I don't intuitively understand. So, warehouses, black cargo wagons, upgraded solar panels, etc. At about 40,000 vanilla solar panels, my computer couldn't really run my base anymore, so.... Now I have 500 "1000x-efficiency" solar panels. :D

Rio, your train script is interesting to me. I may try it. I was definitely torn about how to "design" separate resource channels of the same type if I were to separate them, without necessarily just doing 1 train between precisely 2 spots. I like your idea. As my factory is growing again, I may try it when I need it again.

For now, the circuits were the best solution. It reduced my number of trains by about 80%, so I'm much less congested, and my "full" stations don't get serviced. The threshold numbers are fairly easy to hook up and set since I have warehouses. I just had to stop and understand the circuit network first, as it's the first time I've successfully used it.

I still think my "station weight" idea has merit for vanilla, as it would remove the need for my circuits, but I can actually move forward again without it.

Thanks everybody!
Last edited by Gnord; May 5, 2022 @ 3:37pm
< >
Showing 1-15 of 24 comments
Per page: 1530 50

Date Posted: May 4, 2022 @ 6:53pm
Posts: 24