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:refv2,triangle_hint:refs64)->bool;rebuild_immediately::method()->bool;mark_for_rebuild::method();}
Editor setup (building a navmesh)
Create an entity and add a Navmesh component.
Create child entities with Navmesh_Loop components to define walkable polygons.
For each Navmesh_Loop:
Add points to define the loop shape
Toggle Flip Inside Outside to make a hole/obstacle instead of walkable space
Use the navmesh debug options in the inspector to visualize the triangles.
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:
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)
If you have a parent navmesh that "stitches" multiple child navmeshes together, changing a child navmesh does not automatically rebuild the parent. Call mark_for_rebuild() / rebuild_immediately() on the parent after edits.
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.
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
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.
This is "best effort" collision logic. If something is teleported/despawned between updates, you may not get a clean "exit" unless you handle cleanup.
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.