Pathfinding API
Posted: Sun Jan 15, 2017 11:56 am
I would like the ability to make use of factorio's internal pathfinding api. Currently I am spawning an invisible unit and using it's trail to follow a path but there are a number of issues with that approach that I won't go in to.
Factorio already has a powerful pathfinder so it would be nice to expose it's functionality. Below are some thoughts on a possible way to do that but whatever fits best with the current system should be fine providing it's not specifically tied to unit entities. Part of the idea behind this is that you could use it to find paths for vehicles, characters, routes for transport belt, etc.
LuaSurface or LuaForce both seem like suitable places to expose the pathfinder.
The Pathfinder should make use of the existing path caching systems so any data passed in to the request should match that format. I don't know what that format is, but I it looks like it does recognise the differences between unit size and unit collision masks, so I'd imagine the function would wither required a collision_box and collision_mask, or would require a prototype name instead?
So something like:
surface.pathfinder_request_path{force=LuaForce, collision_box={{-0.49,-0.49},{0.49,0.49}}, collision_mask={"water-tile", "object-layer"}, start_position={x=0,y=0}, target_position={x=100,y=100}}
or
force.pathfinder_request_path{surface=LuaSurface, name="big-biter", start_position={x=0,y=0}, target_position={x=100,y=100}}
Expected responses would be
{ request={the data that made the request including the tick the request was made}, complete = bool(has the process finished), path={list of tiles from start to finish or nil}, valid=bool(only true if a path was found), failed=(nil if pending, string with either "timeout" or "impossible" if failed), pathfinding_started_tick=int(the tick the path was started or nil), pathfinding_ended_tick=int(the tick the path was found or failed or nil)}
The assumption would be that when you first make the request you get a response back with complete=false and maybe pathfinding_started_tick=nil so the pathfinder is busy and has not started yet. If you make the same request a few ticks later then if the pathfinder has found a path for that request it would return a response with the path. An alternative could be to have an on_path_found event instead?
For performance might also be necessary to have a required accuracy in the system to allow or disallow paths from nearby areas to use the same path cache.
Factorio already has a powerful pathfinder so it would be nice to expose it's functionality. Below are some thoughts on a possible way to do that but whatever fits best with the current system should be fine providing it's not specifically tied to unit entities. Part of the idea behind this is that you could use it to find paths for vehicles, characters, routes for transport belt, etc.
LuaSurface or LuaForce both seem like suitable places to expose the pathfinder.
The Pathfinder should make use of the existing path caching systems so any data passed in to the request should match that format. I don't know what that format is, but I it looks like it does recognise the differences between unit size and unit collision masks, so I'd imagine the function would wither required a collision_box and collision_mask, or would require a prototype name instead?
So something like:
surface.pathfinder_request_path{force=LuaForce, collision_box={{-0.49,-0.49},{0.49,0.49}}, collision_mask={"water-tile", "object-layer"}, start_position={x=0,y=0}, target_position={x=100,y=100}}
or
force.pathfinder_request_path{surface=LuaSurface, name="big-biter", start_position={x=0,y=0}, target_position={x=100,y=100}}
Expected responses would be
{ request={the data that made the request including the tick the request was made}, complete = bool(has the process finished), path={list of tiles from start to finish or nil}, valid=bool(only true if a path was found), failed=(nil if pending, string with either "timeout" or "impossible" if failed), pathfinding_started_tick=int(the tick the path was started or nil), pathfinding_ended_tick=int(the tick the path was found or failed or nil)}
The assumption would be that when you first make the request you get a response back with complete=false and maybe pathfinding_started_tick=nil so the pathfinder is busy and has not started yet. If you make the same request a few ticks later then if the pathfinder has found a path for that request it would return a response with the path. An alternative could be to have an on_path_found event instead?
For performance might also be necessary to have a required accuracy in the system to allow or disallow paths from nearby areas to use the same path cache.