RandomPath doesn't use nnConstraint.graph to constrain nodes search

I found that RandomPath doesn’t use nnConstraint.graph to constrain nodes search. It seemed counterintuitive to me. But this fix seems to work:

added:
if (nnConstraint.graphMask == -1 || nnConstraint.graphMask.Contains((int)node.GraphIndex))

public override void OnVisitNode (uint pathNode, uint hScore, uint gScore) {
	// This method may be called multiple times without checking if the path is complete yet.
	if (CompleteState != PathCompleteState.NotCalculated) return;

	if (gScore >= searchLength) {
		if (gScore <= searchLength+spread) {
			nodesEvaluatedRep++;

			// Use reservoir sampling to pick a node from the ones with the highest G score
			if (rnd.NextDouble() <= 1.0f/nodesEvaluatedRep) {
				
				var node = pathHandler.GetNode(pathNode);
				if (nnConstraint.graphMask == -1 || nnConstraint.graphMask.Contains((int)node.GraphIndex))
				{
					chosenPathNodeIndex = pathNode;
					chosenPathNodeGScore = gScore;
				}
			}
		} else {
			// If no node was in the valid range of G scores, then fall back to picking one right outside valid range
			if (chosenPathNodeIndex == uint.MaxValue) {
				chosenPathNodeIndex = pathNode;
				chosenPathNodeGScore = gScore;
			}

			OnFoundEndNode(chosenPathNodeIndex, 0, chosenPathNodeGScore);
		}
	} else if (gScore > maxGScore) {
		maxGScore = gScore;
		maxGScorePathNodeIndex = pathNode;
	}
}

Is it ok or is there better solution?

Hi

That is correct, and as designed, though I agree it’s a bit counterintuitive, especially for this path type.

The RandomPath only uses the graph mask to choose where to start the search.

You can also, if you want, pass a custom ITraversalProvider implementation to the path.
See Agent-Specific Pathfinding - A* Pathfinding Project

1 Like

Thanks for hint with ITraversalProvider, I will just add

public bool CanTraverse(Path path, GraphNode node)
{
    if (path is RandomPath)
    {
        if (path.nnConstraint.graphMask != -1 && !path.nnConstraint.graphMask.Contains((int)node.GraphIndex))
            return false;
    }

    return DefaultITraversalProvider.CanTraverse(path, node);
}