Question regarding LuaSurface::request_path

Place to get help with not working mods / modding interface.
Post Reply
Pi-C
Smart Inserter
Smart Inserter
Posts: 1703
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Question regarding LuaSurface::request_path

Post by Pi-C »

Suppose I request a path using

Code: Select all

  local path_request
  local path_args = {
    bounding_box        = bounding_box,
    collision_mask      = vehicle.prototype.collision_mask or {},
    start               = vehicle.position,
    goal                = goal,
    force               = vehicle.force,
    radius              = radius,
    entity_to_ignore    = vehicle,
    can_open_gates      = true,
    pathfind_flags      = {
      allow_destroy_friendly_entities   = false,
      cache                             = false,
      prefer_straight_paths             = true,
      low_priority                      = false,
    },
  }
path_request = vehicle.surface.request_path(path_args)
Let's assume that I get a valid path when defines.events.on_script_path_request_finished is raised. I now know that 'vehicle' can get from vehicle.position to path_args.goal even if there are walled-in areas with gates. However, vehicle is not allowed to open gates and I want to check whether it could still get to that destination. So I request another path:

Code: Select all

path_args.can_open_gates = false
path_request = vehicle.surface.request_path(path_args)
If there are any gates that must be passed to reach path_args.goal, this request will fail and I'll get no path. But now suppose there are no walls and gates between vehicle.position and path_args.goal. I'd expect that this request would also return a valid.

Question: Given that no parameters except for path_args.goal have changed, is there a guarantee that both path requests return the same path iff there are no gates between vehicle.position and path_args.goal?
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5156
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: Question regarding LuaSurface::request_path

Post by Klonan »

Pi-C wrote:
Fri Dec 01, 2023 11:03 am
Question: Given that no parameters except for path_args.goal have changed, is there a guarantee that both path requests return the same path iff there are no gates between vehicle.position and path_args.goal?
There is no guarantee in any part of the pathfinder, especially as it normally takes some ticks to return the path and in that time any number of things could have changed

It is likely the path will be the same, there are caches and deterministic codepaths throughout, but its best to write your mod without relying on it being a certainty

Pi-C
Smart Inserter
Smart Inserter
Posts: 1703
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Question regarding LuaSurface::request_path

Post by Pi-C »

Klonan wrote:
Sat Dec 02, 2023 9:30 am
Pi-C wrote:
Fri Dec 01, 2023 11:03 am
Question: Given that no parameters except for path_args.goal have changed, is there a guarantee that both path requests return the same path iff there are no gates between vehicle.position and path_args.goal?
There is no guarantee in any part of the pathfinder, especially as it normally takes some ticks to return the path and in that time any number of things could have changed
Makes sense. In my own tests, on_path_request_finished was usually raised one or two ticks after the request. But of course, I've run my tests in a mostly empty world with hardly any buildings, so things may be quite different in a big factory where bots may place new obstacles all the time.
It is likely the path will be the same, there are caches and deterministic codepaths throughout, but its best to write your mod without relying on it being a certainty
The mod in question is Autodrive, where cars and spidervehicles can move even without a player inside. Such vehicles may only path through gates if they are equipped with a "gate sensor".

If a vehicle is trying to find a path, there is a problem: LuaSurface::request_path only checks that there is space for the vehicle at the destination, but not the starting point. So we make up to 5 attempts to find a path, teleporting the vehicle to a non-colliding position in an increasing radius around the current vehicle position.

Currently, the first path request is made with path_args.can_open_gates depending on whether or not the vehicle has a gate sensor. If the vehicle has no gate sensor and the request fails, I make one attempt to find a path with can_open_gates enabled, and only if that succeeds, I continue the circle of teleporting the vehicle to another start position and requesting a path with can_open_gates disabled from the new position up to 5 times. Now this approach is not safe because the testrun may fail for other reasons than the destination being unreachable without opening gates.

Requesting all paths with can_open_gates disabled means that the vehicle would be teleported to a new position and request a new path up to 5 times. That's OK when there is a real chance that a path exists, but it is not efficient if vehicle and destination were completely separated by cliffs or water. Therefore, I came up with the idea to always request a path with can_open_gates enabled (up to 5 times). Then, if a path is found and the vehicle has no gate sensor, I'd make one more request with can_open_gates disabled. If this final request failed, I thought it was safe to assume that the path was obstructed by gates, so it would make sense to recommend adding a gate sensor to the vehicle's equipment.

So, what I had in mind is just an optimization: Assuming a vehicle had no gate sensor, the destination could only be pathed to through gates, and the test run with can_open_gates would succeed on the first try, I'd only need one more path request with can_open_gates disabled before giving up, which would save 4 cycles of teleporting and repathing. In the worst case, if there really was no way for the vehicle to get to its destination (confirmed by 5 failed path requests with can_open_gates enabled), I'd still save the final repathing attempt with can_open_gates disabled.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

Post Reply

Return to “Modding help”