Skip to content

Commit

Permalink
doc: Document field types in flow field pathfinder.
Browse files Browse the repository at this point in the history
  • Loading branch information
heinezen committed Jul 28, 2024
1 parent f2e8355 commit ad76c8b
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 4 deletions.
5 changes: 2 additions & 3 deletions doc/code/pathfinding/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,12 @@ a path request is made, the main influence on performance is the A\* algorithm.
a limited number of portals, the A\* search should overall be very cheap.

The resulting list of sectors and portals is subsequently used in the low-level flow
field calculations. As a first step, the pathfinder uses its integrator to generate
field calculations. More details can be found in the [field types](field_types.md) document.
As a first step, the pathfinder uses its integrator to generate
a flow field for each identified sector. Generation starts with the target sector
and ends with the start sector. Flow field results are passed through at the cells
of the identified portals to make the flow between sectors seamless.

<!-- TODO: More descriptions of cost/integration/flow field calculations -->

In a second step, the pathfinder follows the movement vectors in the flow fields from
the start cell to the target cell. Waypoints are created for every direction change, so
that game entities can travel in straight lines between them. The list of waypoints
Expand Down
78 changes: 78 additions & 0 deletions doc/code/pathfinding/field_types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Field Types

This document describes the field types used in the flow field pathfinding system.

Most of the descriptions are based on the [*Crowd Pathfinding and Steering Using Flow Field Tiles*](http://www.gameaipro.com/GameAIPro/GameAIPro_Chapter23_Crowd_Pathfinding_and_Steering_Using_Flow_Field_Tiles.pdf) article by Elijah Emerson.

## Cost Field

A cost field is a square grid of cells that record the cost of movement on the location
of each cell. Higher cost values indicate that it is less desirable to move through that cell.
The field is usually initialized at the start of the game and persists for the lifetime of
the entire pathfinding grid. During gameplay, individual cell costs may be altered to reflect
changes in the environment.

Cost values are represented as `uint8_t` (0-255) values. The range of usable cost values
is `1` to `254`. `255` is a special value that represents an impassable cell. `0` is reserved
for initialization and should not be used for flow field calculations.

![Cost Field](images/cost_field.png)

- **green**: minimum cost
- **red**: maximum cost
- **black**: impassable cell

## Integration Field

The integration field is created from a cost field when a path is requested. For a specific
target cell, the integration field stores the accumulated cost of reaching that cell from
every other cell in the field.

Integration values are calculated using a wavefront algorithm. The algorithm starts at the
target cell(s) and propagates outward, updating the integration value of each cell it visits.
The integration value is calculated by adding the cost value of the current cell to the lowest
integration value of the 4 cardinal neighbors. The integration value of the target cell(s) is `0`.

Integration values are represented as `uint16_t` (0-65535) values. The range of usable integration
values is `1` to `65534`. `65535` is a special value that represents an unreachable cell. During
initialization, all cells are set to `65535`.

An additional refinement step in the form of line-of-sight testing may be performed before the
integration values are calculated. This step flags every cell that is in line of sight of the
target cell. This allows for smoother pathing, as game entities can move in a straight line to
the target cell. The algorithm for this step is described in more detail in section 23.6.2
of the [*Crowd Pathfinding and Steering Using Flow Field Tiles*](http://www.gameaipro.com/GameAIPro/GameAIPro_Chapter23_Crowd_Pathfinding_and_Steering_Using_Flow_Field_Tiles.pdf) article.

In addition to the integration values, the integration field also stores flags for each cell:

- `FOUND`: cell has been visited
- `TARGET`: cell is a target cell
- `LOS`: cell is in line of sight of target cell
- `WAVEFRONT_BLOCKED`: cell is blocking line of sight to target cell

![Integration Field](images/integration_field.png)

- **green**: lower integration values
- **purple**: higher integration values
- **black**: unreachable cell

## Flow Field

Creating the flow field is the final step in the flow field calculation. The field
is created from the integration field. Cells in the flow field store the direction to
the neighbor cell with the lowest *integrated* cost. Thus, directions create a "flow"
towards the target cell. Following the directions from anywhere on the field will lead
to the shortest path to the target cell.

Flow field values are represented as `uint8_t` values. The 4 least significant bits are used
to store the direction to the neighbor cell with the lowest integrated cost. Therefore, 8
directions can be represented. The 4 most significant bits are used for flags:
- `PATHABLE`: cell is passable
- `LOS`: cell is in line of sight of target cell
- `TARGET`: cell is a target cell

![Flow Field](images/flow_field.png)

- **white**: line of sight
- **bright/dark grey**: passable cells (not in line of sight)
- **black**: impassable cell
Binary file added doc/code/pathfinding/images/cost_field.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/code/pathfinding/images/flow_field.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion libopenage/pathfinding/definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ constexpr cost_t COST_IMPASSABLE = 255;
/**
* Start value for goal cells.
*/
const integrated_cost_t INTEGRATED_COST_START = 0;
constexpr integrated_cost_t INTEGRATED_COST_START = 0;

/**
* Unreachable value for a cells in the integration grid.
Expand Down

0 comments on commit ad76c8b

Please sign in to comment.