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

Add a partial path return option for AStar #88047

Merged

Conversation

theashtronaut
Copy link
Contributor

@theashtronaut theashtronaut commented Feb 7, 2024

This change should address and close godotengine/godot-proposals#277 by adding an optional parameter to get_point_path and get_id_path for AStar2D, AStar3D, and AStarGrid2D that when true will return the partial path instead of an empty path.

By having this be an optional parameter this should not have any compatibility breakages, and for those who rely on having an empty path returned if no complete path is available will not have their code affected. Those who want/need partial paths however can simply pass true in to get them.

Note: This will not return a partial path to a location not in the AStar point list, the destination point still has to be a point. This is especially helpful for games where points may become disconnected due to other points being disabled during play while still permitting a path that gets close to the destination point.

I also went ahead and updated the xml docs for the affected classes to mention this new possibility. If I understand correctly the Godot docs page uses these to auto-generated so a doc update for that shouldn't be necessarily.

The original implementation was modified from KnightNine's branch located here, however there were a bunch of other changes for other features in that branch and I wanted to only address the original proposal issue. They used a separate method as suggested in the proposal issue, but I felt that an optional parameter made more sense and to prevent having extra data structures to store the partial paths.

Example

Download: astar_partial_test.zip

I used the navigation2d demo project to test AStarGrid2D. I tested AStar3D using a personal project and I cannot share the code of that, but it behaved as expected. I have included the modified demo project for ease of testing. I did not have time to modify this demo project to explicitly showcase it working with AStar2/3D.

Screenshot_20240206_185730
This is the test using the attached demo project. The E tile was the destination tile. This tile is a part of the AStarGrid2D's points, but is surrounded by impassible/disabled points isolating it. The path gets as close as it can.

Screenshot_20240206_194638
This example shows the AStar3D test. As movement costs are not 1 for all, I added a few annotations. The infinity over the black tile with brown objects on it is a tile that is not in the map. The tiles with a 2 on them have a cost of 2. The blue tile with the red line was the tile selected. This tile is in the AStar point list, but is not connected to any points. The white arrows follow the path generated by AStar. As you can see it gets close to the target tile. as expected.

3.x

I am uncertain on compatibility for 3.x as I do not use it nor did I test this. My brief cursory glance shows multiple commits to the AStar classes since 3.x, so it is possible due to this it cannot be cherry-picked, but I really admit I am uncertain on how that process works.

@theashtronaut theashtronaut requested review from a team as code owners February 7, 2024 05:07
@theashtronaut
Copy link
Contributor Author

When running the CI checks in my fork's branch, it failed the GDExtension compatibility

Error: Validate extension JSON: Error: Field 'classes/AStar2D/methods/get_id_path/arguments': size changed value in new API, from 2 to 3.
Validate extension JSON: Error: Field 'classes/AStar2D/methods/get_point_path/arguments': size changed value in new API, from 2 to 3.
Validate extension JSON: Error: Field 'classes/AStar3D/methods/get_id_path/arguments': size changed value in new API, from 2 to 3.
Validate extension JSON: Error: Field 'classes/AStar3D/methods/get_point_path/arguments': size changed value in new API, from 2 to 3.
Validate extension JSON: Error: Field 'classes/AStarGrid2D/methods/get_id_path/arguments': size changed value in new API, from 2 to 3.
Validate extension JSON: Error: Field 'classes/AStarGrid2D/methods/get_point_path/arguments': size changed value in new API, from 2 to 3.
Validate extension JSON: Error: Hash changed for 'classes/AStar2D/methods/get_id_path', from CAEE4B7E to BAEE9BE0. This means that the function has changed and no compatibility function was provided.
Validate extension JSON: Error: Hash changed for 'classes/AStar2D/methods/get_point_path', from 10C941DF to CC4B5A58. This means that the function has changed and no compatibility function was provided.
Validate extension JSON: Error: Hash changed for 'classes/AStar3D/methods/get_id_path', from CAEE4B7E to BAEE9BE0. This means that the function has changed and no compatibility function was provided.
Validate extension JSON: Error: Hash changed for 'classes/AStar3D/methods/get_point_path', from 34803E1E to 5D2437D3. This means that the function has changed and no compatibility function was provided.
Validate extension JSON: Error: Hash changed for 'classes/AStarGrid2D/methods/get_id_path', from 7693B298 to 72546031. This means that the function has changed and no compatibility function was provided.
Validate extension JSON: Error: Hash changed for 'classes/AStarGrid2D/methods/get_point_path', from 292643AB to 61DDCC3D. This means that the function has changed and no compatibility function was provided.

I am not sure how to fix this, I thought GDExtension would use the modified ClassDB bindings, but I don't really know how GDExtension works. Advice on how to resolve that would be greatly appreciated!

@dalexeev
Copy link
Member

dalexeev commented Feb 7, 2024

I am not sure how to fix this, I thought GDExtension would use the modified ClassDB bindings, but I don't really know how GDExtension works. Advice on how to resolve that would be greatly appreciated!

See #80410 for example. You need to add .compat.inc file, include it in .cpp, add some code to .h, and add Validate extension JSON: Error: Field... lines to misc/extension_api_validation/4.2-stable.expected file. Compat.cs no longer needs to add compatibility methods.

doc/classes/AStar2D.xml Outdated Show resolved Hide resolved
doc/classes/AStar2D.xml Outdated Show resolved Hide resolved
doc/classes/AStar2D.xml Outdated Show resolved Hide resolved
core/math/a_star.h Outdated Show resolved Hide resolved
core/math/a_star.h Outdated Show resolved Hide resolved
core/math/a_star.h Outdated Show resolved Hide resolved
core/math/a_star_grid_2d.h Outdated Show resolved Hide resolved
core/math/a_star.cpp Outdated Show resolved Hide resolved
core/math/a_star.cpp Outdated Show resolved Hide resolved
core/math/a_star.cpp Outdated Show resolved Hide resolved
core/math/a_star_grid_2d.cpp Outdated Show resolved Hide resolved
core/math/a_star_grid_2d.cpp Outdated Show resolved Hide resolved
@smix8
Copy link
Contributor

