Path Constraints
DeBroglie comes with a set of constraints called path constraints. These constraints all work similarly, and all concern the connectivy across a range of tiles.
A "path" is a route from one cell to another, stepping one adjacency at a time. Each path constraint takes ana IPathSpec as input, which specifies what paths are considered valid. The IPathSpec also lets you control which tiles are "relevant", which is discussed later.
There are currently three constraints:
- ConnectedConstraint - ensures that there is a valid path between relevant tiles.
- LoopConstraint - ensures there are at least two independent paths between relevant tiles.
- AcyclicConstraint - ensures there are are no loops at all in the generated result.
Warning
Note that path constraints are generally more performance heavy than other constraints, and usually require backtracking to get good results.
Example
Path Specs
Path specs describe what paths are considered valid, and what is considered relevant. There are two implementations, PathSpec and EdgedPathSpec. The latter is slower, but more flexible, however they both work similarly.
PathSpec just has a list of tiles that form the path tiles. As long as these tiles are placed adjacency, a valid path can route through them. EdgedPathSpec, on the other hand, lists a set of tiles and what "exits" it has. A path can only route through a pair of adjacent tiles if they both have exits pointing to each other.
EdgedPathSpec is useful for tiles that literally have a picture of a path on them. For example consider placing the tiles and together. Both tiles have a picture of a path on them, but the path exits the tiles only on certain edges. means they are connected, but is not.
Regardless of how valid paths are defined, some path conmponets consider a second set called "relevant" tiles. Typically, the relevant tiles are a subset of the path tiles, and are the only important ones for path finding. By default, all path tiles are considered relevant, so you can ignore these settings. Otherwise, you can set RelevantTiles to configure them, and RelevantCells to force the tile in a given cell to be considered relevant regardless of what is placed there.
For example, suppose you have a player start tile and goal tile. You can make these the only relevant tiles, and use a ConnectedConstraint to force that there is always a route between these two tiles. But the rest of the generation would be unconstrained. Or you could use RelevantCells to mark a specific location for the start and goal without needing special tiles.
Connected Constraint
The ConnectedConstraint checks that for any given two relevant cells, it is possible to connect them together via a path of adjacent path tiles. It does this by banning any tile placement that would make such a path impossible.
Example
Loop Constraint
The loop constraint backtracks whenevever a chokepoint is found in the set of available paths, effectively forcing there to be at least two non-overlapping valid paths between any two relevant tiles.
Acyclic Constraint
The acyclic constraint backtracks whenever a cycle is found, forcing the remaining paths into a tree or forest. The acyclic constraint ignores relevancy for now.