Godot pathfinding / 2026-06-06 / 9 min read
Updated 2026-06-12
Grid or navmesh in Godot? Choosing pathfinding that survives production
The short answer first, then the full decision: movement model, runtime changes, scale, agent size, path stability. Current for Godot 4.6, FAQ included.
The choice most projects make by accident
Most Godot projects pick grid or navmesh the same way: a tutorial used one, so the project uses it too, and the decision is defended for a year. That is a fine way to ship a prototype and an expensive way to discover, six months in, that the navigation layer is fighting the game instead of serving it.
There is no universal winner here. Grid pathfinding (AStarGrid2D) and navmesh pathfinding (the NavigationServer2D with a baked navigation mesh) are good at different things, and the right choice is set by your game's constraints, not by taste. The useful part is that those constraints are knowable in advance.
The short version: grid is the safer default when game logic is discrete, dynamic, explainable, and tile-bound. Navmesh is stronger when motion is free-form, mostly static, and spatially continuous. The rest of this article is how to tell which one describes your game — current as of Godot 4.6.
The short answer
If you want one rule before the detail: tile-locked, frequently-changing, integer-logic worlds lean grid; free-form, mostly-static, smooth-movement worlds lean navmesh. Almost everything below is a refinement of that sentence.
For the implementation route that also includes sparse authored waypoint graphs, use 2D pathfinding in Godot: grid, graph, or navmesh. This page keeps ownership of the deeper grid-versus-navmesh production tradeoff.
And if you're here because a path came back empty, that's its own diagnosis — why is my path failing in Godot walks the empty-path checklist for both models.
What AStarGrid2D actually is
AStarGrid2D is Godot's grid specialization of A*. You give it a rectangular region and a cell size, and it builds the graph for you — no manually creating points and wiring up neighbors like the general AStar2D. It thinks in integer cells (Vector2i), which is exactly what a TileMap-based game already thinks in.
Two properties define it and one method drives it. Set region and cell_size, call update() once, then query with get_id_path(). Marking a cell blocked is set_point_solid(); raising a cell's cost is set_point_weight_scale(). Neither of those needs another update(). The runtime AStarGrid2D guide covers structural rebuilds, point-layer replay, and blocker ownership in detail.
For the full API behavior table, version notes, and edge cases, use the AStarGrid2D complete reference. If the source map is a TileMapLayer, the concrete bridge is how to turn a TileMapLayer into a navigation grid.
Keeping pathfinding correct when the world changes
If walkability changes often — doors, placed towers, destroyed walls — grid is usually cheaper, but be precise about what "cheaper" means. The walkability edit itself is O(1)-style: set_point_solid() flips one cell and needs no update(). Keeping pathfinding correct is not O(1) — that still costs a path query or replan, and depends on your invalidation strategy: which cached paths and which agents actually need recomputing.
The navmesh equivalent of a runtime change is rebaking a region or using obstacle-assisted baking. The expensive part is usually parsing and synchronizing the source geometry, not the bake arithmetic alone, and it scales with the region rather than with the size of the change. It is the same spike story as repathing a whole grid at once: on either side, the fix is to bound the work to what changed — see why your Godot pathfinding causes frame spikes and dynamic blockers without a full rebuild.
Incremental replanning is well studied. Algorithms like D* Lite and Lifelong Planning A* reuse the previous search when only part of the graph changed instead of planning from scratch. The grid model makes that kind of local invalidation straightforward; the navmesh model makes you think in terms of regions and obstacles.
The hybrid reality
The two are not enemies, and plenty of shipped games use both. A common split is navmesh for motion and a grid for tactics and rules: units move smoothly on a navmesh while the game validates a tower placement on a grid so a player can never seal the only route, or biases movement with an influence layer.
Treat them as layers, not a religion. The question is rarely "which one is correct" and usually "which layer owns which decision."
When the built-ins are enough
Either model is fine until the scaffolding around it outgrows the engine layer — caches, debug overlays, clearance logic, custom invalidation. That is the point where you are no longer using a pathfinding API; you are building a navigation system. If that is where your grid project is heading, AStarGrid2D limitations and alternatives in Godot is the next read.
Until then: choose by constraints, keep it boring, and let the model match the game.
Frequently asked questions
When should I choose AStarGrid2D and when NavigationServer in Godot?
Choose AStarGrid2D when movement is tile-locked, the world changes often at runtime, and you need to explain why a path failed. Choose NavigationServer with a baked navmesh when movement is free-form, the world is mostly static, and agents need smooth paths through irregular geometry. Mixing them is normal: many shipped games use a navmesh for motion and a grid for rules.
Should I use AStarGrid2D or NavigationServer for a tower defense or roguelike?
Grid (AStarGrid2D). Discrete tile movement, cheap runtime blockers, and explainable paths are exactly its sweet spot.
Can I use NavigationServer2D without a NavigationAgent2D?
Yes. Query NavigationServer2D.map_get_path(map, from, to, true) directly, using get_world_2d().get_navigation_map() for the map RID. NavigationAgent2D is only an optional path-following and avoidance helper.
Do dynamic grid blockers require a full AStarGrid2D rebuild?
No. set_point_solid() and set_point_weight_scale() take effect immediately. The runtime AStarGrid2D update guide covers when structural changes do require update(), how to replay point data, and how that differs from navmesh rebaking.
Why does my navmesh path come back empty on the first frame?
The NavigationServer map has not synchronized its regions yet. Wait a physics frame; with an agent you can skip until NavigationServer2D.map_get_iteration_id(agent.get_navigation_map()) is no longer 0.
How do I handle dynamic obstacles without rebaking the whole navmesh?
Use NavigationObstacle2D for avoidance or obstacle-assisted baking where it fits. For frequent game-logic walkability changes, a grid with local invalidation is often simpler. Pick the layer that matches what actually changed — an obstacle node does not re-solve topology on its own.
Are NavigationAgent2D and NavigationObstacle2D stable in Godot 4.6?
Both are marked Experimental as of Godot 4.6 ("may be changed or removed in future versions"). They work, but pin your Godot version and re-test navigation on upgrades. AStarGrid2D has been stable.