SSPP Logistics Train Mod

by jagoly

A logistics train mod that aims to be as pleasant to use as possible, even when knee-deep in byproducts. SSPP stands for Source-Sink-Push-Pull.

Content
11 days ago
2.0
585
Logistics Trains

g Why do items have a class?

3 months ago

What is the purpose of items/fluids having a class. Classes seem to be defined with enough information that a delivery should be able to figure out what train class to use without manually setting it per item. If the train classes are there to allow having multiple trains layouts like 1 or 2 wagons, then it would make more sense to set at the station what train classes it allows rather than for the items.

3 months ago
(updated 3 months ago)

Assigning items to a single class is a core simplification of the way that SSPP functions. As a counter to your question, I would ask: Why do you need multiple classes for the same item?

The only valid use case is I can see is if you have specific requester stations that: have very limited storage, need a trickle of many different items, and several of those items all have other requesters that need a great deal of those same items. That particular case is not easy to handle well, and it should be noted that Cybersyn, while allowing this, completely ignores priority in these cases, which can starve the larger requesters if you have a supply shortage.

I should also mention that SSPP is primarily designed around small trains (1-1 or 1-1-1), since now that we have elevated rails to reduce congestion there is really no reason to use larger trains in overhaul mods, other than aesthetics.

If you can describe exactly what it is you are trying to do that SSPP doesn't allow you to do, I would love to hear it. Even if it's something I wouldn't personally do, I would still like to support it if I can without making other things more difficult.

3 months ago
(updated 3 months ago)

I think I mixed two ideas in my initial post which may have been confusing. First, I didn't mean that there is a need to define multiple classes per item. It just seems like unnecessary work as a user to manually define a class for each item. I guess this is a suggestion to remove the class field for items/fluids if you haven't considered it. Instead have the system determine what class to use when it is needed. I don't think this affects the way SSPP works, but it would be a great quality of life improvement.

For example, a basic setup using 1-1 trains you'd have 2 classes: 1 for fluids and 1 for items. If I add iron plates to the system, it should be able to figure out that it needs to use the item class without me telling it.

My second point, is that ability to specify supported classes at a station would be nice. I agree that for most cases 1-1 trains are great, but sometimes other layouts are useful. Like for ore trains in pyanodons which have low stack sizes. Or having just a couple of stations that require double headed trains in a primarily single headed network. I also think it fits in nicely with the SSPP's train class design. Not a huge priority for me, but would be nice to consider for the future.

Otherwise, if SSPP is not going to concern itself it train layouts it could completely remove the manual specification of train classes. Especially if you implement the first suggestion to remove manual train classes from items. Then when trains are added to SSPP, it can just scan the train for it's item/fluid capacity by itself and skip typing the class name. Then it would be possible to paste trains and have them join SSPP automatically, maybe by stopping at a station like in cybersyn.

One last thing that has popped up since I initially posted: there is no way to set train limits for SSPP stations.

Hope this clears up what I was saying. Seems like a cool mod.

3 months ago
(updated 3 months ago)

I think I mixed two ideas in my initial post which may have been confusing. First, I didn't mean that there is a need to define multiple classes per item. It just seems like unnecessary work as a user to manually define a class for each item. I guess this is a suggestion to remove the class field for items/fluids if you haven't considered it. Instead have the system determine what class to use when it is needed. I don't think this affects the way SSPP works, but it would be a great quality of life improvement.

For example, a basic setup using 1-1 trains you'd have 2 classes: 1 for fluids and 1 for items. If I add iron plates to the system, it should be able to figure out that it needs to use the item class without me telling it.

Ah, yeah I see. I think that the convenience aspect could be easily solved with some UI improvements I have planned:
- allow you to set default classes for new items/fluids
- add a "duplicate" button to each row that would just add a copy of that row with the item picker cleared

My second point, is that ability to specify supported classes at a station would be nice. I agree that for most cases 1-1 trains are great, but sometimes other layouts are useful. Like for ore trains in pyanodons which have low stack sizes. Or having just a couple of stations that require double headed trains in a primarily single headed network. I also think it fits in nicely with the SSPP's train class design. Not a huge priority for me, but would be nice to consider for the future.

It is as you suspected, there are a few implementation reasons why this is more complicated than you would expect.

The second example would be doable, where you have single and double headed versions of trains with the same capacity, though it would still be quite complicated to support. I imagine that classes would be given "layouts" lists, where you would specify all of the layouts that might be used for that class. It would let you include a mix of for example single/double headed trains, or trains using the next tier of py wagon (shorter, but with the same capacity). Then you would specify the supported layouts at stations. This does seem pretty niche though so if it does happen, it won't be soon.

As for ore trains with low stack sizes, using longer trains for some items is already possible, the only issue is when you want to be able to use both high and low capacity trains for the same item. This is mostly what I was talking about in my last response. That is a significant change with a lot of other problems that I would need to solve, though I have been thinking of ways to do it that wouldn't break other things.

