AdamK wrote: ↑Wed Feb 24, 2021 6:33 am
Train path finding should not block the game, run in separate thread
I will quote myself here (fff-364):
boskid wrote:One could simply say "make it multithreaded" but there are a lot of technical challenges to solve before this is even possible in order to not cause any issues when running in multiplayer. Basically, to ensure it will still be deterministic.
Trains pathfinder cannot run "anytime in separate thread". If there would be a construction robot placing rail somewhere on the map, if main thread would be in the middle of creating that rail and the pathfinder would run in other thread, then it would be race with 3 possible outcomes: if pathfinder would run fully before, it would not account for that rail, if it would run in parallel with construction robot update it could crash because of transient state inconsistency and if it would run after it would account for that rail which would desync if other clients in MP would get their thread to finish early.
There is lua event `on_train_changed_state` which may fire because of the repath, and because it is a lua event which may touch everything, it cannot run in parallel with anything that depends on the game state (which is basically everything).
AdamK wrote: ↑Wed Feb 24, 2021 6:33 am
1) track should have a property saying: there is a path going through here
That piece already exists and it is used when a rails are destroyed, however there are still checks running for most of the trains because removing rail may cause other changes that affect trains, like it may cause rail blocks to split making some signals to be no longer invalid which may need some paths to be revalidated or recomputed.
AdamK wrote: ↑Wed Feb 24, 2021 6:33 am
2) when new track is build, there is no need to invalidate all paths immediately. It can be delayed and run in separate nonblocking thread
That is also already a thing, however it also has a limited scope: when a rail is created it does not cause all the NO_PATH trains to immediately repath but only schedules those trains to repath within 128 ticks from now (exact tick that train will repath is based on the trainID). In other cases, building a rail may merge 2 rail blocks which will invalidate some rail signals which again needs some revalidations for trains even with a path that does not touch that rail.
AdamK wrote: ↑Wed Feb 24, 2021 6:33 am
3) invalidating path cache could be delayed if there is track related blueprint being built in progress (with a timeout for sure) to not redo/restart everything
each time track is built
There is no such thing as path cache, penalties for different trains will be different (like closed signal will not be considered closed for a train that has a rail block reserved behind the signal), and repath events means that literally there were changes affecting penalties so the cache (if any) would be invalidated anyway. All the pathfinder requests are done on real entities, possibly touching all the rails in the whole rails network (when there is no path, every rail reachable rail has to be touched because it could be the one missing piece to the goal).
There are some micro tweaks, like when you have a rail block that has no trains on it, has no signals anywhere on it (and is not connected to any other blocks, but that is obvious as it has no signals), removing or creating rails in that rail block will not cause any checks and repaths.
In general this topic classifies to "outdated/not implemented"