TL;DR:
A train should skip a stop it is set to skip if it already fulfills the wait conditions of that station right when it is departing.
Background:
A few years back, I was inspired by other circuit-based train managers to create my own, one that deploys the minimum number of trains between available pickup and drop-off stations to satisfy demand. It being vanilla-compatible meant that I was able to use it in environments that lacked a more robust manager, like LTN. At the time, I was faced with two problems that I did not find to have a sufficient circuit solution:
- If there were multiple available stations providing or requiring the same resource, the trains did not have a way to sufficiently tell which station was actually available for however many trains, leading trains to sometimes horde a singular station that did not need that many trains heading towards it.
- There was no way to have a train prioritize a station over another station, say, to consume a particular ore patch first or deal with a byproduct of a process before falling back to that resource's main supply.
My point with all this is that eventually there was a vanilla change that solved the first issue, that being the addition of train stop limits. A simple, yet elegant solution that only required a small change in wiring to what I had already constructed to tell the station to only accept as many trains as it claims to support. While there were technically workarounds to this issue prior to this change (by exploiting train signal pathfinding penalties), it was not perfect, and the addition of train stops had the added bonus of properly limiting depot stations to a single train at a time.
My aim with this proposal is to provide a similarly elegant solution for the second issue. As it stands, I could name the station I would like to prioritize a different name and order it earlier in the train's schedule than the other stations set to the same resource, and set its wait conditions to be the same as the non-prioritized station. This technically works... to an extent. The problem is that the train will then schedule itself to head over to an open, non-prioritized station even if that station too requires or is capable of supplying trains of its own, leading to a full train wasting time pathing to a supply station only to immediately move on from that station as soon as it realizes it is already full, similar deal with empty trains to demand stations. Even worse than this would be a train (as a result of having to path to a non-priority station after fulfilling its wait conditions at a priority station) waiting on another train sent to that station directly, essentially waiting on however much time it would take for the train at the stop to load/unload, only for the waiting train to head to that station, stop briefly, then move on with its schedule. Setting train limits by circuit
condition in reaction to this phenomenon does not readily solve this issue, since it may neglect to account for other trains that are otherwise perfectly capable of fulfilling that station's request.
The Proposal:
When a train has fulfilled its wait conditions at a stop and is at the stage in its departure to evaluate the next stop to path towards, it should check, if the train is set to check for skips (for that stop or at all, more on this in the user interface section), if the train already fulfills the listed wait conditions for the next stop:
- If so, it will run the same check until it either gets to a stop for which it does not already fulfill its wait conditions, or it gets to a stop it cannot skip, in either case it will path to that stop.
- If the train would end up skipping all stops, it must evaluate the closed or train-limited stops in its schedule if it already fulfills their listed wait conditions:
- If there is at least one it cannot skip or has wait conditions it does not already fulfill, the train will wait at its current stop until one such station opens up, and if not, it should have a message similar to the "no path available" floating text that conveys that the train will have no valid stations to path to as it effectively skips all of them (something like "no valid destination").
A train should not repath to a skipped station if it somehow no longer fulfills the skipped station's wait conditions during transit (
passenger jumps out of the train, someone steals or places resources in the train during transit, etc.). The skip check should only be done when the train is about to depart from a train stop.
I imagine the closed train stop case will be the biggest technical hurdle.
User Interface:
I suspect that a major reason why prior proposals to solve this issue failed to gain significant traction was because of the complex presentation of such solutions to the end user. What I mean by this is that I found that prior proposals often take a sledgehammer approach to adjusting the train schedule interface to accommodate such changes: introducing programming control flow more complicated and verbose than basic logic, separate skip conditions that the train also checks on top of the wait conditions it already has for such a stop, ill-defined probability approaches that introduce fiddling with numbers and random chance to achieve the desired effect of prioritizing stations, you get the idea. My suggestion for the user interface of the train schedule to accomplish my proposal is straightforward, though it depends on the preferred approach:
- If this proposal were to be implemented such that each stop in the schedule may individually be set to skip if the conditions are already met, I suggest that shift-clicking or ctrl-clicking on the play/pause/closed button to the left of each station name either replaces the play icon with a different icon, or adds that icon in the corner of that button, that icon being the "track skip" icon (a play icon that has a vertical bar intersecting it perpendicular to the rightmost tip of it, in keeping with the theme of using media icons to represent these states). This skip setting may alternatively be placed as a separate button to the right side of the train stop name in the schedule, just to the left of the delete button. I personally would prefer this implementation, since it allows for further granularity on train scheduling, though I can understand this being a bit visually busy and potentially unintuitive.
- If this proposal were to instead be implemented such that the train either always does skip checks or not at all, this setting may instead be moved to a toggle switch in the same bar as the "Automatic/Manual" switch, denoted by something like "Skip stops/Don't skip stops", or using media icons akin to the ones present in the buttons next to the station names, with hovertext clarifying the toggle switch.
Unskippable Stations:
There are certain wait conditions that the train cannot already meet from all the way at its departure station, i.e., time passed, inactivity, and circuit
condition. This, too, poses a user interface issue, though I do have suggestions on approaching this:
- For the per-station implementation (the former), the track skip icon may be crossed out or otherwise unselectable, with either hovertext clarifying which of the three wait conditions are preventing it from being selected, the wait condition having a similar crossed-out track skip symbol next to it denoting that it is explicitly preventing the station from being skipped, or both.
- For the per-train implementation (the latter), simply having the crossed-out track skip symbol next to the corresponding wait condition, the train stop name, or both, would suffice.
Conclusion:
This may very well all be null and void, depending on plans already laid out for trains for 1.2 and onward, but the ability to significantly extend the functionality of trains using minimalist approaches has proven to both be popular and powerful with the addition of train limits for train stops, and I imagine this skip functionality or something like it would produce a similar effect, in being able to have prioritization for train stops without resorting to either clunky, incomplete circuit approaches or mods that may either extend the scope of trains far beyond what is necessary to sufficiently manage such a case or are otherwise unavailable in a multiplayer setting.