Otherwise, if SSPP is not going to concern itself it train layouts it could completely remove the manual specification of train classes. Especially if you implement the first suggestion to remove manual train classes from items. Then when trains are added to SSPP, it can just scan the train for it's item/fluid capacity by itself and skip typing the class name. Then it would be possible to paste trains and have them join SSPP automatically, maybe by stopping at a station like in cybersyn.

The classes are most important for specifying the depot and fueler names. Admittedly, I don't quite see the advantage of removing classes entirely; I don't think that specifying them for each item is that inconvenient (especially if I make the improvements I mentioned above), and they are very convenient for me, implementation wise. I also enjoy the fact that when things go wrong and the train is locked, SSPP doesn't forget about the train. All I have to do is switch it back to auto and the train will purge any items and then go back to work.

Picking classes automatically could definitely be done, though even just a popup window where you can pick from existing classes would mostly fix the inconvenience IMO. That is already on my TODO list.

One last thing that has popped up since I initially posted: there is no way to set train limits for SSPP stations.

Yep, that is known. Train limits are complicated to support. If you use them in cybersyn for example, you are basically saying "I don't care about priority". I made a PR to deal with that a long time ago actually https://github.com/mamoniot/project-cybersyn/pull/135 . If I add support for train limits, it will be done in a way that doesn't cause stations to miss out on service if by coincidence they happen to be servicing different items at a particular moment.

Hope this clears up what I was saying. Seems like a cool mod.

I think it did, and thanks :)

3 months ago

Ah, yeah I see. I think that the convenience aspect could be easily solved with some UI improvements I have planned:
- allow you to set default classes for new items/fluids
- add a "duplicate" button to each row that would just add a copy of that row with the item picker cleared

Sounds great.

Yep, that is known. Train limits are complicated to support. If you use them in cybersyn for example, you are basically saying "I don't care about priority". I made a PR to deal with that a long time ago actually https://github.com/mamoniot/project-cybersyn/pull/135 . If I add support for train limits, it will be done in a way that doesn't cause stations to miss out on service if by coincidence they happen to be servicing different items at a particular moment.

I'm not familiar with how train limits would affect priority, but I think it is better to have train limits even with issues. It is too easy to cause a deadlock by having more trains at a station than it is meant to hold.

3 months ago
(updated 3 months ago)

Basically in cybersyn, if a station is over it's train limit, then as far as the dispatcher is concerned, it has all of it's needs completely met. Resources will happily be sent to low priority (void) stations, and the high priority station will get nothing. Depending on the order that dispatches of other items happen, this can repeat, potentially wasting a lot of resources.

I should also note that SSPP does check the train count of stations before it dispatches, and will prefer sending to ones with fewer trains first. My view is that if your stations are at risk of deadlocking due to too many trains being sent, then they can't actually handle the throughput that you've told them to, and you should probably split them into multiple stations anyway.

3 months ago
(updated 3 months ago)

I think a train limit is a way of setting throughput limits and if that limit is hit it is correct to send to a lower priority. Plus a player can not set a limit or set a high limit if they run into the issue you mention. Having train limits doesn't you have to use them.

Setting throughput is not a solution to train limits. For provider stations, the throughput doesn't do anything to limit trains. SSPP will gladly send as many trains as it can if there are enough items in the buffer. For requester stations, throughput can barely limit trains. How many trains are needed to service a certain throughput is far from obvious and throughput may change. Requesting multiple items make this worse since each item can be sent at the same time. 10 items with a throughput of 1/min each can send 10 trains at the same time.

Limited throughput or sending resources to low priority is better than potential deadlocking. It is more important that I can trust SSPP to not cause a deadlock when left unattended for long periods of time. Also when too many trains don't deadlock, it can still block other trains for a long time.

3 months ago

Something I've noticed while testing is that trains sometimes stop. It is hard to debug because the warning message only appears for a few seconds so by the time I notice it is gone. I also have no idea where the train was going because I think the schedule was cleared when the train is set to manual. The reason the trains stop is because it seems SSPP can reschedule the train while it is on the way to the depot, but before it arrives. But sometimes the train can't turn around and find a path because it is in the middle of an intersection.

3 months ago
(updated 3 months ago)

Limiting trains on providers is done by setting limits on your chests, as you should really do in any train system, including vanilla. You already need to do that for multi providers to function at all, and it's even simpler to do for single item providers.

The logical purpose of train limits is of course to limit the number of trains at a station at once. In vanilla, that is effectively a throughput limit, but it doesn't have to be that way, if you have buffers large enough to handle the variation that temporary fullness causes. In SSPP that variation should be included in the "latency" value, which is really just a simple "more buffer" value.

When train limit support is added, it definitely won't result in sending resources to lower priority stations. It will be purely to spread the deliveries out over time. I also want it to warn you if you try to give stations requirements that are simply impossible to meet. I have plans to support limits eventually, though I won't be supporting it at all until it can be supported properly.

Also, the theoretical maximum number of trains is actually quite easy to calculate, I almost added it the statistics block but opted not to since you really, really don't actually need room for that many. Related items are going to tend towards being staggered naturally. Just give every station at least one dedicated waiting area, and design your stations so that trains entering don't block trains from exiting, and you'll be fine.

