UchuServer / Uchu

LEGO Universe server written in C#
GNU Affero General Public License v3.0
85 stars 20 forks source link

Replace Pathfinding (Incomplete) #330

Open TheNexusAvenger opened 2 years ago

TheNexusAvenger commented 2 years ago

This pull request is incomplete and covers a feature I have abandoned due to a lack of motivation.

This pull request attempts to replace the current AI movement system. At the moment, the system applies the A* algorithm on a grid of points generated from the heightmap, which results in a huge grid with tens of thousands to hundreds of thousands of nodes. Using a system simpler to navigation meshes is the obvious replacement for the existing solution.

Theory

The theory of the solution proposed in the pull request uses the idea of generating bounding shapes from the heightmap for the walkable areas and determining paths from there. Since the LEGO Universe maps are relatively flat for where NPCs can traverse, the math for the paths is 2D and the heightmap can be referenced for the height component when needed. Even if this doesn't completely match what the game uses due to objects, this is still a decent replacement for the existing system.

Shape Parsing

This is assumed to be completely implemented at this point. Issues may exist.

Parsing of the bounding shapes of the walkable area is done in several steps and uses the heightmap as the only source of truth. Caching is done of the shape parsing since results can take a very long time to generate. For releases, we would want to pre-calculate them and bundle them with the releases.

Determine Walkable Heightmap Graph

The first step follows the primary step of the existing solution: taking the heightmap and creating a graph of the positions that can be walked to from each other. To do this, a 2D grid is made of the heightmap points and each point is connected if the distance between them is a certain amount. This makes it so points that are considered too steep to traverse aren't connected. For lack of a better picture, this is an example of Avant Gardens rendered in Roblox that I took before: image

Create Bounding Shapes

From this graph of connected nodes, the bounding shapes are created. After several attempts, the solution that was found to is to convert the graph into a set of small shapes (triangles and squares) and merge them. The process for this is very slow and requires being run in parallel. Otherwise, parsing can take 10s of minutes. To get around this, a merging technic similar to "merge sort" is done in parallel. Below is a small example illustrated in Roblox with the initial graph step. image

Optimize Bounding Shapes

To optimize the bounding shapes, all that needs to be done is to merge lines that are collinear. This reduces the total lines each shape has without changing the geometry, making any computations faster. image

Store The Shapes By Containment

The last step that is done is to store the shapes in order by how they are contained. In order to reduce computations for pathfinding, the only relevant shapes for a given point to path find around is the inner-most shape that contains the point and the shapes that are directly contained by that shape. Creating the hierarchy, or spanning tree, makes that easier.

Pathfinding

This has not been implemented.

Once the bounding shapes are generated or cached for a zone, the assumed process for an NPC is to find the inner-most bounding shape for them and then path find to targets using 1 of 3 options:

  1. If the target point is out of the shape, no path exists.
  2. If a direct path exists inside the shape, use the direct path from the start to the target.
  3. If a direct path doesn't exist inside the shape, perform a pathfinding algorithm (like A*) on the points of the containing and inner shapes. This is outlined on a website I found when researching this.

This gives the X and Z positions to use. The Y position is then reversed from the heightmap given the X and Z positions.

Remaining Work

It is believed that a majority of the work is done and not a lot is required to finish it. However, there are still several tasks left: