Factorio-Access / FactorioAccess

An accessibility mod for the video game Factorio, making the game accessible to the blind and visually impaired.
Other
20 stars 9 forks source link

add a tool to find end rails and stations which are reachable from a current rail #245

Open ahicks92 opened 1 month ago

ahicks92 commented 1 month ago

This is useful for testing junctions and other parts of rail networks. For example if it's 4-way you'd better be able to find the expected rails in all directions. We can list them off by distance. It can also tell one about mistakes merging tracks and other such things by highlighting that there are unexpected reachable end rails.

The intent would also be to account for signals.

This is easier than it sounds. End rails are always rails with only zero or one connection. The API gives us segments and their intersections and so on. One need only crawl blocks as provided by the API recursively, counting their lengths and guestimating when the distance threshold is reached. The mod will still have to run calculations to figure out how to present the rail because we do a bit extra but getting all end rails or stations within a specific radius on a specific rail network efficiently is doable.

The range probably needs to depend on how efficient we can get. There's really no need to stop as long as they're sorted well. A breadth-first search is O(n) so it may be able to go quite far as long as we don't push on trying to use the full pathfinder.

Note that the rail segments can be modeled as nodes in a directed graph (or edges, but nodes is useful here) where the direction of each edge is exactly determined by the signals separating the two segments. There's two ways to do it: at the rail level (slow but simple) or the block level (fast but maybe very complicated).

It's also worth noting that a problem limited to only the realm of entities with owners can rely on unit numbers for unique entity identification even across ticks. Unlike the scanner Lua's data structures alone are probably sufficient--but I'll drop the note here in case someone who doesn't know about unit_number tries. That's how one can build a set of seen rails.

LevFendi commented 1 month ago

This was a feature planned long ago so good to have it formalized. You can already query what is "up and down" a selected rail. That function can be re-used here to find what comes next in every direction from this fork or junction.

As for iterating along until the actual end rail, that one is a little annoying, also was planned long ago but i have not had the patience for it.

The issue is that pretty much anything like a rail signal in the opposite direction marks the end of a rail segment. You need to select the right neighbor in the right direction every time. Not unsolvable but very confusing.

ahicks92 commented 1 month ago

The API tells us that information if you work at the segment level rather than the individual rail level because you can ask it for the connections. I am not 100% sure that it makes things as trivial as I think around figuring out if any given end is an entrance, exit, or both. See (on LuaEntity) get_rail_segment_entity, get_rail_segment_end and the bunch of others around that spot on the page, sadly not all with the word rail in the name.

The thing is though that by junction I mean that 100x100 thing I showed you, not just a fork. I'm asking for the general case. I don't consider the specific case very interesting. Without something like this it's a nightmare to debug that thing. I'm sort of tired of test drives. You've seen what I'm doing, you can no doubt imagine why.

LevFendi commented 1 month ago

For the large junction debug job, it may be easier to add support for an independent function checking if there is a valid rail path between rail A and rail B.

ahicks92 commented 4 weeks ago

Yes and no. Such a tool with an 8-exit junction would require checking 64 pairs. I think it's useful but running it is much different than just getting a list. 8 clicks versus 64 clicks (or possibly 128 to select both rails for that matter). No thanks.

Admittedly the menu still requires checking 64 values but at least it doesn't require setting a tool up one by one.

If I was going to add and use such a tool then I would do it for stations and I would include whether the path is bidirectional, since 99% of the test drives are "is this path bidirectional". That'd cut down a lot of time right there even before we discuss proper scheduling and management UIs.