EDIT: apparently this took me half an hour to type (went and got a snack), it was responding to your first message :D

3 months ago

Something I've noticed while testing is that trains sometimes stop. It is hard to debug because the warning message only appears for a few seconds so by the time I notice it is gone. I also have no idea where the train was going because I think the schedule was cleared when the train is set to manual. The reason the trains stop is because it seems SSPP can reschedule the train while it is on the way to the depot, but before it arrives. But sometimes the train can't turn around and find a path because it is in the middle of an intersection.

Ah, right. I wasn't thinking about double headed trains when I decided to let trains dispatch from anywhere. I think the only safe way to deal with double headed trains is to only allow them to dispatch once they reach the depot. I'll add a new setting for classes for whether or not they can dispatch early. Thanks for catching that.

Also, even when the alert goes away, the information about what went wrong should still be visible in the SSPP widget when you click on that train. I do intend to add a centralised log for recent alerts, deliveries, etc. which will make finding trains easier if you don't react to the alert right away. For now though, the vanilla trains view will show them as "[Empty]" and you can click them from there.

3 months ago

Sorry I wasn't able to get the depot bypass switch finished today, some stuff came up. If they are causing issues for you until I get the fix done, just putting loops on your depots should fix things. I feel pretty silly for not fully testing double headed trains before publishing this 😅

3 months ago

Hi, I've just published a new version with support for disabling depot bypass. Please let me know if it fixes your issues :)

3 months ago

I think that fixes the issue :) . The way cybersyn bypasses depots is it will only create a bypass while it is stopped at a cybersyn station which provides the best of both worlds.

There is a bug in the available train count on the classes tab. It works fine when bypass is disabled, but gives weird values with it enabled. With 4 trains it shows 3/3, 2/3, 0/4, 2/2, 4/3, etc.

It's been amazing seeing how fast you're developing this. Good job.

3 months ago
(updated 3 months ago)

Would it be possible to make broken paths not break a train? It would be nice if after fixing a rail the all trains don't need to be restarted. Breaking an important rail can break a lot of paths at once. Also the vanilla path not found error is really good and makes debugging path issues easier.

3 months ago
(updated 3 months ago)

Not really. I don't think any of the other logistics train mods do that? Keeping track of trains when things go wrong is not easy. When I add the log tab that I mention at the bottom of the readme, that'll have an "enable all trains" button that will switch them all to automatic again.

In the meantime, there is a command you can use, /sspp-reboot that should get things going again after any kind of mass failure.

3 months ago
(updated 3 months ago)

I think that fixes the issue :) . The way cybersyn bypasses depots is it will only create a bypass while it is stopped at a cybersyn station which provides the best of both worlds.

There is a bug in the available train count on the classes tab. It works fine when bypass is disabled, but gives weird values with it enabled. With 4 trains it shows 3/3, 2/3, 0/4, 2/2, 4/3, etc.

It's been amazing seeing how fast you're developing this. Good job.

Thanks, I'll look into both of those things, as soon as I fix the migration issues people are having. I really need to just add a second rail grid to my test world for double headed trains.

Edit: The bug with the total is now fixed, thanks for reporting it. As for the first point about CS depot bypass, I think you are misremembering. CS doesn't ever let a train wait at a requester, it will send the train to the depot as soon as the requester is done, so it would have the exact same issue as SSPP. Interestingly enough, having trains wait at requesters that don't have new trains coming IS actually something SSPP could theoretically support, and is something I looked into adding to CS back when I worked on it, but it wasn't doable with the way CS worked.

3 months ago
(updated 3 months ago)

Not really. I don't think any of the other logistics train mods do that? Keeping track of trains when things go wrong is not easy. When I add the log tab that I mention at the bottom of the readme, that'll have an "enable all trains" button that will switch them all to automatic again.

This is at least how CS handles it. Once a train is dispatched it does not check if there is a path break. It doesn't even check for a valid path when dispatching (besides check they are the same surface). This is still useful behavior since it makes it very visible when a train cannot get somewhere. The only error you'll get from the mod is a stuck train error if a train doesn't arrive somewhere after a few minutes. I think that is the key, as far as the mod is concerned, broken paths aren't even a concept so they don't need to be specially handled. Path errors are vanilla train behavior which works pretty well without a mod doing anything.

You're right about CS bypass, guess I never noticed.

3 months ago

Right, that does seem to be the case. I was intentionally quite zealous with locking the train when something unexpected happens. Going forward, I'll try and make more unexpected things into expected things. I think I SHOULD be able to just not lock the train when a path break happens, but there's a couple of edge cases I'll need to test and account for before I can do that.

3 months ago

I tried rewriting it behaving more like cybersyn and it seems to work pretty well. I'm not sure if you are open to contributions, but I did make a pull request if you are.

3 months ago
(updated 3 months ago)

If you've already got it done, a PR would certainly be welcome! I don't think it should be too much code, just tweaking the train state change handler, and the send_hauler_to_* functions. It seems like it should be a lot less intrusive than I thought it would be.

edit: oh you already sent it haha

New response