-
Notifications
You must be signed in to change notification settings - Fork 4
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
The temporary waypoints from FindLocation will prefer to connect to an unreachable edge over a reachable edge, so long as it is closer #82
Comments
Hey, thanks for reaching out. I haven't stumbled across this issue since I run extensive tests on my hogwarts map and its a single connected graph, so usually there always is a shortest way. The way I programmed it is rather simple, I have an injector that adds external locations like player location or target location via temporary node to the nearest edge in a 90° angle, like you noticed. And then just starts the usual navigation process. The navigation algorithm is a modification of the dijkstra algorithm, which finds the shortest path to any nodes on the graph. To programm a solution for your specific case, I would need to find the closest point on any edge to the target location to be 100% correct or if I just wanted to approach the optimal solution find the nearest node and check its neighbouring edges and if sections of them are even closer to the target than the node. And then I'd check if the target is within reach from that point on. From a users perspective, this would make more sense. So I'll leave this issue open to track progress on an implementation for "findlocation":
I'll cache the point edge distance results from step one to reuse in step 4, so there won't be a big performance impact |
changed my mind.
|
Now the final mechanism connects external nodes to ALL islands of the graph if the nearest edge is nearer than the configured min distance. It makes the most sense but doesn't mean there is always a way. Like you can see in the image, only the center path is valid, but if the island of the centerpath doesn't provide a connection from its start node entry point to the target node entry point (due to directed edges), it will not find a possible way of course. Which is intended behaviour. In the end, the graph should do most desicion and the entry points should only help to connect external nodes into the graph in the most fitting way. |
Left to do: regression that makes the playernode no longer a grouped node, hence not rendering particles from player position on but from first graph node. |
I tried out the fix, and in the case that I described it seems to work great! Regarding the islands with directed edges: I tried out a case similar to my example above, but where the "second island" is connected to the main island via a directed edge. This causes an uncaught error to occur. I suspect that this is because the two groups are treated as being a part of the same island, so the 'end' node only connects to the unreachable part of the island
|
NavigationLocation start = route.getStart();
NavigationLocation end = route.getEnd().stream().filter(l -> l.getNode().equals(path.getPath().get(path.getPath().size() - 1))).findAny().orElseThrow(); The exception is being thrown here in the second line. I suppose from I only wonder how you manged to obtain a path with 0 nodes. It should either respond with NoPathFoundException or a valid path. I'll try some different setups to reproduce but maybe I'd need you to create a minimal example or send me your node database if thats fine. |
I'll happily send you my testing database after work if needed. The steps to reproduce were as follows: Create a line of points from A to B, where point B is connected via a directed edge (in the direction of A) Go to point A Use findlocation to navigate to coordinates that are on the opposite side of point B |
I have attached my pathfinder plugin folder, including a recent dump. This is a very simple test setup, where the bug can be triggered by standing on 5539 60 4902 and navigating to 5556 59 4848 (or any location that is behind directed segment) |
Thanks a lot, I successfully reproduced the error! |
Okay so the exception now throws like it should, because the player and target connect correclty to the graph and the graph does not provide a valid path from player to target. |
I'm happy to hear that you had progress! To me, the ideal solution would be that if a part of an island B cannot be reached from the players current location on part A, then that part is treated as a different island entirely. So it would either handle them as island A and island B, or as island A and island AB If I understand your algorithms correctly, then this would lead to the target connecting to both parts of the split island (provided that they are both within range). It would then get as close as possible on island A and do the remainder with a temporary line, ignoring the connection to island B. I'll describe the situation on our server that had us run into this problem: We have one giant island that covers every intended walkable path in the city Flying overtop of the city, we have a branching elytra network, that connects a single point in the sky to 50 flying points across the entire city via directed edges. These flying points are in turn connected to every outdoor point on the ground that is within radius 50 of that point. This works great, and allows our emergency service roleplayers to quickly find any players on the server with their gliders. But a problem occurs when a player who is currently on the ground tries to find a location that is nearest to one of the "elytra network edges". Since these edges are directed downwards at an angle, and can only be reached from the elytra launch point |
Your elytra system sounds pretty exciting! You're right about the algorithm, it should work that way. I'll change it. Thanks for having a close look at how things work and discussing with me how to improve. This is pretty much the first time I am having an indepth conversation about what I coded in the plugin and the feedback is really appreciated |
So the last commit solves the issue with correctness in mind. I will work on these two things next week I am without internet for the next 9 days |
So the per edge connection fixed the scalability issue. The algorithm simply connects the player and the target to each edge that intersects with the sphere of configured radius around them. All those new edges to connect to the intersecting edges have a much higher weight, which will motivate the path finding algorithm to not use these temporary edges a lot and instead get on the actual graph asap. Your scenario would work fine because it will try to navigate across the dead end, fail and try another edge. |
We've been running into some problems where specific coordinates could not be reached via findlocation. After a lot of digging and testing, I finally understand why.
I was under the impression that the FindLocation command would bring you as close to the coordinates as possible, and then connect the remainder via a temporary edge. But the way that it's done right now is the opposite: It will connect the temporary node to the nearest point along an existing edge, and then try to bring you to that connection. The problem is, this is not always the shortest route, or even a possible route.
Example screenshot:
If I'm at the lapis block and I try to navigate to the redstone block's coordinates, then that navigation will fail regardless of my distance setting. Because the redstone block will connect to the emerald line, and then the navigator concludes that navigation is impossible because the emerald line cannot be reached from the lapis line.
This is the case even when distance settings would have allowed the redstone block to connect to the lapis line directly.
I'm not sure what the most elegant solution to this problem is, or even whether a solution is desired. But this is the nature of our problem.
The text was updated successfully, but these errors were encountered: