NEVER Do in Navigation & Pathfinding
- NEVER set
target_position before awaiting physics frame — NavigationServer not ready in _ready()? Path fails silently. MUST call_deferred() then await get_tree().physics_frame.
- NEVER use
NavigationRegion2D.bake_navigation_polygon() at runtime — Synchronous baking freezes game for 100+ ms. Use NavigationServer.bake_from_source_geometry_data_async() for stutter-free updates.
- NEVER forget to check
is_navigation_finished() — Calling get_next_path_position() after reaching target = stale path, AI walks to old position.
- NEVER use
avoidance_enabled without setting radius — Default radius = 0, agent passes through others. Set nav_agent.radius = collision_shape.radius for proper avoidance.
- NEVER poll
target_position every frame for chase AI — Setting target 60x/sec = path recalculation spam. Use timer (0.2s intervals) or distance threshold for updates.
- NEVER assume path exists — Target unreachable (blocked by walls)?
get_next_path_position() returns invalid. Check is_target_reachable() or validate path length.
- NEVER use heavy node-based navigation for thousands of simple entities — Use
NavigationServer3D/2D RIDs directly to bypass node overhead.
- NEVER call
get_path() every frame — Use query_path() with reused NavigationPathQueryResult objects to prevent massive heap allocation and GC pressure.
- NEVER leave 'enter_cost' at 0 for high-penalty areas — Use costs to make AI prefer logical paths (roads over water) instead of just shortest geometric distance.
- NEVER ignore
agent_set_avoidance_callback — Always use the callback for safe velocity computation to avoid synchronization issues and "jittery" movement.
Decision Tree → Scripts
MANDATORY for the chosen path. Do NOT Load editor-intro / Official Docs bootstrap recipes from this skill body (use Reference links when you need first-time region setup).
| Need |
Script |
| Runtime / procedural bake without hitch |
MANDATORY async_dynamic_baking.gd |
| Agent stuck / jitter recovery |
MANDATORY agent_stuck_detection.gd |
| High-count RVO without nodes |
MANDATORY low_level_avoidance.gd |
| Moving platforms / dynamic regions |
dynamic_nav_manager.gd |
| RID-only maps/regions |
server_navigation_setup.gd |
| Reused path query objects |
memory_optimized_queries.gd |
| Terrain enter/travel costs |
terrain_cost_manager.gd |
| Projectiles as RVO obstacles |
moving_obstacle_server.gd |
| Links (jump/teleport/elevator) |
nav_link_traversal.gd |
| Walk / fly / swim layers |
layer_mask_navigation.gd |
| Crowd formation offsets |
group_avoidance_formations.gd |
| Server RVO crowd agent (node-less) |
crowd_agent_3d.gd |
| Dynamic navmesh carve (impact holes) |
nav_mesh_carver_3d.gd |
| Bake-time benchmark |
navmesh_profiler.gd |
| Smart agent wrapper |
smart_navigation_agent.gd |
Chase / Retarget Rule (never contradict NEVER)
Do not assign target_position every physics frame. Retarget on a timer (~0.2s) or when the chased body moves beyond a distance threshold:
# Threshold retarget — not per-frame path spam
const RETARGET_DIST := 1.5
var _last_target: Vector3
func _physics_process(_delta: float) -> void:
var desired := prey.global_position
if desired.distance_to(_last_target) >= RETARGET_DIST:
nav_agent.target_position = desired
_last_target = desired
if nav_agent.is_navigation_finished():
return
var next := nav_agent.get_next_path_position()
velocity = (next - global_position).normalized() * speed
move_and_slide()
Available Scripts
async_dynamic_baking.gd
bake_from_source_geometry_data_async — parse on main, bake off-thread.
agent_stuck_detection.gd
Distance-over-time stall detection and recovery.
low_level_avoidance.gd
Server-side RVO agents + avoidance callbacks.
dynamic_nav_manager.gd
Runtime navmesh updates for moving platforms.
server_navigation_setup.gd
Node-less maps/regions via NavigationServer RIDs.
memory_optimized_queries.gd
Reuse path query parameter/result objects.
terrain_cost_manager.gd
enter_cost / travel_cost for preferred routes.
moving_obstacle_server.gd
Dynamic RVO obstacles without full rebake.
nav_link_traversal.gd
NavigationLink jump/teleport/elevator handling.
layer_mask_navigation.gd
Multi-domain navigation layers (walk/fly/swim).
group_avoidance_formations.gd
Leader-relative offsets to reduce clumping.
smart_navigation_agent.gd
Production NavigationAgent wrapper patterns.
Expert Pointers
- Prefer Official Docs intros for first NavigationRegion bake UI; this skill owns async bake, server RVO, costs, and stuck recovery.
- Thousands of simple agents → RID server path (server_navigation_setup.gd + low_level_avoidance.gd), not one NavigationAgent node each.
- Crowd RVO / carve / bake benchmark samples → crowd_agent_3d.gd, nav_mesh_carver_3d.gd, navmesh_profiler.gd
Deep dives (on demand)
- 2D/3D chase, patrol, avoidance signals → agent-movement-patterns.md
- Server RVO crowds, projected carving, bake benchmarks → expert-nav-architectures.md
Reference
Progressive disclosure: open Official Documentation links only when researching a specific API;
load Related Skills when routing work to a peer domain — do not preload the whole lattice.
Official Documentation
- Navigation introduction (2D) — Minimal NavigationRegion2D + NavigationAgent2D setup, baking walkable polygons, and first-frame readiness.
- Navigation introduction (3D) — Parallel 3D bootstrap with NavigationRegion3D / NavigationAgent3D and mesh baking expectations.
- Using NavigationAgents — target_position, get_next_path_position, avoidance radius, and velocity_computed safe-velocity flow.
- Using NavigationServers — RID maps/regions/agents for node-less crowds and custom server setups.
- Using navigation meshes — Parse/bake source geometry, async baking, and projected obstructions for dynamic carving.
- Using NavigationRegions — Region ownership, enter/travel costs, and chunked/runtime region updates.
- Using NavigationObstacles — RVO push obstacles vs bake-time carving without full remesh every frame.
- Using NavigationLinks — Jump/teleport/elevator edges and manual link traversal on agents.
- Using navigation layers — 32-bit layer bitmasks for walk/fly/swim (or faction) path filters.
- Using navigation path query objects — Reuse NavigationPathQueryParameters/Result to avoid per-frame GC in crowds.
- Optimizing navigation performance — Bake cost, agent/obstacle counts, and server query budgets for large AI populations.
Related Skills
Prerequisites
- godot-characterbody-2d — Path corners become CharacterBody velocity via move_and_slide; agent scripts assume a body parent.
- godot-2d-physics — Collision layers/shapes still block bodies; navmesh is not a physics substitute for walls and triggers.
- godot-physics-3d — 3D agents share the same split: NavigationServer paths vs RigidBody/CharacterBody collision and slopes.
Complements
Downstream / consumers
- godot-genre-rts — Unit move commands and RVO crowds consume NavigationAgent/Server patterns directly.
- godot-genre-tower-defense — Lane/path enemies and dynamic blockers depend on regions, costs, and obstacle updates.
- godot-genre-stealth — Guard patrols and investigate points are NavigationAgent routes gated by detection state.
- godot-combat-system — Engage/kite/flank movement issues new targets and stuck recovery on top of paths.
- godot-monte-carlo-balancer — Simulate chase reachability, travel-time bands, and crowd pressure when tuning AI difficulty.
Master
- godot-master — Library router and mirrored module entry for this Domain Skill.
1---
2name: godot-navigation-pathfinding
3description: "Expert blueprint for AI pathfinding (tower defense, RTS, stealth) using NavigationAgent2D/3D, NavigationServer, avoidance, and dynamic navigation mesh generation. Use when implementing enemy AI, NPC movement, or obstacle avoidance. Keywords NavigationAgent2D, NavigationRegion2D, pathfinding, NavigationServer, avoidance, baking, NavigationObstacle."
4---
5
6## NEVER Do in Navigation & Pathfinding
7
8- **NEVER set `target_position` before awaiting physics frame** — NavigationServer not ready in `_ready()`? Path fails silently. MUST `call_deferred()` then `await get_tree().physics_frame`.
9- **NEVER use `NavigationRegion2D.bake_navigation_polygon()` at runtime** — Synchronous baking freezes game for 100+ ms. Use `NavigationServer.bake_from_source_geometry_data_async()` for stutter-free updates.
10- **NEVER forget to check `is_navigation_finished()`** — Calling `get_next_path_position()` after reaching target = stale path, AI walks to old position.
11- **NEVER use `avoidance_enabled` without setting radius** — Default radius = 0, agent passes through others. Set `nav_agent.radius = collision_shape.radius` for proper avoidance.
12- **NEVER poll `target_position` every frame for chase AI** — Setting target 60x/sec = path recalculation spam. Use timer (0.2s intervals) or distance threshold for updates.
13- **NEVER assume path exists** — Target unreachable (blocked by walls)? `get_next_path_position()` returns invalid. Check `is_target_reachable()` or validate path length.
14- **NEVER use heavy node-based navigation for thousands of simple entities** — Use `NavigationServer3D/2D` RIDs directly to bypass node overhead.
15- **NEVER call `get_path()` every frame** — Use `query_path()` with reused `NavigationPathQueryResult` objects to prevent massive heap allocation and GC pressure.
16- **NEVER leave 'enter_cost' at 0 for high-penalty areas** — Use costs to make AI prefer logical paths (roads over water) instead of just shortest geometric distance.
17- **NEVER ignore `agent_set_avoidance_callback`** — Always use the callback for safe velocity computation to avoid synchronization issues and "jittery" movement.
18
19## Decision Tree → Scripts
20
21> **MANDATORY** for the chosen path. **Do NOT Load** editor-intro / Official Docs bootstrap recipes from this skill body (use Reference links when you need first-time region setup).
22
23| Need | Script |
24|------|--------|
25| Runtime / procedural bake without hitch | **MANDATORY** [async_dynamic_baking.gd](scripts/async_dynamic_baking.gd) |
26| Agent stuck / jitter recovery | **MANDATORY** [agent_stuck_detection.gd](scripts/agent_stuck_detection.gd) |
27| High-count RVO without nodes | **MANDATORY** [low_level_avoidance.gd](scripts/low_level_avoidance.gd) |
28| Moving platforms / dynamic regions | [dynamic_nav_manager.gd](scripts/dynamic_nav_manager.gd) |
29| RID-only maps/regions | [server_navigation_setup.gd](scripts/server_navigation_setup.gd) |
30| Reused path query objects | [memory_optimized_queries.gd](scripts/memory_optimized_queries.gd) |
31| Terrain enter/travel costs | [terrain_cost_manager.gd](scripts/terrain_cost_manager.gd) |
32| Projectiles as RVO obstacles | [moving_obstacle_server.gd](scripts/moving_obstacle_server.gd) |
33| Links (jump/teleport/elevator) | [nav_link_traversal.gd](scripts/nav_link_traversal.gd) |
34| Walk / fly / swim layers | [layer_mask_navigation.gd](scripts/layer_mask_navigation.gd) |
35| Crowd formation offsets | [group_avoidance_formations.gd](scripts/group_avoidance_formations.gd) |
36| Server RVO crowd agent (node-less) | [crowd_agent_3d.gd](scripts/crowd_agent_3d.gd) |
37| Dynamic navmesh carve (impact holes) | [nav_mesh_carver_3d.gd](scripts/nav_mesh_carver_3d.gd) |
38| Bake-time benchmark | [navmesh_profiler.gd](scripts/navmesh_profiler.gd) |
39| Smart agent wrapper | [smart_navigation_agent.gd](scripts/smart_navigation_agent.gd) |
40
41## Chase / Retarget Rule (never contradict NEVER)
42
43Do **not** assign `target_position` every physics frame. Retarget on a timer (~0.2s) or when the chased body moves beyond a distance threshold:
44
45```gdscript
46# Threshold retarget — not per-frame path spam
47const RETARGET_DIST := 1.5
48var _last_target: Vector3
49
50func _physics_process(_delta: float) -> void:
51 var desired := prey.global_position
52 if desired.distance_to(_last_target) >= RETARGET_DIST:
53 nav_agent.target_position = desired
54 _last_target = desired
55 if nav_agent.is_navigation_finished():
56 return
57 var next := nav_agent.get_next_path_position()
58 velocity = (next - global_position).normalized() * speed
59 move_and_slide()
60```
61
62## Available Scripts
63
64### [async_dynamic_baking.gd](scripts/async_dynamic_baking.gd)
65`bake_from_source_geometry_data_async` — parse on main, bake off-thread.
66
67### [agent_stuck_detection.gd](scripts/agent_stuck_detection.gd)
68Distance-over-time stall detection and recovery.
69
70### [low_level_avoidance.gd](scripts/low_level_avoidance.gd)
71Server-side RVO agents + avoidance callbacks.
72
73### [dynamic_nav_manager.gd](scripts/dynamic_nav_manager.gd)
74Runtime navmesh updates for moving platforms.
75
76### [server_navigation_setup.gd](scripts/server_navigation_setup.gd)
77Node-less maps/regions via NavigationServer RIDs.
78
79### [memory_optimized_queries.gd](scripts/memory_optimized_queries.gd)
80Reuse path query parameter/result objects.
81
82### [terrain_cost_manager.gd](scripts/terrain_cost_manager.gd)
83`enter_cost` / `travel_cost` for preferred routes.
84
85### [moving_obstacle_server.gd](scripts/moving_obstacle_server.gd)
86Dynamic RVO obstacles without full rebake.
87
88### [nav_link_traversal.gd](scripts/nav_link_traversal.gd)
89NavigationLink jump/teleport/elevator handling.
90
91### [layer_mask_navigation.gd](scripts/layer_mask_navigation.gd)
92Multi-domain navigation layers (walk/fly/swim).
93
94### [group_avoidance_formations.gd](scripts/group_avoidance_formations.gd)
95Leader-relative offsets to reduce clumping.
96
97### [smart_navigation_agent.gd](scripts/smart_navigation_agent.gd)
98Production NavigationAgent wrapper patterns.
99
100## Expert Pointers
101
102- Prefer Official Docs intros for first NavigationRegion bake UI; this skill owns async bake, server RVO, costs, and stuck recovery.
103- Thousands of simple agents → RID server path ([server_navigation_setup.gd](scripts/server_navigation_setup.gd) + [low_level_avoidance.gd](scripts/low_level_avoidance.gd)), not one NavigationAgent node each.
104- Crowd RVO / carve / bake benchmark samples → [crowd_agent_3d.gd](scripts/crowd_agent_3d.gd), [nav_mesh_carver_3d.gd](scripts/nav_mesh_carver_3d.gd), [navmesh_profiler.gd](scripts/navmesh_profiler.gd)
105
106## Deep dives (on demand)
107
108- 2D/3D chase, patrol, avoidance signals → [agent-movement-patterns.md](references/agent-movement-patterns.md)
109- Server RVO crowds, projected carving, bake benchmarks → [expert-nav-architectures.md](references/expert-nav-architectures.md)
110
111## Reference
112
113> Progressive disclosure: open Official Documentation links only when researching a specific API;
114> load Related Skills when routing work to a peer domain — do not preload the whole lattice.
115
116### Official Documentation
117- [Navigation introduction (2D)](https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_introduction_2d.html) — Minimal NavigationRegion2D + NavigationAgent2D setup, baking walkable polygons, and first-frame readiness.
118- [Navigation introduction (3D)](https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_introduction_3d.html) — Parallel 3D bootstrap with NavigationRegion3D / NavigationAgent3D and mesh baking expectations.
119- [Using NavigationAgents](https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_using_navigationagents.html) — target_position, get_next_path_position, avoidance radius, and velocity_computed safe-velocity flow.
120- [Using NavigationServers](https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_using_navigationservers.html) — RID maps/regions/agents for node-less crowds and custom server setups.
121- [Using navigation meshes](https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_using_navigationmeshes.html) — Parse/bake source geometry, async baking, and projected obstructions for dynamic carving.
122- [Using NavigationRegions](https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_using_navigationregions.html) — Region ownership, enter/travel costs, and chunked/runtime region updates.
123- [Using NavigationObstacles](https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_using_navigationobstacles.html) — RVO push obstacles vs bake-time carving without full remesh every frame.
124- [Using NavigationLinks](https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_using_navigationlinks.html) — Jump/teleport/elevator edges and manual link traversal on agents.
125- [Using navigation layers](https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_using_navigationlayers.html) — 32-bit layer bitmasks for walk/fly/swim (or faction) path filters.
126- [Using navigation path query objects](https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_using_navigationpathqueryobjects.html) — Reuse NavigationPathQueryParameters/Result to avoid per-frame GC in crowds.
127- [Optimizing navigation performance](https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_optimizing_performance.html) — Bake cost, agent/obstacle counts, and server query budgets for large AI populations.
128
129### Related Skills
130
131#### Prerequisites
132- [godot-characterbody-2d](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-characterbody-2d/SKILL.md) — Path corners become CharacterBody velocity via move_and_slide; agent scripts assume a body parent.
133- [godot-2d-physics](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-2d-physics/SKILL.md) — Collision layers/shapes still block bodies; navmesh is not a physics substitute for walls and triggers.
134- [godot-physics-3d](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-physics-3d/SKILL.md) — 3D agents share the same split: NavigationServer paths vs RigidBody/CharacterBody collision and slopes.
135
136#### Complements
137- [godot-raycasting-queries](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-raycasting-queries/SKILL.md) — Line-of-sight, aim cones, and hit prediction sit beside pathfinding for chase/stealth AI.
138- [godot-state-machine-advanced](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-state-machine-advanced/SKILL.md) — Patrol/chase/search states own when to retarget NavigationAgent and when to stop.
139- [godot-tilemap-mastery](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-tilemap-mastery/SKILL.md) — TileMap/TileSet geometry often feeds NavigationPolygon baking in 2D levels.
140- [godot-3d-world-building](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-3d-world-building/SKILL.md) — Static meshes and GridMaps are the usual NavigationMesh source geometry for baked regions.
141- [godot-procedural-generation](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-procedural-generation/SKILL.md) — Runtime layouts require parse + bake_from_source_geometry_data_async after generation.
142- [godot-performance-optimization](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-performance-optimization/SKILL.md) — Crowds push toward server RIDs, query reuse, and avoidance tuning called out in this skill.
143
144#### Downstream / consumers
145- [godot-genre-rts](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-genre-rts/SKILL.md) — Unit move commands and RVO crowds consume NavigationAgent/Server patterns directly.
146- [godot-genre-tower-defense](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-genre-tower-defense/SKILL.md) — Lane/path enemies and dynamic blockers depend on regions, costs, and obstacle updates.
147- [godot-genre-stealth](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-genre-stealth/SKILL.md) — Guard patrols and investigate points are NavigationAgent routes gated by detection state.
148- [godot-combat-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-combat-system/SKILL.md) — Engage/kite/flank movement issues new targets and stuck recovery on top of paths.
149- [godot-monte-carlo-balancer](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-monte-carlo-balancer/SKILL.md) — Simulate chase reachability, travel-time bands, and crowd pressure when tuning AI difficulty.
150
151#### Master
152- [godot-master](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-master/SKILL.md) — Library router and mirrored module entry for this Domain Skill.