The BotManager can fail to call bots' retire method since the bot loop keeps waiting for a game tick data that never arrives.
I don't know if this happens in practice, but it looks possible from the code.
The BotManager should probably wait for all threads to join before returning from retire.