routeNavmesh & Collision

Navmeshes define walkable space for pathfinding and movement constraints.

Navmeshes define the walkable areas in your world. Use them to:

  • Snap spawned items onto reachable ground

  • Lock players/NPCs to walkable regions

Colliders can also be used to carve navmeshes in the editor.

Components (quick overview)

  • Navmesh: the baked navigation mesh you query and rebuild

  • Navmesh_Loop: polygon loops that define walkable boundaries (and holes)

  • Colliders: Box_Collider, Circle_Collider, Edge_Collider, Polygon_Collider

circle-info

For movement/pathfinding (Movement_Agent) see Movement Agents/NPCs.

Navmesh :: class : Component {
    // Project a point onto this navmesh.
    // triangle_hint is an acceleration hint you can reuse for nearby queries.
    try_find_closest_point_on_navmesh :: method(
        to_point: v2,
        result: ref v2,
        triangle_hint: ref s64
    ) -> bool;

    rebuild_immediately :: method() -> bool;
    mark_for_rebuild    :: method();
}

Editor setup (building a navmesh)

  1. Create an entity and add a Navmesh component.

  2. Create child entities with Navmesh_Loop components to define walkable polygons.

  3. For each Navmesh_Loop:

    • Add points to define the loop shape

    • Toggle Flip Inside Outside to make a hole/obstacle instead of walkable space

  4. Use the navmesh debug options in the inspector to visualize the triangles.

circle-info

By default, a Navmesh_Loop defines a walkable area. Flip it to "punch holes" (unwalkable islands) into an existing navmesh.

Colliders and navmesh loops

Colliders can also contribute loops via collider inspector options (for example "Make Navmesh Loop" / "Flip Navmesh Loop").

Important caveats:

  • A Navmesh does not automatically rebuild just because a collider changes at runtime.

  • If you modify collider geometry and you rely on collider-driven loops, manually rebuild the navmesh (see below).

  • If you want a navmesh that ignores colliders entirely, use the navmesh inspector option to ignore colliders.

Spawning on navmesh (clamp to reachable ground)

Use try_find_closest_point_on_navmesh to project a desired position onto the closest valid point on a navmesh:

circle-info

Reuse triangle_hint for repeated queries in the same area (loot spawners, wave spawns, etc). It can significantly speed up projection.

Rebuilding navmeshes (when geometry changes)

Use one of:

  • mark_for_rebuild(): defers rebuild to the start of next frame (best for batching)

  • rebuild_immediately(): rebuilds now (use only if you must query the updated mesh in the same frame)

circle-exclamation

Collision (current CSL support)

Colliders exist as components (Box_Collider, Circle_Collider, Edge_Collider, Polygon_Collider), but collision enter/exit scripting callbacks are not yet implemented in CSL.

Pseudo collision behavior (triggers, pickups, "hits")

Until collision callbacks are exposed in CSL, the standard approach is:

  • Query nearby components with Scene.get_all_components_in_range / Scene.get_closest_component_in_range

  • Do simple distance checks (in_range) to decide "inside", "picked up", "hit", etc.

Scene query helpers

circle-info

Prefer server-side for gameplay consequences (damage, pickups, scoring). Use local-only checks for cosmetic feedback.

Trigger volume (enter / stay / exit)

To simulate a trigger zone, keep a list of who was inside last frame and diff it against the current frame’s results.

circle-exclamation

Pickups (closest in range)

Fast movement "hits" (simple sub-stepping)

If you move quickly (dash, projectile), you can miss narrow targets when checking only the final position. A simple workaround is sub-stepping: sample a few points between last and new position and run the same range queries.

Last updated