Steamhammer 2.0 base defense
I rewrote important parts of base defense. I fixed minor bugs in passing, but I had 2 main reasons: 1. Squad unit clustering caused bad defensive behaviors that had to be fixed. 2. The original base defense, as inherited from UAlbertaBot, was actually region defense. It iterated through regions of the map, and defended any region where the bot owned buildings. On some maps, one region can contain more than one base. Examples are the mineral-only bases on Python which are all in one big center region, and the center bases on Fortress which are laid out similarly. Base defense needed changes to defend these bases successfully.
• Iterate through bases, not regions, to check for areas that need defense. This means that buildings built outside any base area are no longer defended—not a serious loss, they were rarely defended well in the first place. See CombatCommander::updateBaseDefenseSquads()
. The squads created to defend bases are called Base squads.
• A base is deemed to be in need of defense when an enemy unit (other than a single worker scout) is within a specified baseDefenseRadius
distance of the base, OR if it is in the same region as the base and is within baseDefenseRadius + 300
. The base region may be very large (and may contain multiple bases), in which case we don’t want to panic and send defenders when they aren’t needed. Or the base region may be very small, so that attackers outside the region can hit the base, a historical problem for Steamhammer. This condition covers both cases.
• A base is considered to be no longer under attack if there are no enemy units meeting the same criterion, except that the radius is larger by baseDefenseHysteresis
. The hysteresis reduces indecisiveness. The numbers baseDefenseRadius
and baseDefenseHysteresis
are constants defined at the top of CombatCommander::updateBaseDefenseSquads()
; at some point I may move them to the configuration file.
• Steamhammer used to ignore overlords, observers, and floating terran buildings in deciding whether the base needs defense. Now it counts them, and will send anti-air units if needed and available. It will also assign a detector if needed to target the observer. Thou Shalt Not Scout For Free.
• A Base squad is disbanded and the squad data structure destroyed when the squad is no longer needed. The squads used to be kept around even when empty. Dropping the squad mainly makes the debug display easier to understand.
• The Base squad’s order is centered on the enemy unit which is closest to the base location (the upper left corner of the command center, nexus, or hatchery). This guarantees that the Base squad won’t sit idle in the middle of the base while the enemy rampages on the outskirts.
• Release defending units that can’t attack any of the remaining intruders. For example, if the enemy shows up with both air and ground units, we might assign both zerglings and mutalisks for defense. If the enemy ground units are destroyed or leave and only air units remain, the zerglings become useless for defense and are released. The useless zerglings used to remain in the Base squad until the whole squad was released.
• Don’t double-count the same unit as both a ground and an air defender. Steamhammer used to think, “I have 4 hydralisks to drive off these corsairs, and I have the same 4 hydralisks to stop these 2 zealots. I have enough defenders!” The calculation to avoid double-counting is kind of involved.
• Fixed a bug introduced in a recent version which could overassign defenders. It would, for example, always assign at least 2 anti-ground defenders when under air attack.
pulling workers
Deciding whether to pull workers for defense—to place them in a Base squad—is also in this code. Pulling workers is sometimes necessary, but it has to be strictly regulated because it puts workers in danger. (Worker self-defense doesn’t involve putting them into a Base squad, and is not handled here.) I tried to fix the biggest weaknesses.
• Pull workers that are within a smaller radius: 18 tiles instead of 24. This is about the location of the worker. That should mostly prevent Steamhammer from pulling workers from another base to defend this one.
• Pull workers only when the enemy is very close to the mineral line. This is about the location of the enemy. Steamhammer used to pull workers to meet the enemy too far away from the mineral line, wasting time and putting workers in unnecessary danger.
• Release pulled workers much sooner. Steamhammer used to retain pulled workers in the Base squad until the squad was disbanded. Now it releases the workers when the “must pull workers!” condition is not satisfied.
Next: Squad unit clustering.