smix8 commented Feb 7, 2024

Premature approval for the feature as this has been requested many times.

Can't say much about the technical detail or style as the AStar classes are not really my habitat.

I would even go as far and do a small compatibility break here on this and make it the default to always return the partial path if the target can not be reached. That is what the majority of (new) users expect and is also how the NavigationServer path queries all behave. That the path returned empty when the target could not be reached always irritated and annoyed people.

@theashtronaut theashtronaut requested review from a team as code owners February 7, 2024 21:09
@theashtronaut
Copy link
Contributor Author

Many thanks to everyone for the suggestions regarding naming/style! I've made those changes.

I am not sure how to fix this, I thought GDExtension would use the modified ClassDB bindings, but I don't really know how GDExtension works. Advice on how to resolve that would be greatly appreciated!

See #80410 for example. You need to add .compat.inc file, include it in .cpp, add some code to .h, and add Validate extension JSON: Error: Field... lines to misc/extension_api_validation/4.2-stable.expected file. Compat.cs no longer needs to add compatibility methods.

Thank you! I think I've done this correctly. The validation script no longer returned any errors related to these classes when I ran it locally at least.

Premature approval for the feature as this has been requested many times.

Can't say much about the technical detail or style as the AStar classes are not really my habitat.

I would even go as far and do a small compatibility break here on this and make it the default to always return the partial path if the target can not be reached. That is what the majority of (new) users expect and is also how the NavigationServer path queries all behave. That the path returned empty when the target could not be reached always irritated and annoyed people.

If others agree I can set the default to true! I just defaulted to the most compatible option to start with.

@theashtronaut theashtronaut force-pushed the add_partial_return_astar branch 5 times, most recently from 8d530a7 to 219286a Compare February 13, 2024 01:39
@Bromeon
Copy link
Contributor

Bromeon commented Feb 13, 2024

I would even go as far and do a small compatibility break here on this and make it the default to always return the partial path if the target can not be reached. That is what the majority of (new) users expect and is also how the NavigationServer path queries all behave. That the path returned empty when the target could not be reached always irritated and annoyed people.

"Small compatibility break" is an understatement. This will break success checks for all existing AStar{2D|3D}::get_{id|point}_path() calls and thus affect the majority of pathfinding code using those APIs.

Checking for emptiness was the recommended approach in Godot 4.0, 4.1 and 4.2. I don't think changing this to accomodate for new users is a good idea. Besides, we don't even know how many people would be irritated/annoyed if a simple emptiness check would now become a "either empty or last path is destination" check.

@theashtronaut theashtronaut force-pushed the add_partial_return_astar branch from 219286a to 60a2578 Compare February 19, 2024 23:54
@theashtronaut theashtronaut force-pushed the add_partial_return_astar branch 3 times, most recently from c7f3563 to 2bc15d7 Compare February 25, 2024 20:11
@theashtronaut theashtronaut force-pushed the add_partial_return_astar branch 2 times, most recently from 0bbba5f to 583ba15 Compare February 27, 2024 21:51
@theashtronaut
Copy link
Contributor Author

Just because I'm a little unclear on Godot dev cycles, is 4.3 "feature frozen" and this wouldn't be merged until 4.4 begins (and thus 4.3 is released)?

Mainly checking to know if I should keep clearing the conflicts with the 4.2-stable.expected file every few days to keep it ready to merge, or if the expectation that it's gonna wait until 4.4 then I can leave it for a while.

@akien-mga
Copy link
Member

akien-mga commented Mar 2, 2024

There's still some time for 4.3 features, we're not in feature freeze yet. The feature freeze will start with 4.3 beta 1, probably in a month.

But you don't need to rebase frequently to solve the conflicts on that compat file, first we need some maintainers familiar with that feature to approve the changes. Then you can do a final rebase to make it merge ready.

Copy link
Contributor

@smix8 smix8 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the navigation feature. Users ask regularly about a partial path option with the astar classes to be added. Tested and at least from my view it works as expected.

Not sure about code or compatibility detail. Others need to check that part.

core/math/a_star.cpp Outdated Show resolved Hide resolved
core/math/a_star.cpp Outdated Show resolved Hide resolved
core/math/a_star.cpp Outdated Show resolved Hide resolved
core/math/a_star.cpp Outdated Show resolved Hide resolved
core/math/a_star_grid_2d.cpp Outdated Show resolved Hide resolved
core/math/a_star_grid_2d.cpp Outdated Show resolved Hide resolved
@akien-mga akien-mga modified the milestones: 4.x, 4.3 Apr 3, 2024
@theashtronaut theashtronaut force-pushed the add_partial_return_astar branch from 583ba15 to 51e529e Compare April 3, 2024 22:26
* AStar2D, AStar3D and AStarGrid2D now can return a partial path if the destination point isn't reachable but still in the map. This option is available for both get_point_path and get_id_path
@theashtronaut theashtronaut force-pushed the add_partial_return_astar branch from 51e529e to aa1bbe1 Compare April 4, 2024 05:27
@akien-mga akien-mga merged commit a1ab287 into godotengine:master Apr 4, 2024
16 checks passed
@akien-mga
Copy link
Member

Thanks! And congrats for your first merged Godot contribution 🎉

@akien-mga akien-mga changed the title Add a partial path return option for astar Add a partial path return option for AStar May 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add an AStar function to get partial path if end point is unreachable
7 participants