Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor pathfinding. #75945

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

CLIDragon
Copy link
Contributor

@CLIDragon CLIDragon commented Aug 25, 2024

Summary

Infrastructure "Refactor the pathfinding code"

Purpose of change

Revive #70274. Though things have changed a bit since that PR,

Describe the solution

Toss out the old monster movement functions will_move_to, can_reach_to, know_danger_at, and replace them with solely can_move_to. Replace the old pathfinding settings with a new bitflag-based class (PathfindingSettings) with a decent amount more functionality. Additionally, the implementation of A* has been moved to a new file a_star.h, and has been sufficiently genericised to use any heuristic, distance function, and transition cost function that we want. It will also make potential future implementations of e.g. Jump Point Search much easier.

RealityBubblePathfindingCache is a direct replacement for the old flat_index, path_data_layer approach. A RBArray is simply an array sized for each element in each map square.

The new logic is generally a superset of the old logic. Things are handled the same way as before, but a few new things are handled more consistently (or at least, compared to Dec 18 2023)).

Code has been updated to include #74322. The current implementation ignores sharp objects when attempting to attack the player instead of adding a heavy cost. I believe that we do try to path around them if possible, but I would have to check .

#74301 and #74373 complicated merging a bit. I believe that we behave appropriately with regards to avoiding objects, but again, it needs to be verified.

There are a decent amount of unnecessary bounds checks e.g. in RealityBubblePathfindingCache::update. I'm not sure how to remove these. Overloading every function with _ib variants doesn't sound appealing.

  • Check whether we attempt to path around dangerous objects when attacking the player. (i.e. mon get_path_avoid)
  • Check if we avoid objects correctly
  • Confirm that current pathing logic is a superset of old logic - i.e. we behave the same in all cases the old logic explicitly handled (except where rendered obsolete or where it is clearly incorrect).
  • Remove horrific type overload to handle raw tripoints.
  • Did I handle the terrain ids correctly?
  • Check other TODOs in code.
  • Check bash_range is implemented correctly (and how does a large max discourage bashing?)
  • Check whether exponential backoff is implemented correctly in monmove.
  • Convert Character::get_pathfinding_settings() to use the new PathfindingSettings.
  • Add @prharvey to co-authors.

Describe alternatives you've considered

Just leave pathfinding code as is. This clearly doesn't work, as evidenced by the long string of PRs making slight changes and many comments expressing confusion at the system. The more I read, the happier I am with @prharvey's approach of just tossing out the old system for monster movement.

All terrain with a cost less than 2 is homogenised. This is the way we've always done things, but I'm not sure if it's appropriate. For example, terrain with a cost of 1 will path the same as terrain with a cost of 1.9. I wonder if we should have more granularity.

Making closest_points_first into an iterator. It turns out making iterators is a nightmare, and the overhead is not really worth the benefit. I might have a go if (when?) cata moves to C++20.

Testing

Not done yet. I at least plan to revive the tests from #70274.

Additional context

I will download astyle at some point soon.

Does anybody know of a diff tool with syntax highlighting that can ignore whitespace changes, brackets, etc? I basically entirely hand-merged this, and at least half of it should have been automatable.

Ping: @nornagon A lot of this touches on code you have directly changed, and I suspect that you probably have a better grasp of the old behaviour than I do.

See pull request for more details.
@github-actions github-actions bot added NPC / Factions NPCs, AI, Speech, Factions, Ownership Map / Mapgen Overmap, Mapgen, Map extras, Map display [C++] Changes (can be) made in C++. Previously named `Code` Monsters Monsters both friendly and unfriendly. Mechanics: Enchantments / Spells Enchantments and spells Code: Infrastructure / Style / Static Analysis Code internal infrastructure and style new contributor labels Aug 25, 2024
@kevingranade
Copy link
Member

I strongly recommend pushing the astar extraction to a seperate PR for quick merging and putting some thought into what other pieces of this can get a similar treatment. This PR has a very high conflict risk and we need to mitigate that.

CLIDragon added a commit to CLIDragon/Cataclysm-DDA that referenced this pull request Aug 26, 2024
Part of CleverRaven#75945. The variant will be used in pathfinding to find the nearest
ramp or stairs without having to enumerate all points.
CLIDragon added a commit to CLIDragon/Cataclysm-DDA that referenced this pull request Aug 26, 2024
Part of CleverRaven#75945. The variant will be used in pathfinding to find the nearest
ramp or stairs without having to enumerate all points.
@CLIDragon
Copy link
Contributor Author

Unfortunately the A* algorithm is probably the hardest piece of code to reuse. The current algorithm is deeply integrated with the current cache and pathfinding settings, and the new algorithm, while decently agnostic, is not designed to work with the old system in any way. It would require a new distance metric, heuristic function, cost function, and neighbour function designed to work with the old system.

Instead, I should be able to separate out the new pathfinding settings (which will have the advantage of reducing a decent amount of noise) and the new cache system into separate pull requests.

@kevingranade
Copy link
Member

Ok sure my focus is on splitting where possible, not too bothered about which pieces are best for doing that and you're in a better position to decide on that I think.

