NavigationServer: objects, queues and readiness
Distinguish assigned properties from published navigation.
NavigationServer2D and NavigationServer3D manage maps, regions, links and queries in their respective dimensions. NavigationRegion, NavigationLink and NavigationAgent Entities use the server internally. Direct API access is useful when owning procedural geometry or navigation-object lifetimes; it does not automatically move characters.
Choose an approach
| Task | Approach |
|---|---|
| Place regions and links in the editor | Use the corresponding Entities and their properties. |
| Create procedural surfaces | Create server maps/regions with explicit RID ownership. |
| Obtain only route points | MapGetPath; see direct paths. |
| Filters, metadata and limits | QueryPath; see query objects. |
RIDs and ownership
A RID identifies a server object; it is not an Entity ID or a persistent resource path. MapCreate creates a map; RegionCreate creates a region. A query takes a map RID; RegionSetMap takes a region first and a map second. Do not swap RID types or submit them to the other dimension's server.
An ordinary navigation Entity manages its server object. Creating one directly makes you its owner: retain the RID, assign the map, provide data, then release it through FreeRid. See the complete 2D map ownership helper.
Why Set and Get can differ in one frame
Many modifying calls queue a command. A getter can still read the previous server state, while an Entity getter may already return its locally assigned property. Object creation, command application and geometry publication are separate events.
The checked procedural-level sequence is:
- Create a map and enable processing.
- Create regions and assign polygons/meshes, layers and map.
- Wait for published navigation. A zero
MapGetIterationIdmeans querying is premature. - Execute the query and validate its points and endpoints.
- After migration or geometry changes, wait for another publication and query again.
Do not treat one await PhysicsFrame as a universal readiness guarantee: asynchronous region and map building can require several steps. The fixture uses bounded waiting between changes, not a universal latency requirement. A nonzero iteration ID establishes a published version, rather than freshness of every submitted command.
MapForceUpdate provides forced synchronization. Do not replace normal processing with a call every frame or promise that one call completes all asynchronous work. This example does not establish that guarantee.
Queries, movement and avoidance
Path points describe a route. The game separately selects the next point, computes velocity, moves with collisions and handles link transitions. Agent avoidance is another mechanism; a velocity-computation callback is not a MapGetPath result. Do not overwrite gameplay positions with path points expecting physically correct movement.
A server command queue does not make arbitrary Entity operations safe from a worker thread. Check the specific API threading model separately; this example runs in the normal engine loop.
Executed checks cover queued map assignment, subsequent reads, region migration, queries and explicit object disposal. Multithreaded calls, avoidance/callbacks, MapForceUpdate guarantees and movement were not tested by this suite.