1.18.1 fixes the game closing when you stop hosting on Windows. Network protocol unchanged (42), same simulation, demos unaffected.
Fixes
STOP HOSTING closed the game (Windows)
- What players saw: pressing STOP HOSTING (or anything else that ends a hosted game: BACK TO EDITOR after a test map, ending an edit session, vs bots or a time trial, a dropped connection, hosting again, quitting) closed the whole game with no message, instead of returning to the menu. It happened once the bots had searched for a route, so with bots almost every time.
- Why: a hosted game's server runs on its own thread, which ends when hosting stops. The bots' route search (
NavGraph::findPath) kept four reusable buffers inthread_localvectors. The Windows build uses MinGW, whose thread-locals are emulated (emutls), and emutls frees a thread-local's memory before running its destructor. When the server thread ended, the vectors' data pointers had already been overwritten by the heap's free-list links, so their destructors freed garbage pointers. That corrupted the heap, and Windows ends a GUI program on heap corruption without a message. It was not a quit: it was a crash. - Why 1.18.0 didn't fix it: 1.18.0's fix ("a crash when a hosted game's server thread ended") moved the server's rules cache out of
thread_local, the same bug in another place. The route-search buffers were the second one; they date from the bot rewrite in 1.17.0. - How it was found: Linux (glibc's native thread-locals) never shows it, and STOP HOSTING worked there before and after the fix. Test programs built with the release's own Windows toolchain (
x86_64-w64-mingw32-g++-posix13, static) and run under Wine showed the vectors' data pointers replaced by the same heap link at thread exit. - The fix: the buffers are now a member of the nav graph (
NavGraph::scratch_). Only its own server's thread searches it, and they're freed with the server, so nothing leaks. It's also slightly faster on Windows: each route search no longer makes five__emutls_get_addresscalls to find its buffers. - Test: a new
botaimtest hosts a server with 3 bots on its own thread the way the game does, checks the bots searched routes on that thread, then ends the thread and stops the server, twice. The Windows CI runners run it on the toolchain that crashed. - No
thread_localwith a destructor is left in shipped code. Rule from here on:thread_localonly for plain types or a raw pointer.