Three bot changes from the bot editor thread, approved by the owner: the nav graph no longer routes through things standing on a floor, bot perception is spread over ticks, and HOST GAME can pick a custom bot brain. No network protocol, map or demo format change.
Bot navigation (src/game/bots.{h,cpp})
- The bug: the nav graph had one node per walkable top, so a route across a floor went straight through whatever stood on it. The Depot bomb carrier pushed into its gatehouse's front wall (stuck about 16 s), Depot yard runs stopped at the perch (about 14 s), and Summit's west spawn walked into the ledge ramp's tall end for about 4-20 s.
- The fix: each top is cut into rectangles round anything standing on it that a player can't step over (grown by the player hull), with edges snapped at 10 cm so there are no slivers. Pieces of one top link where they meet; different tops link when a step, jump or drop reaches and nothing stands in the way (corner to corner for diagonal jumps, so Viaduct's zig-zag pads with posts still link).
- Routing: A* over regions (a top's joined pieces per 12 m tile, ALT landmarks, exact), then a fine A* through that corridor. Routes average x1.07 the shortest possible.
- Goals off the pieces (a hill centre under a mast, a site inside a crate) take the nearest piece within 4 m (
NavGraph::kGoalNear). A bot drifting onto a piece next to its route keeps the route instead of searching again. - Results: Depot gate 16 s stuck to 8.0 s to arrive; Depot yard 14 s to 3.6 s; the Summit hold is gone. Depot bomb bot sims went from 11 to 310 kills over the same runs.
- Urgent bomb bots: a bomb carrier or defuser hunting someone planned a route to both the hunt and the objective every think (the second always won). With the finer graph that doubled the searches per tick and starved the per-tick path budget; it now plans one.
- Trade-offs: Summit KOTH hill time is down about 30% (bots used to stand stuck on the hill, which counted as holding it). Building the nav graph is slower (Midtown 60 to 305 ms, on the background thread, so no frame or tick cost). Lodestone's worst single route search rose from about 2.6 to 3.5 ms; average and p99 searches improved.
NavKind::Surfaceskeeps the old whole-tops graph for the map report, the stairs check and the map editor's metrics, sodocs/MAP_REPORT.mdis byte-identical.
Bot perception spread (src/game/bots.cpp)
- Bots look (perception, 20 Hz of game time) starting from their respawn time, so a round restart put every bot on one tick from then on: 8-12 of 16 bots looked on the same tick in Depot bomb. Each bot now looks on a fixed phase of the 50 ms period from its id (golden-ratio steps), kept through deaths; a missed look (dead, a hitch) waits for its next phase instead of happening at once.
- serverbench (pinned core, median of 3): busiest tick 10 to 1 bot looking (Depot bomb 1000 Hz), 8 to 3 (125 Hz). Bot think time per tick p99: Hamlet 24 bots 500 to 372 us, Depot 125 Hz 667 to 631 us, Midtown points 288 to 272 us. Whole-tick p99 on Hamlet 1053 to 917 us.
- serverbench gains Midtown points (16 bots) and Depot bomb (1000 / 125 Hz) runs, a run selector, the busiest look tick and the bots' think time per tick.
HOST GAME > ADVANCED > BOT BRAIN (client host menu, botbrain listBrains())
- A cycle under SERVER LOG: BUILT-IN, then every
bots/*.qbrainin the data folder, listed again whenever HOST opens. The choice is saved (host_bot_brain) and goes toServerConfig::botBrain, so consoleaddbotand balance bots play it too. - A brain that doesn't compile shows ERROR ON LINE n - BOTS PLAY THE BUILT-IN BRAIN under the row (the full file:line:col error goes to the console); hosting with it says so and uses the built-in brain. A brain whose file is gone falls back to BUILT-IN when HOST opens.
- Ranked: BOT BRAIN: OFF (RANKED), greyed, never applied (the server refuses too). VS BOTS keeps the built-in brain.
- Why ADVANCED: the main host panel has no free row in duel.
- INFO > HOSTING,
docs/UI_TEST.mdanddocs/RELEASE_CHECKLIST.mdare updated; the checklist also gets a row for the nav fix (Depot gate and yard, Summit west spawn, Viaduct pads).
Tests
testBotNavBlockers(the three stuck cases; each fails on the old graph),navstuckandnavbenchcommands,testNavGraphchecks the region A* is exact and routes are short; allmaps / checkNavRoutes take spawns and goals the way bots do (nodeNear).- The UI test's data folder gets two brains (one broken), so the cycle and error line are clicked and layout-checked: 2396 widgets pass.