Skip to content

[game] Reimplement pathfinding - #310

Open
modawan wants to merge 2 commits into
masterfrom
pathfinder
Open

[game] Reimplement pathfinding#310
modawan wants to merge 2 commits into
masterfrom
pathfinder

Conversation

@modawan

@modawan modawan commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Pathfinding is implemented as a collection of algorithms:

  1. Global pathfinding algorithm builds a coarse-grained path from A to B as a
    sequence of walkmesh faces. It ensures that a path exists, but makes no
    effort to make it "natural" from the player perspective.

  2. Funnel algorithm takes a sequence of faces from the global pathfinding,
    and attempts to make a straight-line path through it.

  3. Steering behaviour takes a direction from the funnel algorithm, and turns
    it into a "driving" force. It then calculates and combines other forces:

    • "keepout" force to steer away from borders and corners
    • "stuck" force to recover from pathfinding failures.

The combined force is then integrated to smooth changes of direction and make
the path more natural.

Omissions:

  1. Dynamic objects (creatures) are not handled. Each creature has a "personal
    space" radius that must be taken into account for pathfinding.

  2. Static objects that do not have a carve-out for them in the room walkmesh
    are not reflected in the Uniwalk yet. Each object has it is own
    "non-walkable" mesh, which must be subtracted from the room mesh.

BWM format stores vertices, faces, edges as separare arrays,
effectively a structure of arrays. Before this patch we used to
transform this into an array of structures (struct Face) and keep only
one array in the Walkmesh.

This approach had several problems:

1. Vertices are duplicated. Each vertex is a vec3, and there are 1.5x
more faces than vertices, because most faces have adjecent faces.

2. It is more difficult to find adjecent faces, without keeping
original vector indices. We have to check distance between vertices to
find if it is the same vertex. With indices it is enough to check if
indices are the same.

The patch also updates return value of raycast function. They used to
return a nullable pointer to the face and distance as an output
parameter. Now they return a struct with an index of the face that the
ray intersects, distance from the origin point to the intersection,
and an error code if there is no intersection.
Pathfinding is implemented as a collection of algorithms:

1. Global pathfinding algorithm builds a coarse-grained path from A to B as a
sequence of walkmesh faces. It ensures that a path exists, but makes no
effort to make it "natural" from the player perspective.

2. Funnel algorithm takes a sequence of faces from the global pathfinding,
and attempts to make a straight-line path through it.

3. Steering behaviour takes a direction from the funnel algorithm, and turns
   it into a "driving" force. It then calculates and combines other forces:

   - "keepout" force to steer away from borders and corners
   - "stuck" force to recover from pathfinding failures.

  The combined force is then integrated to smooth changes of direction and make
  the path more natural.

Omissions:

1. Dynamic objects (creatures) are not handled. Each creature has a "personal
space" radius that must be taken into account for pathfinding.

2. Static objects that do not have a carve-out for them in the room walkmesh
   are not reflected in the Uniwalk yet. Each object has it is own
   "non-walkable" mesh, which must be subtracted from the room mesh.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant