Skip to content

Bot Navigation

P3rlE edited this page Oct 9, 2026 · 2 revisions

Bot Navigation

Race bots use two systems:

  1. bot_path_node (primary): routes you place in the editor.
  2. Ghost routes (fallback): when a map has no bot_path_nodes, bots follow the fastest recorded ghost laps.

If a map has any bot_path_nodes for the current variant, the ghost fallback isn't used.

Combat bots in DM and team modes use the classic Quake III .aas navigation. Build it with bspc (see Mapping: Getting Started).

Autoball bots 🧪

In Autoball bots don't follow routes. They steer straight at the ball, a defensive spot or a turbo pickup, depending on their role (attack, defend, support). The map still needs an .aas file, because the bot code won't start without one. g_autoballDebug 2 prints the role changes.

bot_path_node

A point entity marking one waypoint of a route. Bots drive from node to node in order, and after the last node they continue with the first one.

Key Default Range Description
pathId 0 0 – 63 Route ID. All nodes with the same pathId form one route. A map can have several routes.
order 0 0 – 4095 Position of the node in its route. Must be unique per pathId. Nodes are sorted by this value.
width 256 1 – 8192 Usable track width at this node, in units. Bots stay within this corridor.
targetSpeed -1 -1 – 5000 Target speed in units/s. -1 = automatic (recommended).
trackLengthMask 7 1 – 7 Track lengths this node is used for: 1 short, 2 medium, 4 long. Add them up, e.g. 3 = short + medium.
reversed 0 Direction: 0 / forward, 1 / reversed, or both

A route needs at least 2 nodes. The game warns in the console if nodes are unreasonably close together or far apart.

Placement tips

  • Put a node at the apex of every corner and at regular intervals on straights.
  • Use a wide width on straights and a narrow one in technical sections.
  • Coverage of the important track features matters more than the number of nodes. Bots interpolate smoothly between them.
  • Use targetSpeed only where bots consistently arrive too fast, for example before a hairpin after a long straight.
  • For reversible tracks, either use reversed "both" or build a separate node set with reversed "1".

How bots follow the route

  • Each frame the bot finds the nearest node ahead of it.
  • It steers towards a look-ahead point that moves further ahead the faster it drives (400 units + 0.35 × speed).
  • Its sideways offset is clamped to the node's width, so it stays on the road even while recovering from a slide.
  • If it gets stuck, it reverses briefly, re-centres and rejoins the route.

Viewing routes in-game

\devmap mymap
\toggle cg_drawBotPaths

Ghost fallback

Without bot_path_nodes, the server builds bot routes from the ghost files in its ghosts/ folder:

  • Ghosts are matched to the current track variant (<map>_tl<length>_rev<0|1>_*.ghost).
  • The server takes the five fastest ghosts per variant. Clean laps (no resets or teleports) are preferred.
  • Every variant needs its own ghosts. A ghost of the long track doesn't help on the short one.

To prepare a track this way: drive a few clean laps for every variant and ship the resulting ghost files in ghosts/.

Fuel

Bots use fuel at only 10 % of the normal rate, so they effectively never run dry during a race.

Debugging

Set these server cvars to log a per-tick trace of the bot navigation:

\set g_aiDmnetDebugExport 2
\set g_aiDmnetDebugExportPath "logs/ai_dmnet_debug.jsonl"
Field Meaning
pathId -1 = ghost route, 0+ = bot_path_node route
nodeIndex Current node or waypoint
actualSpeed / targetSpeed Current vs. desired speed (units/s)
recoveryState none, stuck_detect, reverse_unwind, rejoin_route, emergency_reset
collisionRisk 1 = another car predicted close ahead
routeDeviation Distance from the bot to the current node

Example maps

  • Race_Bot_Test: a small test track with bot_path_nodes
  • q3r_valley: Desert Valley, a full track with bot_path_nodes

Clone this wiki locally