Exporting the navigation mesh
The navigation mesh is the game’s own: the walkable surface of the level - every yard, road, floor, stair and bridge -
as polygons, the way the game’s own people walk it. With it an NPC actor sent somewhere
(MoveActor) walks there around the walls instead of straight through them and
opens the doors on its way ([actors] open_doors), an actor chasing a player goes around the corner after them, and a
game mode can ask for a walk between two points
(FindPath), whether one is reachable from the other
(IsReachable), where the floor is - indoors, on a bridge, where the terrain
says otherwise (GetNavmeshHeight) - and the nearest walkable spot to a
point (NearestNavmeshPoint).
Without it the actors walk straight lines - the body stops at a wall and catches up when the line comes out - and the
functions answer nil / false; HasNavmesh tells a mode which it is.
Exporting it
Section titled “Exporting it”Run tools/KcdMp.ExportNavmesh.exe from the Windows server folder on a machine that has the game. It reads the mesh
straight from the level’s own files - the game does not start, it takes a second per level - and writes the files into
the server folder’s data/navmesh/.
KcdMp.ExportNavmesh [--level <name>|all] [--variant <n>] [--game <folder>] [--out <folder>]All three levels by default; --level klaster does one. The game keeps a mesh for the level as the story leaves it -
doors bricked up, a ruin cleared, a camp built - and the tool takes the state a fresh world starts in; --variant <n>
picks another of the level’s states, for a server that stages one (-1 is the base mesh alone). The game is found
through Steam, the Xbox app’s games, the Epic Games Launcher or --game; --out writes elsewhere. --help prints the same.
Installing it
Section titled “Installing it”The tool puts the files where the server reads them. For a server on Linux, copy them into its data folder under
navmesh/, named after the level (klaster.knav). That is where the server looks by default:
[validation]navmesh = "data/navmesh/{level}.knav" # the default; "" = never{level} is replaced by the level the server runs, and the mesh is used while that level’s file is there - nothing to
turn on. The server log confirms the mesh at start
(navmesh: ... tiles, ... polygons ...: the actors walk paths, FindPath is live) or says it found no file, or why it
could not use the one it found.
The mesh is held in memory while the server runs: a few MB for klaster, about 400 MB for trosecko and 600 MB for
kutnohorsko. On a small machine running a big level, navmesh = "" keeps it out (the actors then walk straight
lines).
Every path search is bounded by navmesh_search_nodes and navmesh_search_ms in the same section (16384 nodes and
100 ms by default). A place the mesh has cut off - a room whose door the game’s mesh does not join, a ledge, a roof -
answers “no way” at once; a search that runs past the budget stops and answers “no way” as well. Both show in the log
with what asked and the two points:
navmesh: the game mode's FindPath (3164.4 876.8 56.1 -> 3152.9 857.5 61.1): the end is on a part of the navmesh no way leads to (114 polygons) - no pathnavmesh: the chase of actor 812 (...): stopped at the search budget (16384 nodes, 63 ms; ...) - no pathA line like the first one means the place itself cannot be walked to on the game’s mesh: pick another spot, or join it
with a nav link (CreateNavLink). An NPC chasing someone it cannot reach asks
again every five seconds and walks straight at them meanwhile.
One mesh per level per game build: after a game update, export it again.
