NEVER Do in Navigation & Pathfinding
- NEVER set
target_positionbefore awaiting physics frame — NavigationServer not ready in_ready()? Path fails silently. MUSTcall_deferred()thenawait get_tree().physics_frame. - NEVER use
NavigationRegion2D.bake_navigation_polygon()at runtime — Synchronous baking freezes game for 100+ ms. UseNavigationServer.bake_from_source_geometry_data_async()for stutter-free updates. - NEVER forget to check
is_navigation_finished()— Callingget_next_path_position()after reaching target = stale path, AI walks to old position. - NEVER use
avoidance_enabledwithout setting radius — Default radius = 0, agent passes through others. Setnav_agent.radius = collision_shape.radiusfor proper avoidance. - NEVER poll
target_positionevery 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. Checkis_target_reachable()or validate path length. - NEVER use heavy node-based navigation for thousands of simple entities — Use
NavigationServer3D/2DRIDs directly to bypass node overhead. - NEVER call
get_path()every frame — Usequery_path()with reusedNavigationPathQueryResultobjects 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
- godot-raycasting-queries — Line-of-sight, aim cones, and hit prediction sit beside pathfinding for chase/stealth AI.
- godot-state-machine-advanced — Patrol/chase/search states own when to retarget NavigationAgent and when to stop.
- godot-tilemap-mastery — TileMap/TileSet geometry often feeds NavigationPolygon baking in 2D levels.
- godot-3d-world-building — Static meshes and GridMaps are the usual NavigationMesh source geometry for baked regions.
- godot-procedural-generation — Runtime layouts require parse + bake_from_source_geometry_data_async after generation.
- godot-performance-optimization — Crowds push toward server RIDs, query reuse, and avoidance tuning called out in this skill.
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.