> ## Documentation Index
> Fetch the complete documentation index at: https://docs.eucaengine.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Navigation

> Build a grid navmesh from scene colliders, compute an A* path between two world points, and attach a path goal to a unit — built end to end on a local server.

Euca's navigation (`euca-nav`) turns a region of the world into a **grid navmesh**, runs **A\* pathfinding**
over it (8-connected, Euclidean heuristic, line-of-sight smoothing), and exposes a **`NavAgent` + `PathGoal`**
you can attach to a unit. The mental model: the navmesh and `/path/compute` are pure functions you call from
the handler — they need no scheduled systems — while `/path/set` only attaches components that a *steering
system* must consume to move anything. This page builds a navmesh and routes a unit end to end; every command
is real and runnable against a [local server](/quickstart), and the outputs below are captured from one.

## Build a navmesh and route a unit

**1. Build the navmesh.** Give it a region and a `cell_size`; it rasterizes the scene's colliders into a
walkable grid and stores the result as a world resource. Cells under a collider come back as `blocked_cells`.

```bash theme={null}
curl -s -X POST http://localhost:3917/navmesh/generate \
  -H 'Content-Type: application/json' \
  -d '{"min_x":-50,"max_x":50,"min_z":-50,"max_z":50,"cell_size":1.0}'
# {"blocked_cells":0,"height":100,"ok":true,"total_cells":10000,"width":100}
```

A 100×100 region at `cell_size 1.0` is `10000` cells; `blocked_cells` is `0` here because the bare world has
no colliders to rasterize.

**2. Compute a path.** `/path/compute` runs A\* between two world positions and returns the waypoint list. It
reads the navmesh resource directly in the handler — no `/step` needed.

```bash theme={null}
curl -s -X POST http://localhost:3917/path/compute \
  -H 'Content-Type: application/json' -d '{"from":[0,0,0],"to":[10,0,5]}'
# {"count":10,"ok":true,"waypoints":[
#   [1.5,0.0,1.5],[2.5,0.0,2.5],[3.5,0.0,2.5],[4.5,0.0,3.5],[5.5,0.0,3.5],
#   [6.5,0.0,3.5],[7.5,0.0,4.5],[8.5,0.0,4.5],[9.5,0.0,4.5],[10.0,0.0,5.0]]}
```

Waypoints are cell centers (`x.5`) until the final one, which snaps to the exact target. A diagonal across the
whole grid returns proportionally more:

```bash theme={null}
curl -s -X POST http://localhost:3917/path/compute \
  -H 'Content-Type: application/json' -d '{"from":[-20,0,-20],"to":[20,0,20]}'
# {"count":40,"ok":true,"waypoints":[[-18.5,0.0,-18.5],...,[20.0,0.0,20.0]]}
```

**3. Attach a path goal to a unit.** `/path/set` puts a `NavAgent` and a `PathGoal` on the entity (and a
`Velocity` if it lacks one). Spawn a unit first, then set its goal:

```bash theme={null}
curl -s -X POST http://localhost:3917/spawn \
  -H 'Content-Type: application/json' -d '{"position":[0,0,0]}'
# {"entity_id":1,"entity_generation":0}

curl -s -X POST http://localhost:3917/path/set \
  -H 'Content-Type: application/json' -d '{"entity_id":1,"target":[10,0,5],"speed":5.0}'
# {"ok":true,"message":"Set path goal for entity 1 to (10.0, 0.0, 5.0)"}
```

The goal is now attached — but whether the unit actually moves depends on the project scheduling the nav
systems **and** a navmesh with a route to follow. See the gotcha below.

## Behavior and gotchas

The things you only find out by running it:

* **`/path/set` attaches the goal; whether the unit then moves depends on the project's schedule and a usable
  navmesh.** Following a path needs the `euca-nav` `pathfinding_system` (recompute the path when the goal is
  dirty) and `steering_system` (drive `Velocity` toward the next waypoint) **in the project's step schedule**,
  plus a navmesh that actually contains a route. The example MOBA project served headless *does* schedule both
  systems — but with the default `/navmesh/generate` over its dense level geometry, the test cell is blocked,
  so `/path/compute` returns "No path found" and a unit set to a goal still doesn't move:

  ```bash theme={null}
  curl -s -X POST http://localhost:3917/path/set \
    -H 'Content-Type: application/json' -d '{"entity_id":106,"target":[10,0,10]}'
  # {"ok":true,"message":"Set path goal for entity 106 to (10.0, 0.0, 10.0)"}

  curl -s -X POST http://localhost:3917/step -H 'Content-Type: application/json' -d '{"ticks":30}'
  curl -s http://localhost:3917/entities/106
  # ..."transform":{"position":[0.0,0.0,0.0],...},"velocity":{"linear":[0.0,0.0,0.0],...}
  ```

  So `/path/set` returns `{"ok":true,...}` but the entity stays put. To see steering actually relocate a unit,
  generate a navmesh over an open region (`min_x`/`max_x`/`min_z`/`max_z`) so a route exists. Navmesh
  generation and `/path/compute` are self-contained and run synchronously regardless of the schedule.

* **`/navmesh/generate` and `/path/compute` need no `/step`.** Both run synchronously in the handler. Generation
  rasterizes colliders into the grid; compute reads the stored navmesh and runs A\* immediately.

* **The navmesh is static once built.** It snapshots colliders at generation time and is not rebuilt when the
  world changes. Regenerate to refresh it — and regenerate *before* you compute paths, or `/path/compute`
  returns `{"ok":false,"error":"No path found (no navmesh or blocked)"}`.

* **Waypoints are cell centers.** With `cell_size 1.0`, interior waypoints land on `x.5` coordinates; only the
  final waypoint is the exact requested target. A smaller `cell_size` yields finer paths and more cells.

## Endpoints

| Method | Path                | Description                                                                       |
| ------ | ------------------- | --------------------------------------------------------------------------------- |
| `POST` | `/navmesh/generate` | Rasterize scene colliders into a grid navmesh (stored as a world resource)        |
| `POST` | `/path/compute`     | A\* between two world positions; returns the waypoint list (needs a navmesh)      |
| `POST` | `/path/set`         | Attach a `NavAgent` + `PathGoal` to an entity (a steering system must consume it) |

## Status

* **Shipped** — Navmesh generation from colliders, grid A\* with Euclidean heuristic and line-of-sight
  smoothing, and the `NavAgent`/`PathGoal` steering components. All headless.
* **Project-dependent** — Following a path needs the `euca-nav` steering and pathfinding systems in the
  project's step schedule **and** a navmesh that contains a route. The example MOBA project schedules both
  systems, but its dense level navmesh blocks the default test region, so `/path/set` attaches the goal yet the
  unit stays put; generate a navmesh over open ground (or run a project that does) to see steering relocate the
  agent. Navmesh generation and `/path/compute` work on any server.
* **Partial** — The navmesh is static once built (no automatic rebuild when colliders change; regenerate to
  refresh).

<Card title="Navigation endpoints" icon="route" href="/api-reference/introduction" horizontal>
  Navmesh, path-compute, and path-set endpoints with request and response schemas.
</Card>
