Difference between direct graph updates and grid graph rules?

What is the difference between directly updating the walkability of a tile via graph updates like described here docs with the following code (only updating a single tile for simplicity):

            AstarPath.active.AddWorkItem(new AstarWorkItem(ctx =>
            {
                var gg = AstarPath.active.data.gridGraph;
                var node = gg.GetNode(0, 0);
                node.Walkable = false;
                gg.GetNodes(node => gg.CalculateConnections((GridNodeBase) node));
            }));

and using a grid graph rule like so (I have no idea how to select a specific node here so it’s probably broken code):

public override void Register (GridGraphRules rules) {
            rules.AddMainThreadPass(Pass.BeforeConnections, context => {
                var nodeWalkable = context.data.nodeWalkable;
                var nodePositions = context.data.nodePositions;
                for (int i = 0; i < nodePositions.Length; i++) {
                    nodeWalkable[i] &= false;
                }
            });
        }

In my use case, a player can place or remove obstacles on the grid graph frequently. I just want to let the grid know when that happens and update it for that one specific tile, so the visualization also updates. Which one of these methods is preferable for such use case, and what is the difference?

Hi

The first one modifies the graph data in place, the second one is a rule that will be applied whenever the graph is scanned or when the graph is updated.

The benefit of the second one is that it is declarative, so it is much more robust.

For the grid graph rule, just call AstarPath.active.UpdateGraphs with a bounding box that encapsulates just that node. Note that even though the bounding box is just one node, it may update more nodes if you are using e.g. the ‘erosion iterations’ setting.

When you update a graph that has a grid graph rule, then the rule will be called with a small nodes array that represents a sub-rectangle of the graph.

The top approach is preferable if you just want to update the graph and you don’t really care about integrating anything with physics or other kinds of graph updates. The second approach is preferable if you want to integrate it with other graph updates and/or other rules and settings.

Note that if you use the first approach for just a single node you probably want to use gg.CalculateConnectionsForCellAndNeighbours(node) for just the node you are updating, instead of calculating the connections for every single node in the graph (which is a bit slow).