Steamhammer can’t rebuild its last hatchery
While reviewing WorkerManager to find a different bug, I happened to notice a subtle mistake in WorkerManager::getBuilder(), the routine that chooses a worker to construct a building. If there is a worker whose job is to move into position, it prefers that worker. But if there is not, it picks a mineral worker:
if (unit->isCompleted() && (workerData.getWorkerJob(unit) == WorkerData::Minerals))
It looks correct. If you have workers then should always have mineral workers, unless they are all pulled for other jobs, and then you probably prefer to wait to start the building. But it’s not correct. There is an important case where there are no mineral workers: You may have no bases mining minerals because they were destroyed or mined out, so all the former mineral workers are marked Idle.
if (unit->isCompleted() && (workerData.getWorkerJob(unit) == WorkerData::Minerals || workerData.getWorkerJob(unit) == WorkerData::Idle))
Without this fix, when Steamhammer loses its only hatchery, it is unable to rebuild. I ran into that bug in January and always wondered about the cause. Theoretically the bug could also strike in the late game, after all surviving hatcheries have mined out their minerals. I’ve never seen it happen, but then there would be no mineral workers and Steamhammer would be unable to construct a building.
It’s not a critical bug. Losing your last hatchery usually means you lose the game. But if the opponent is also in dire straits, you still have a chance. It happens most often in zerg versus zerg.
Now I need to go find any other places where code looks for a mineral worker and make sure it can find an idle worker too. WorkerManager::isFree() was already correct, but there might be more....
Update: The other routines which get a mineral worker and skip over idle workers are WorkerManager::getClosestMineralWorker(),
WorkerManager::getGasWorker(), and
WorkerManager::getMoveWorker(). Routines outside WorkerManager which do similar jobs all call isFree() as they should. I rewrote these three to call isFree() too.
Comments
PurpleWaveJadien on :
Jay Scott on :
Paul Goodman on :
Jay Scott on :
MicroDK on :
Jay Scott on :
Jay Scott on :
PurpleWaveJadien on :
Joseph Huang on :
Jay Scott on :