6.4 KiB
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/:
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:
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:
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 for dependency and ownership decisions and the implementation plan for acceptance gates.