CLIDragon added a commit to CLIDragon/Cataclysm-DDA that referenced this pull request Aug 29, 2024
Part of CleverRaven#75945. The additional flags aren't presently used as they are
intended to be part of a new pathfinding implementation.
CLIDragon added a commit to CLIDragon/Cataclysm-DDA that referenced this pull request Aug 29, 2024
The current flags do not support all functionalities required (e.g.
whether a piece of terrain is sheltered or unsheltered), and lack
granularity with e.g. GOESUPDOWN requiring extra checks for ramps,
whether it goes up or goes down, and so forth.

Additionally, using a scoped enum is good practice and will hopefully
prevent accidental misuse of the enum type.

Part of CleverRaven#75945. The additional flags aren't presently used as they are
intended to be part of a new pathfinding implementation.
CLIDragon added a commit to CLIDragon/Cataclysm-DDA that referenced this pull request Aug 29, 2024
The current flags do not support all functionalities required (e.g.
whether a piece of terrain is sheltered or unsheltered), and lack
granularity with e.g. GOESUPDOWN requiring extra checks for ramps,
whether it goes up or goes down, and so forth.

Additionally, using a scoped enum is good practice and will hopefully
prevent accidental misuse of the enum type.

Part of CleverRaven#75945. The additional flags aren't presently used as they are
intended to be part of a new pathfinding implementation.
CLIDragon added a commit to CLIDragon/Cataclysm-DDA that referenced this pull request Aug 30, 2024
Part of CleverRaven#75945. The variant will be used in pathfinding to find the nearest
ramp or stairs without having to enumerate all points.

* Make find_point_closest_first generic over point and tripoint.
* Extract common code between closest_points_first variants
CLIDragon added a commit to CLIDragon/Cataclysm-DDA that referenced this pull request Sep 2, 2024
The current flags do not support all functionalities required (e.g.
whether a piece of terrain is sheltered or unsheltered), and lack
granularity with e.g. GOESUPDOWN requiring extra checks for ramps,
whether it goes up or goes down, and so forth.

Additionally, using a scoped enum is good practice and will hopefully
prevent accidental misuse of the enum type.

Part of CleverRaven#75945. The additional flags aren't presently used as they are
intended to be part of a new pathfinding implementation.

Co-authored-by: prharvey <[email protected]>
@CLIDragon
Copy link
Contributor Author

Including a list of issues here for future reference.
#73674. #74200. #74433 (for the grievances with the current travel system). #75009 (what exactly is the intended behaviour? How much punishment are monsters willing to accept to get to the player?). #72465. #52972.

CLIDragon added a commit to CLIDragon/Cataclysm-DDA that referenced this pull request Sep 5, 2024
Part of CleverRaven#75945. The variant will be used in pathfinding to find the nearest
ramp or stairs without having to enumerate all points.

* Make find_point_closest_first generic over point and tripoint.
* Extract common code between closest_points_first variants
CLIDragon added a commit to CLIDragon/Cataclysm-DDA that referenced this pull request Sep 5, 2024
The current flags do not support all functionalities required (e.g.
whether a piece of terrain is sheltered or unsheltered), and lack
granularity with e.g. GOESUPDOWN requiring extra checks for ramps,
whether it goes up or goes down, and so forth.

Additionally, using a scoped enum is good practice and will hopefully
prevent accidental misuse of the enum type.

Part of CleverRaven#75945. The additional flags aren't presently used as they are
intended to be part of a new pathfinding implementation.

Co-authored-by: prharvey <[email protected]>
@CLIDragon
Copy link
Contributor Author

#75401. #73269.

@Brambor
Copy link
Contributor

Brambor commented Sep 11, 2024

#75401. #73269.

If ref is in a list, it expands:

It's much more readable with a phone, where you cannot hover over a link.

@CLIDragon
Copy link
Contributor Author

If ref is in a list, it expands:
Good to know, though I'll probably leave them unexpanded as I don't want to clutter the comments too much.

CLIDragon added a commit to CLIDragon/Cataclysm-DDA that referenced this pull request Nov 7, 2024
Part of CleverRaven#75945. The variant will be used in pathfinding to find the nearest
ramp or stairs without having to enumerate all points.

* Make find_point_closest_first generic over point and tripoint.
* Extract common code between closest_points_first variants
CLIDragon added a commit to CLIDragon/Cataclysm-DDA that referenced this pull request Nov 9, 2024
Part of CleverRaven#75945. The variant will be used in pathfinding to find the nearest
ramp or stairs without having to enumerate all points.

* Make find_point_closest_first generic over point and tripoint.
* Extract common code between closest_points_first variants

Co-authored-by: prharvey <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[C++] Changes (can be) made in C++. Previously named `Code` Code: Infrastructure / Style / Static Analysis Code internal infrastructure and style Map / Mapgen Overmap, Mapgen, Map extras, Map display Mechanics: Enchantments / Spells Enchantments and spells Monsters Monsters both friendly and unfriendly. new contributor NPC / Factions NPCs, AI, Speech, Factions, Ownership
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants