108 lines
6.4 KiB
Markdown
108 lines
6.4 KiB
Markdown
# Navigation Authoring
|
|
|
|
Blacksite navigation v1 uses authored bounds, obstacles, areas, links, and validation samples to
|
|
produce a deterministic Rerecast bake artifact. The scene crate owns one height-aware Polyanya
|
|
query core; editor preview, project validation, and `game::navigation::NavigationRuntime` use that
|
|
same implementation.
|
|
|
|
## Authoring
|
|
|
|
Use **Scene > Navigation** or the path icon in the existing viewport toolbar to create navigation actors:
|
|
|
|
- **Navigation Bounds** defines an axis-aligned bake region, agent profile, generated artifact path,
|
|
optional debounced auto-bake, and named start/end validation samples.
|
|
- **Navigation Obstacle** carves a blocked volume from overlapping bounds.
|
|
- **Navigation Area** records a named walkable/blocked volume and traversal cost. V1 applies blocked
|
|
areas during bake and retains walkable cost metadata for a future per-polygon cost callback.
|
|
- **Navigation Link** connects otherwise isolated regions. Endpoints are local to the actor;
|
|
direction, enabled state, and traversal cost are authored.
|
|
|
|
V1 source geometry includes primitives and additive brushes. Imported static-mesh manifests do not
|
|
yet contain normalized collision triangles, so imported objects require authored navigation
|
|
obstacles until that artifact contract is extended. Bounds never synthesize a walkable floor:
|
|
at least one overlapping primitive or additive brush must provide real source triangles, so gaps,
|
|
voids, and separated platforms remain non-navigable unless explicitly linked.
|
|
|
|
Each navigation actor must own exactly one navigation component. Inspector changes are undoable and
|
|
save-time validation rejects invalid extents, profiles, area IDs/costs, and link endpoints. New and
|
|
duplicated bounds receive an actor-ID-derived artifact path; headless bake and project validation
|
|
reject legacy or manually edited paths claimed by more than one bounds actor before any file is
|
|
written.
|
|
|
|
The authoritative bake resolver starts from the active scene's authored snapshot, expands visible
|
|
composed subscenes, and expands linked prefab sources recursively. Contributor IDs include their
|
|
subscene/prefab chain so repeated source actors remain unambiguous. Prefab transform, primitive,
|
|
brush, navigation-component, and nested-instance overrides use their serialized values. Independent
|
|
property paths on one component merge with the same reflected semantics as runtime hydration, while
|
|
every override must still match the source component base it was authored against. Drifted property
|
|
layers and structural overrides are blocked with a rebase/apply/unpack repair action because
|
|
silently guessing would produce a different mesh from the hydrated editor world. Prefabs may
|
|
contribute geometry, obstacles, areas, and links, but Navigation Bounds remain owned by level
|
|
scenes.
|
|
|
|
## Bake And Preview
|
|
|
|
Select a bounds actor and click **Bake** in its Inspector, use **Scene > Navigation > Bake Selected
|
|
Bounds**, or click the toolbar path icon. The generated artifact must remain under
|
|
`assets/navigation/generated/`. Its fingerprint includes the source scene, bounds, agent settings,
|
|
overlapping primitive/additive-brush triangles, obstacles, areas, and links. Distant authoring is
|
|
excluded so independent bounds do not invalidate one another. Relevant edits immediately mark it
|
|
stale; auto-bake waits 0.75 seconds after the latest change before rebuilding. A failed auto-bake
|
|
reports once and waits for another authored change before retrying.
|
|
|
|
The viewport overlay draws authored volumes, baked polygon edges, link endpoints, and the current
|
|
path test. Bounds, obstacles, and areas are shown as the same scaled, rotated world-axis-aligned
|
|
volumes consumed by the bake, so the overlay remains truthful for transformed or parented actors.
|
|
Set **Path start** and **Path end** on the bounds card and choose **Test Path**. Green/red endpoint
|
|
markers and an amber route show the exact result returned by the game runtime API. The editor also
|
|
tracks the selected artifact path on disk: external deletion, replacement, or rebaking invalidates
|
|
the previous preview and reloads the new artifact before another path query can run.
|
|
|
|
Choose **Pin Current Path** to store the current local-space endpoints as a named validation sample.
|
|
Samples can be enabled, edited, loaded back into the preview, or removed from the same bounds card.
|
|
Enabled samples are embedded in the artifact and must resolve through the shared multi-link runtime
|
|
query during project validation.
|
|
|
|
## Headless And Runtime
|
|
|
|
Bake one scene or every scene under `assets/levels/`:
|
|
|
|
```bash
|
|
cargo bake-navigation --project . --scene assets/levels/navigation_authoring_showcase.scn.ron
|
|
cargo bake-navigation --project .
|
|
cargo bake-navigation --project . --check
|
|
```
|
|
|
|
`--check` never writes. It fails when an artifact is missing, malformed, stale, generated by a
|
|
different exact navigation toolchain, or differs from a fresh deterministic bake, making it
|
|
suitable for CI. Bake requests are rejected before allocation when their voxel grid exceeds the
|
|
production budget (8,192 cells per X/Z axis and 4,194,304 XZ cells total). `cargo validate-levels`
|
|
applies the same composed-scene/prefab resolver, validates link proximity and enabled samples,
|
|
reports effective disconnected components after valid links, and adds current navigation artifacts
|
|
to package dependencies. Artifacts use schema 2, an exact Rerecast/Polyanya/glam generator ID, and a
|
|
self-verifying payload hash; incompatible or parseable-tampered artifacts must be rebaked.
|
|
|
|
Gameplay loads and queries an artifact without editor dependencies:
|
|
|
|
```rust
|
|
let navigation = game::navigation::NavigationRuntime::load(path)?;
|
|
let path = navigation.query(start, destination)?;
|
|
```
|
|
|
|
The returned path contains height-resolved world-space points, 3D total length, and the ordered
|
|
stable actor IDs of every off-mesh link used by the route. Routes may traverse multiple directed or
|
|
bidirectional links across disconnected islands.
|
|
|
|
The game binary also exposes a renderer-free artifact check for build or deployment tooling:
|
|
|
|
```bash
|
|
cargo run -p game -- --validate-navigation assets/navigation/generated/example.nav.ron
|
|
```
|
|
|
|
It validates link placement and every enabled embedded sample, then exits nonzero with the named
|
|
failure instead of opening a window.
|
|
|
|
See [ADR 0032](../adr/0032-versioned-navigation-bake-and-runtime-query.md) for dependency and
|
|
ownership decisions and [the implementation plan](../../.cursor/plans/navigation_authoring_2026-07-11.plan.md)
|
|
for acceptance gates.
|