# 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.