archive by month
Skip to content

ASL 16 round of 24 group D

ASL 16 round of 24 continues this week. Group D just finished as I write, and it has the best games of the tournament so far.

Game 2, Action versus Effort, was a hive tech ZvZ, always special. It went to ultralisks versus defiler-lurker. Recommended. The following two games were also exciting, and the final game was not bad.

what’s next for Steamhammer: the decision

I have decided what tactical skills to work on. My list included skills for specific units: Mutalisks, the most important; lurkers, which I’m most interested in for now; scourge, which Steamhammer spends heavy gas on and doesn’t always use well, defiler skills because Steamhammer often reaches late game. But those are only single unit types. And unit coordination skills, like storm dodging, scarab dodging, mine clearing and mine dragging, making the best use of the dark swarm that is on the map—all needed, all narrow and specific. And tactical analysis, my initial favorite. I have an algorithm in mind, which calls for a fast combat evaluator. MaasCraft’s tactical search also uses a fast combat evaluator. My idea is different, and I’m not satisfied with MaasCraft’s evaluator. Thinking through what’s needed, I concluded that the first draft would be easy to write, but would produce poor results. I think it’s likely that it needs a sophisticated combat evaluator to work well—I have an AI algorithm in mind for that too, but I fear I can’t finish it in time for SSCAIT in December.

To make the most progress before SSCAIT, I decided to work on the next level of pathfinding skills. Steamhammer currently calculates terrain paths without regard to where the enemy may be. On an empty map, ground units reach their destinations without getting stuck on terrain. When a unit is trying to reach its destination safely despite the enemy, a scouting unit or a drone transferring to another base, the unit reacts to dangers by leaving its path and running away from the enemy. It is not able to figure out a way around (though it may blunder into one), and it is not able to tell when its path is completely blocked and it should give up. So overlords scout less safely and less efficiently than they could, and worse, drones trying to transfer may end up burrowed all over the map, wasting supply and risking their lives to achieve nothing.

Steamhammer needs true safe pathfinding. It has to recalculate safe paths when the enemy is sighted. That opens the door to a lot of more specific skills.

• Don’t send drones to a place you know they can’t reach. This alone would save many games.
• Don’t even spawn extra drones inside a tight contain. They won’t get out.
• Better scouting, from maneuvering the early scouting worker to moving overlords and the Recon squad.
• Calculate least-danger paths for harassment. You can take hits as long as you escape.
• Similarly for drops.
• Reach safe spots to attack walls or other stuff from outside enemy range.
• Enemy vision is a kind of danger too. Find sneaky paths.
• Path through nydus canals. Nydus canals are part of my plan to support islands.

I don’t know how many of these I’ll get to by SSCAIT. There is a lot to it: Ground units and air units have different needs, safe paths and least-danger paths are different, sneaky paths are different. Safe drone transfers are the biggest weakness and have top priority. Part of the solution is to spread hatcheries out more, rather than putting all macro hatcheries in the main.

The first part of the job was to create a task manager to run background tasks. It’s simple, I wrote it yesterday. The idea is that pathfinding tasks will update safe pathfinding data structures behind the scenes, so that the calculation load is spread out and the data is reasonably up-to-date. Over time, I expect to add a lot of other kinds of tasks. Steamhammer runs fast, and for now there is little risk of overstepping the frame time limit. (Even in the late game when maxed, most frames take a handful of milliseconds, and spikes above 20ms are rare.) But I have thought up plenty of complicated tasks, and it seems likely to become an issue someday. I want the infrastructure to be ready, so that I can implement a principled solution instead of refactoring a lot of code when the day arrives.

Steamhammer 3.5.10 change list

Steamhammer 3.5.10 is the AIIDE 2021 tournament version. The current version on SSCAIT and BASIL is 3.5.2. The change list covers everything in between. I’ll upload the new version shortly, and source before long.

I wanted to improve lurker play to the point of having working lurker contain skills, but it was too ambitious for the time available. Even so, the improvements to lurker play should be easy to see. I soon decided it would be more effective to work on smaller fixes. There are always many short to-dos that each make a difference... because they accumulate faster than I can retire them.

tournament preparation

• Special preparation against 9 prospective AIIDE 2021 opponents—the ones it might make a difference against, plus Stardust where Steamhammer is at risk of scoring zero. I followed the same preparation plan as last year: For each opponent, choose a small number of builds that have historically won, or that seem to have good chances, and enter them into history as fictional single winning games. Let learning do the rest.

It amounts to giving hints “try this a few times before giving it up.” Steamhammer has a better chance of finding good builds early, and is not weighed down with masses of outdated learning data if the opponent brings surprises.

information

• Remember whether the enemy has used psionic storm this game. I wanted to feed the information into lurker spacing decisions, but ended up not implementing lurker spacing, so the feature is unused for now. There are other potential uses.

static defense

Changes to static defense include tuning to make the right amount in different situations—zerg static defense is expensive, and needs to be worth it. I think the tuning is improved versus terran, fairly good versus protoss, and still weak versus zerg.

• Fixed a crash due to division by zero. The bug fix does not affect strength, because the crash only happened when Steamhammer had no bases left. Yes, it was dividing by the number of bases. How easy it is to forget that you may already be dead! For my part, I forget that nearly every day.

Morph forgotten creep colonies into sunkens or spores, if and when they happen to be needed. The building manager sometimes slips up and forgets to morph a creep colony that was intended to become static defense. If defense is not needed, it will remain a creep for the time being. When the static defense planner decides that it is needed, it may turn into either a sunken or a spore. At some point I’ll implement tactical analysis and Steamhammer will have an idea of when the enemy might attack in strength. Then it will be able to leave all colonies until they are needed.

Try to place spore colonies in the mineral line, rather than somewhere vaguely near the hatchery. This helps ZvZ the most.

• Make one sunken colony less per base, compared to before.

• If the enemy has many tanks with siege mode, sharply limit the number of sunkens. They become a waste of minerals.

• Make more spores versus mass wraiths and mass scouts.

buildings

Anti-cannon sunken reaction failed due to errors in building placement introduced in a recent version. Fixed.

• Other attempted improvements to anti-cannon sunken placement.

• Added configuration option Config::Skills::UseSunkenRangeBug so that I can turn the feature off when it’s not allowed. It’s part of building placement; see BuildingPlacer::getAntiCannonSunkenPosition(). It’s off for AIIDE, where use of the bug is not allowed. It’s on for SCHNAIL, since it’s allowed in human games.

Steamhammer might try to build a macro hatchery directly on top of the main hatchery in the opening. The hatchery failed to build and the drone assigned to build it was left idle for a time, a serious breakdown. Fixed.

• In rare cases, a building might be placed invalidly so that it could not be built. Fixed.

squad orders

• Each squad keeps track of the last time its order was changed to a different target. It also remembers the most recent frame that any cluster of the squad attacked, and the most recent frame of a retreat. (“Attack” usually means that the combat sim said “go attack”, not that any unit fired a shot.)

• The above info is used by the air squad in deciding whether to keep attacking its current target, or seek an undefended target of opportunity. If the last attack was a long time ago and the last retreat was just now, then the mutas are sitting around and should try another target. They look for the closest undefended thing and try that instead. Unfortunately, the closest undefended target is often as inaccessible as the original target—it can be attacked in theory, but Steamhammer doesn’t have the smarts to do it in practice. So far, the feature is not worth the effort I put into it. I think it will become worth it when I implement more pathing and harassing skills.

• In defense, defeat enemy proxy pylons when nothing more dangerous threatens. There was always code to do this, but it was broken in a subtle way. The method for assigning units to squads is too complicated; I’ve got to find a better idea.

• In defense, count an enemy proxy creep colony as 2 units, not 1. When pulling drones to defeat the proxy before it can finish morphing into a sunken, Steamhammer will pull 4 drones and win the fight instead of 2 drones and lose. (3 drones would be ideal, if no other unit interferes.)

recon squad

The Recon squad has been a valuable feature ever since I implemented it. But lately Steamhammer has become strong enough that Recon’s weaknesses are hurting. For example, classically the Recon squad only pays attention to units that it can see, ignoring the remembered positions of enemy units, because its purpose is to see what’s going on. But suppose the squad consists of 1 zergling and it wants to scout an area defended by a sieged tank. The ling approaches to see, gets splatted by the tank. Another ling is assigned, approaches, splatted, etc., until the target times out. The process is, as people say nowadays, unsustainable.

I made 3 changes. None is critical in itself, but together they make the Recon squad safer and more effective and count as an important improvement.

• Combat sim attends to all enemy units, as for other squads, not only visible enemy units.

• When the squad is restored after it has become empty (for any reason, not only losing all units to the enemy), reset its target to somewhere else.

• Don’t assign the squad a target that is already in view. If the Watch squad or an overlord can see the target, the Recon squad doesn’t need to. As always, if no targets need scouting, disband the squad.

irradiated squad

I improved the behavior of irradiated units, but it still doesn’t work as intended. I’m convinced that bugs are hidden somewhere in the infrastructure code, not in the top-level decision code.

• The code was already clean, but I simplified it a little more.

• An irradiated unit keeps farther away from its friends than before. This is the most important change, even though the old distance was already outside the irradiation splash range.

• Flying units seek in a wider radius to find enemy units to splash radiation onto. Mutas are fast and may get there in time to do a little splashing.

• A slight change to burrow decisions.

scouting

• Release the scout worker early in a few special cases: If there is an overlord nearby to continue the scouting work; if the scout runs into a completed enemy bunker or photon cannon. There are details to the conditions; for example, if no enemy unit type has been seen yet beyond those the enemy had at the start of the game, then the scout stays on the job. Steamhammer usually scouts early, and returning the scout is economically good. An enemy bunker or cannon (if not a proxy) means on the one hand that the scout cannot advance, and on the other that the enemy has no intention of attacking right away, so Steamhammer can return the scout now and wait for zerglings to arrive to keep watch.

squad tactics

Don’t retreat forward if the enemy is near at all. The feature was meant to fix the case where one cluster of units is attacking the enemy, while a smaller cluster farther away was afraid to approach because it could not win on its own. But if an enemy was between the two clusters, which could happen despite a triangle-inequality test to try to prevent it, the cluster retreating forward would walk through the enemy and get shredded. Instead, a Regroup cluster close to an Attack cluster is itself changed to Attack in a second pass through the cluster status decisions before they are executed. The failure cases are non-horrible, and the change fixes one of Steamhammer’s biggest tactical weaknesses. At some point I’ll rewrite it so that clusters fighting the same enemies are treated together, not separately, but that’s for the future.

Enemy unit clustering is turned on, so that known enemy units are grouped into clusters just as Steamhammer’s units are. The config option Config::Debug::DrawClusters draws the enemy clusters in red circles to contrast with Steamhammer’s clusters in white circles. The enemy clusters are used in various decisions at the cluster and unit level.

An unhandled case led to poor lurker retreat decisions. I rewrote the code to simplify it and fix the bug.

When retreated all the way to the retreat point, lurkers burrow and tanks siege. Formerly, both remained ready to move, which meant that they were unready if the enemy advanced. It may not sound important, but it’s a big improvement. Indecision between advancing and retreating is common, which causes the familiar burrow/unburrow frenzy, but it’s a net gain by a wide margin.

• When retreating, count a sieged tank or a burrowed lurker as immobile defense, an option to retreat toward. Formerly, Steamhammer only looked for static defense.

• When seeking a cluster ahead to join this cluster with, use the squad’s order distance instead of the air distance. The order distance is the ground distance for ground clusters or the air distance for air clusters. This fixes some poor decisions made by ground units near terrain features.

• The code to retreat behind static defense was rewritten to be correct for a change. The actual behavior doesn’t change much, though.

• Be a little quicker to declare overlord danger at a base, so that new overlords are not spawned there to die uselessly.

combat sim

• The configuration option Config::Debug::DrawCombatSimInfo now draws information for each cluster, rather than for the most recent cluster simulated. It shows both the raw and the smoothed attack/regroup results, so you can see how the raw results flip-flop more. Combat sim is that much more debuggable—still not very.

A bug could leave the combat sim in an out-of-date state. Fixed. The bug (mentioned earlier in Steamhammer is progressing) is responsible for most or all of the 50-100 elo strength loss on BASIL in version 3.5.2. It’s what caused units to sit back instead of, say, attacking an undefended base.

• The radius to look for enemy units to include in the combat sim is altered to match what the Squad code does. I think this is a no-op; the enemy units that end up included are those in range to fire into the combat radius, which is different. But it looks tidy.

micro

Cancel a dying egg, cocoon, or unfinished building 1 second before it is predicted to die, not 5 seconds as previously. Lurker eggs were being canceled almost the moment they came under attack, which was bad. The gain of canceling items later outweighs the loss of a few units that come under sudden massive attack and die before they can be canceled.

• In figuring out which direction to kite a hydralisk, Steamhammer knows not to kite back into its own ground units—they are in the way. But it did not check whether the units were burrowed. Hydras had trouble kiting when near burrowed lurkers, because escape paths appeared to be blocked. Fixed.

terran

• Slightly improve the stim calculation, so that marines overstim a little less. It’s a change made in passing while I was working on other stuff, under the rule “if you see it now, fix it now.” (If it were possible to follow this rule all the time, there would be no such thing as technical debt.)

zerg

Macro: Steamhammer did not always make enough macro hatcheries due to a bug. That hurt a lot. Fixed.

• Macro: Make no macro hatchery unless there are at least 3 drones per base. Yeesh. It sounds basic, but the drone count never entered into Steamhammer’s calculation of whether it needed a macro hatch. This is a lenient limit that prevents rare egregious blunders (which I have seen happen). I expect I’ll tighten it in the future, one way or another.

• Macro: I noticed that Steamhammer sometimes became briefly supply blocked in the early middle game. I tweaked an overlord timing parameter by 1 point of supply, which fixed it.

• Macro: Fixed a potential production freeze related to air upgrades. This is a rare freeze; I'm not sure it has ever happened. When I fixed it, I thought it was a less-rare freeze that can happen when the enemy goes mass air. Then I discovered I was wrong. I have fixed the more important freeze, but not in time to get it into this version.

• Queue sunkens ordered by the strategy boss (as well as those ordered by the static defense boss, a change made in version 3.5.2), rather than posting them directly to the building manager. I never saw the old code cause a problem, but it’s likely that the change fixes rare misbehaviors.

• Queens: Be more flexible about parasiting high-priority targets instead of waiting for a good ensnare or broodling. If there is no tank in sight and the queen suddenly notices an enemy dropship, it should know what to do. A parasited dropship cannot surprise you.

• Queens: Get ensnare much less often versus terran, and a little less often versus protoss. I find the improvement in terran play to be visible.

• Defilers: A defiler that is about to die wants to cast a last spell. It’s done in part by a hit point test. Formerly, if the HP were too low but the enemy was gone, the defiler might (say) swarm itself, then consume, then swarm again nearby because the HP were still low, etc. There was often little or no gain, and the consumed zerglings did not appreciate it. Now the defiler only casts its low-HP Hail Mary spell if the enemy is around to shoot at it. (Being irradiated, stormed, or plagued also brings a Hail Mary.)

Lurkers: Avoid burrowing in tank or cannon range unless friends are along to help. This reduces the tendency of lurkers to rush in where angels fear to tread, though they’re still pretty foolish.

• Lurkers: Undetected lurkers look around harder for dangerous enemies nearby before unburrowing.

• Unit mix: Discourage guardians more overall. Discourage ultralisks and encourage hydralisks versus battlecruisers more. Favor hydras a little more versus wraiths. I think guardians may finally be tuned almost acceptably for Steamhammer’s current poor skill with them.

• Unit mix: When seeing 2 or more starports and no other air units, assume wraiths are likely and nudge the unit mix toward countering them. Steamhammer doesn’t make many predictions, but this one seemed important.

• Unit mix: Dark archons discourage queen production, though they don’t always eliminate it.

• I found that some urgent defensive reactions were happening too slowly. Therefore, first, call makeUrgentReaction() twice as often. Second, when making an anti-cannon sunken, it is allowed to start the creep colony before the spawning pool finishes. (Starting the creep before the prerequisite finishes for the final morph to a sunken or spore was already supported in other cases.)

Upgrades: Better code for ground upgrades. Historically, in long games Steamhammer went for ultra-ling in all matchups, and I wrote rigid upgrade code to match. It got carapace and then melee attack upgrade, and that’s all, correct preparation for the ultra-ling unit mix, with an exception added later for ZvZ to get melee attack first. Today Steamhammer varies its unit mix more sensitively depending on the situation, and may stick with or switch to hydralisks in the late game if they’re called for. I rewrote the code to be simpler and more flexible. In the planning phase, code puts any or all of melee attack, missile attack, and carapace into priority order depending on the matchup and game situation. In the execution phase, code assigns the top priorities to available evolution chambers.

In ZvT, Steamhammer gets missile attack if it is making hydras to fight goliaths or battlecruisers, because the terran is likely to stick with them. In ZvP, Steamhammer likes hydras and usually gets missile attack first and carapace next, though it depends. In ZvZ, with less variety, upgrades are about the same as before, except that there are extra rules if hive tech is reached. To my eye, play is clearly improved, especially in ZvP. Though the behavior is a lot more complicated, the total code size is small and about the same as the old rigid code.

• Upgrades: Fixed a minor bug where Steamhammer thought it could upgrade in an uncompleted evolution chamber. The worst case result was that the bot might slightly underspend its money on this production round.

openings

Overgas+1 build added to use more of that fast gas. Only one new opening! Is it a record low?

Tomorrow: What’s next for Steamhammer?

Steamhammer 3.5.1 change list

Yesterday I uploaded Steamhammer 3.5.1 to SCHNAIL, as Steamhammer, Randomhammer, and Crazyhammer. At least some games today still seem to be running the old version, though. I’m not sure how the details of update work.

This version concentrates on changes to improve play against humans, though I expect some of the changes to help against bot opponents too. The headline skill is new static defense analysis, which should help Randomhammer’s terran and protoss against all opponents, and zerg against humans. If performance is as good as I hope, I’ll soon upload to SSCAIT too. But I expect real games to look different from my test games.

static defense

New StaticDefense module makes decisions about static defense timing and placement for all races. (Special zerg reactions to events like rushes and proxy bunkers still exist, so the new code doesn’t handle all static defense.) The former code was only for zerg. The new code is more general and capable, and simpler in key aspects. It should be easier to work with. Like the old code, it understands that ground defenses at a natural base also protect the main base behind it, and it understands that drops bypass those defenses.

One frame it examines the situation and makes a plan for what anti-ground and anti-air static defense is needed. The next frame it starts to carry out the plan, including building prerequisite tech like an engineering bay for turrets if needed. After a fixed delay, the cycle repeats. The terran plan only calls for turrets; it’s easily extended to make bunkers, but Steamhammer doesn’t have the skills to use bunkers properly as static defense (its only skill is to put marines that it already has into a nearby bunker if the enemy is nearby too). The protoss plan calls for cannons at all necessary places to defend against cloaked units, vultures, drops, and air attack. The zerg plan is comprehensive. It makes one spore at one or two selected bases to preserve overlords if needed, or the required number of spores at all bases to defend against air attack. Steamhammer should do better against mass wraiths and mass scouts, which human players occasionally go for, and better in ZvZ when far behind in mutalisks. Sunkens are concentrated at the front line base versus bots, because nearly all bots go straight there, and spread to all exposed bases versus humans, because humans like to wipe out unprotected bases first. (At some point I want to add a SkillKit skill to remember the opponent’s past behavior, so that Steamhammer doesn’t have to rely on a blanket heuristic.)

The overall effect should be that zerg is resilient in a slightly wider range of situations, while terran and protoss become better able to survive common attacks like DT rushes, mutalisks, and drops.

Detailed building placement is not improved. I did nothing with the building placer to ensure that that defenses cover approaches or buildings or the mineral line, etc. Sometimes turrets are in a tight line, so that half the mineral line is overprotected and half is open. One step at a time.

• To support this, I moved getMySpireTiming() from the zerg strategy boss to the information manager. I also updated it to work in the case where the bot is making more than one spire simultaneously (which it could do if the opening build explicitly codes it). In ZvZ, if your mutas are far enough behind then you have to start preparations for a spore colony before the enemy spire finishes.

• I moved the “front point” for defense from 7 tiles away from the hatchery to 5 tiles away. It helps zerg place sunkens in a tighter group, and should not hurt terran or protoss.

squad orders

• Assign more anti-air defenders when under attack by protoss scout air units. 2 hydras per scout were not reliably enough; 3 should do it.

• Watch squad: In ZvZ, don’t watch as many bases. Expansions are few in the matchup, and the zerglings are more valuable in combat.

• Watch squad: Don’t waste a ling trying to watch a base which is covered by enemy defense, such as a sieged tank or a cannon.

• Watch squad: Smaller combat sim radius—let the enemy get closer before fleeing.

• Watch squad: An unburrowed zergling watching a base tended to oscillate around the base position, rather than sitting still, churning useless commands. When originally implemented, the Watch squad did not misbehave like that. I found 2 bugs born since then, each of which independently caused oscillation: 1. Being at the order point automatically made a unit “near the enemy,” so that it might run away a short distance though not actually near the enemy. 2. In the distances grid used for pathfinding, the grid 0 point could be slightly offset from the true goal position. I decided to allow some tolerance.

micro

Diagonal movement, lack of which I noted as a disadvantage in Steamhammer’s pathfinding. Units often get where they are going faster, which should help in all matchups versus humans or bots. On the other hand, I’ve noticed that the orthogonal movement can sometimes sneak past the opponent’s army and let Steamhammer make a surprise attack. There is always a tradeoff.

Try to stay out of tank range when not actively attacking. Steamhammer mostly keeps retreated units out of enemy fire, but there are exceptions. The worst was leaving ground units nearly, but not quite, outside of tank range; given time, one enemy tank could destroy an entire ground army (common versus humans who benefit from zero-APM passive defense, rare versus bots). I made 2 changes to fix it. 1. A retreating unit checks an attack map to make sure it is out of range; if not, it hasn’t retreated far enough. 2. The combat sim seeks enemies in a wider circle if there is a risk of sieged tanks, so that it doesn’t overlook the enemy and wander back into range “because it’s safe.”

Canceling buildings under construction, as well as unhatched eggs and cocoons, when they are under attack and about to die, works again. I introduced bugs when I “improved” it, causing it to nearly always fail. Now it is both improved and reliable, which (surprising though it may be) is better than either alone. It also cancels earlier, at a predicted 5 seconds left to live, which may be too soon. I’m guessing 2 or 3 seconds might be best; it depends on how accurate the predictions are.

• Bug fix in handling irradiated units: They feared splashing their radiation onto zerg buildings, though radiation does not affect buildings. Buildings apparently have rad shielding. This was a minor bug with trivial effects. I found the bug while searching for known serious bugs in handling irradiated units, bugs that regularly cause severe mistakes in games, but I could not pinpoint any of them. Except for its deadly flaws, the code appears flawless.

queens

Queens are surprisingly valuable against turtling human terrans, so I put effort into improving them. But not much; these are all simple changes. Big improvements need more complicated work (but will happen in time).

• Configured to make up to 8 queens, up from the previous limit of 6.

• Get the queen’s nest a little earlier if we have reason to want queens or defilers, or a little later if we don’t. This should help Steamhammer get queens and/or hive tech sooner when needed, and delay the expense otherwise.

• Get ensnare less often in ZvT. The combat sim understands ensnare reasonably well, but the queens cast it at inappropriate times when it does no good. Broodling is more valuable with Steamhammer’s skills.

• Don’t get broodling if the enemy has too much air-to-air strength. Wraiths and corsairs love to shoot down queens.

• Versus both terran and protoss, a higher threshold to get broodling in the first place, but once the threshold is crossed, a greater number of queens to use broodling. It’s an efficiency improvement.

• Changes to the scoring for queen broodling targets: A bigger bonus for a target which is defense matrixed. A discount for a plagued target. A bonus for a target under dark swarm. A slight increase to the bonus for already being in range, so that the queen doesn’t have to move in.

zerg

Defense against proxy cannons: Attempt to exploit the sunken range bug. This is one of 2 main expert defenses against cannons behind the minerals (the other is to push workers through the minerals to fight). If it can, Steamhammer will place a sunken which is in range of a pylon and out of range of the cannon or cannons that the pylon powers. When the cannon fires on the hatchery (or on anything else), the Brood War bug will cause the sunken to target the cannon even though the cannon is out of range and cannot fire back at the sunken. Use of this bug seems to be universally legal. If it works as intended, it should stop many tries to put cannons behind the minerals (if the cannons are too early, the hatchery will instead be canceled, or never started, and Steamhammer will have to destroy or play around the cannons).

No bot yet has tried to cannon behind Steamhammer’s minerals. Human protoss players do it often. It doesn’t always win, but with the right followup it’s effective.

• Defense against proxy cannon pushes: More often place multiple sunkens versus surrounding cannons. Opponents, both humans and MadMixP, are increasingly creeping cannons around the edges of the defense zone of Steamhammer’s single anti-cannon sunken.

• A high score for a defiler to place dark swarm over burrowed lurkers, and a lower score over unburrowed lurkers. A minor change.

• Adjust defilerScore higher against protoss dragoons. That will make Steamhammer get defilers earlier—see the item about the queen’s nest timing above under queens.

• The remaining zerg items are adjustments to the unit mix scoring. I adjusted existing scoring terms to reflect results against humans on SCHNAIL, adding only one new term. Human players pose unit mix problems that bots do not. ZvT unit mix adjustments: Wraiths more encourage hydras. Valkyries more strongly discourage guardians and encourage devourers.

• ZvP unit mix adjustments: Lower global bias toward ultralisks. All protoss air encourages hydras. Corsairs and scouts more discourage guardians and encourage devourers. Carriers discourage devourers. The new scoring term is that merely having a stargate (which could be an inferred stargate; it doesn’t have to be directly scouted) discourages guardians. Steamhammer has been making too many guardians against protoss, and uses them in a way that’s strong enough against bots, but fatally weak against humans.

• ZvZ unit mix adjustment: Guardians and devourers are both more discouraged in general. They should be rare.

openings

• In many terran and protoss openings, replaced go scout once around with go scout, meaning that the early worker scout stays inside the enemy base if it can. Compared to zerg, terran and protoss have more workers and can better afford to dedicate one to looking at stuff.

curious Steamhammer plays

Steamhammer understands that plaguing an archon doesn’t do much good. An archon has 350 shield points and only 10 hit points, and plague affects hit points only. But put enough archons together, and Steamhammer may calculate that it’s worth it anyway.

6 plagued archons in battle

Steamhammer intentionally errs on the side of excess plague. Plague on 6 archons destroys at most 6 * (10 - 1) HP, only 54. It’s questionable whether that’s enough to pay for the 3 zerglings the defiler consumed (the lings have the adrenal upgrade and do damage fast, but then again, they’ll die almost instantly against mass archons so maybe they weren’t worth much). Dark swarm might have been a better choice, but I don’t mind. As I said, it’s intentional, and anyway, Steamhammer was losing this game no matter what.

In this game versus Krasi0 on BASIL, Steamhammer selected an unsafe ZvP build. Almost all ZvT builds come with a lair pretty early; the exceptions that come to mind are rushes. This was a multiple-hatch-before-pool into 6 hatch hydra build with a late lair, sensible against sufficiently slow protoss play, senseless against typical terran barracks play. Somehow Krasi0 steered right into it, starting with its thou-shalt-not-rush-me ramp bunker and continuing with goliaths. Hydras are strong against goliaths.

Both bots have a lot to learn about strategy.

interesting Chobo-Steamhammer game

The SCHNAIL web site was updated as promised, and looks much prettier. On the leaderboard, “Download” is still spelled “Dowload” though.

Today is an interesting game from SCHNAIL, Chobo (P) vs Steamhammer on Python. Chobo played corsair-reaver with mass reaver drops to destroy bases and an eventual switch into carriers, a classic strategy I have never seen used against Steamhammer. It’s a demanding strategy for both players. Protoss must be fast and aggressive with drops, never leaving its expensive forces long at home because zerg grows back fast. And zerg must cope with the overwhelming splash damage of reavers on the ground and corsairs in the air—the units may not work against Monster, but they are deadly against Steamhammer. Classic zerg play against corsair-reaver includes burrowed zerglings around the map to see the reaver drops coming, a skill that Steamhammer does not have.

Corsair-reaver depends on a heavy force of tech units, so it launches slowly. Chobo curiously did not take the natural, but blocked the ramp with 2 zealots and a dragoon while teching, then took the nearby island base—which, by the way, I think Steamhammer never discovered. Steamhammer luckily started with a 3-hatch strategy before it scouted the protoss base, so it did not fall behind right off. A one-reaver probing drop did light damage at the zerg natural, then the reaver relocated to the morphing zerg third to try to prevent it. But scourge chased the shuttle away and hydra-ling chopped the reaver. Chobo learned a little caution.

Seeing the reavers, Steamhammer elected to make mutalisks despite the corsairs. It does understand the tradeoff risk... in a vague way. Soon protoss moved down the ramp to take the natural as a third base. By this point, Steamhammer was worried by the powerful-looking protoss force and went with army over economy, starting to fall behind. Chobo tried a 2-reaver drop at the zerg third and killed the defending sunken, but the drones burrowed and protoss left rather than risk the reavers. Still, with 2 bases and another coming versus 3 undersaturated zerg bases, protoss was ahead. Chobo dropped again, again killing the replaced sunken and again retreating. Seeing the drones instantly burrow and unburrow as the reaver appeared and disappeared must have been amusing.

protoss moves into the natural

At this point I think the human player began to go wrong. Chobo made defensive cannons and moved by air to take a 4th base, dedicating reavers and adding ramp cannons for its defense. Chobo was perhaps concerned about APM and reaction speed, limited resources if you’re human. But a human can’t outmacro Steamhammer without keeping pressure on. The reavers in speed shuttles are highly mobile. If protoss wants to take another base, I think it’s correct to airlift in minimal defense and rely on the main force to fly to the rescue in case of trouble. In case of no trouble, those reavers want to be blowing stuff up, or at least threatening to. Anyway, a zerg base was morphing below the new protoss base, and the hatchery did not last long. But Steamhammer, seeing more cannons and not seeing more army, correctly concluded that it could make drones and tech up. At the time of the picture, defiler consume is researching.

plus one protoss base, minus one zerg base

Steamhammer poked the protoss main with its mutalisks, and Chobo responded by chasing the mutas back to the zerg base and eradicating them, with minor corsair losses. Steamhammer does not understand that air units can scatter and keep fleeing, it believes they have to make a last stand to defend the base. Zerg was reduced to 15 army supply versus 52 army supply for protoss.

It didn’t matter. Zerg had the economy and soon reached its drone limit of 75 (this was Steamhammer 3.4.8, not 3.5 which has a limit of 65). When the corsairs and shuttles moved toward the zerg army, they were plagued and then ensnared, so that the outnumbered mutalisks (11 corsairs with attack +2, 10 mutas with carapace +2) held the upper hand. Protoss dropped the zerg third again, this time with mass reavers and disruption web, and eradicated it. With an observer, the reavers wiped the burrowed drones too. Steamhammer countered in the protoss natural with dark swarm and zerglings and returned the favor. In the picture, Steamhammer has realized its mineral excess and is adding hatcheries to burn it off—and meanwhile, the overloaded human can’t keep up with macro (watch the APM figures).

ensnare and plague, ouchies

Carriers arrived and there was more fighting, but the strategic position was decided. Drones and hive tech beat reavers and carriers. The picture is shortly after a base full of drones was destroyed, but as soon as the drones visible in the production tab finish, Steamhammer will have re-maxed its drone count.

dark swarm everywhere

I wish the game had lasted a little longer, so that I could see how well Steamhammer’s endgame scouting and clean-up of islands works. It theoretically has the skills, but so few opponents take island bases that they are untested in real games.

An entertaining game. A lesson for zerg bots: Defiler skills count! Steamhammer needed both plague and swarm to win. A lesson for human players: Keep the pressure on! There is one regular SCHNAIL opponent for Steamhammer who seems to enjoy playing tower defense as terran: Stay alive as long as possible with bunkers and tanks and turrets. The two have played dozens of times, and Steamhammer has won every game. Defending does not keep you alive, attacking keeps you alive.

movement simulation

Steamhammer is nearly prepared for AIST S4. I made 3 major improvements, plus smaller ones. Not everything I tried succeeded, though. Today I want to write about a new feature I implemented that is definitely valuable, and that Steamhammer will find uses for in the future even though my first use case didn’t work out as I hoped.

Steamhammer inherited from UAlbertaBot a weakness in retreating. It is Steamhammer’s longest-standing serious weakness. The point of retreating is to get away from a fight, so the units get move commands and ignore enemies they meet on the path to their retreat point. Nearly all cases where Steamhammer’s units run into or through or past enemies without fighting are because it is trying to retreat them. There are spectacular failure cases, like running ultralisks through a field of cannons and losing them for nothing. My past attempts to fix it have been half-hearted, since I want to delay coding a full tactical analysis until later. I thought I’d try something more courageous.

So I implemented retreat simulation in FAP. Moving is a lot easier than fighting, and it didn’t take much code. Pass in a target position, and our simulated units move to the position while the enemy’s keep chasing and shooting as usual, with no change to their side of the simulation. We’ll say the retreat “succeeded” if the fleeing units’ losses were lower than some percentage.

My idea was: If the regular combat sim said to retreat, then I ran a retreat sim in the same frame. If the retreat failed, then don’t run away, keep fighting regardless. The retreat sim runs fast because it is simpler, and also I cut its duration to only 2 seconds. I didn’t meet any problems with the frame time limit. In principle, the retreat sim can conclude “the cannon will kill us even if we run away, so keep hitting it,” and notice when the retreat path is blocked, and distinguish a faster force that can escape from a slower force that the enemy will chase down (yes the speedlings will kill your marines for free if they run, better to make a last stand).

In practice, the retreat sim might be worth it on average, but I was not convinced. The sim results were as noisy as ever, and there were times when it hurt. Also, in some situations it’s conceptually the wrong thing to do. Having the “retreating” ultralisks fight cannons is better than running past the cannons, but better yet is to understand the situation as an attack rather than a retreat, and to stand aside until you can win. And that seems to call for the tactical analysis that I was saving for later.

I called the internal routine in FAP not retreatsim() but rather movesim(), because it can answer many questions about when movement is safe.

  • Will this runby succeed in running by?
  • How far can the transport go before it must unload?
  • How many scourge will survive to hit their target?
  • Will this plague/broodling/etc. succeed, or will the caster be killed first?
  • If I mind control that unit, will it live to join my army?

And with a little more elaboration, questions like

  • If it lives to cast, will the defiler/queen/etc. also escape safely?
  • Is there time to unburrow/unsiege, or should the immobile units remain as they are?
  • Can the mutalisks pick off another marine and still get away without losses?

I think it’s a safe bet that Steamhammer will be answering some of these questions before AIIDE this year.

Steamhammer 3.3.5 change list

Here’s what’s new in Steamhammer 3.3.5, which is the SSCAIT tournament version. Play is visibly improved with this version, and I expected a significant improvement in results, but if so it’s not showing. Santa came by, and Steamhammer’s web page is updated with binary and source downloads.

production

The “build beside the base” bug (mentioned here) is fixed. It’s a damaging bug and the fix is critical, but the issue that learning hides bugs means that damage will be ongoing for a while yet.

Building manager can construct sunkens and spores when ordered, carrying out both steps itself. Formerly, laying down the creep colony, and then morphing it to a sunken or spore, were separate steps that had to be queued as two distinct items. Further, there was no connection between the queue items, so sometimes a creep colony intended to be a sunken instead became a spore, and vice versa. The change ensures that you get the static defense you ordered when and where you want it, and simplifies other code so that future features will be easier. The implementation is not perfect; a game against Stone shows that it can go wrong when the spawning pool is destroyed and has to be replaced.

• Fixed a production bug that prevented research from being done in a hive or greater spire. The result was a production freeze, so this is a critical bug fix, though the bug was rare. When I updated to BWAPI 4.4.0 I ensured that research could be ordered in a hive or greater spire, as newly allowed by the BWAPI version, but since my mind is a steel trap I was not clever enough to verify that the research succeeds.

scouting and information

• A terran scan counts as mobile detection. For some decisions, like how useful it will be to make lurkers, having ever seen an enemy scan counts the same as having seen a science vessel or an observer—it means the enemy has the tech. (The question “does it look as though this location is in range of an enemy detector?” is different and was already answered in version 3.3. See UnitUtil::EnemyDetectorInRange(), which did not need any code change under BWAPI 4.4.0 to notice enemy scans.)

• I was annoyed by games where Steamhammer’s drone scout was stopped by a bunker or cannons at the enemy’s front, and since it was unable to move forward, stuck there for the rest of its life as the game continued around it. Must scout—can’t scout—do nothing—die young after a wasted life. I added a rule to release the worker scout in that situation once friendly combat units arrive to keep an eye on the front. It will help the economy and my mood.

overlords

• Formerly, overlords not needed for any other purpose were assigned to wait at Steamhammer’s front defensive line, where the primary sunkens go if there are any. It turned out they were too vulnerable there; sometimes masses were shot down before they could escape. Now one overlord is assigned to the front line, and leftovers are sent to the current “main” base, where they are less available but safer. Occasionally the main base changes and they undertake a mass migration, but I haven’t seen it cause a problem.

• Assign overlords to watch island bases, when it is safe and with a low priority.

micro

MoveSafely() is smarter. Its purpose is to move a unit to its destination while avoiding enemy attacks. Now a moving unit in danger from enemy mobile attackers seeks nearby friendly units that can defend it—an air unit seeks anti-air defenders, while a ground unit seeks anti-ground defenders. It works by clustering all potential defending units, and looks for a cluster that it can reach. (Clustering is done centrally by the ops boss, on demand, and cached for the frame. A common case is that many overlords are independently moving safely, so that clustering is more efficient than seeking defenders unit by unit. It also provides more information for the decision, like how strong the cluster is.) If it doesn’t find defenders, or if it is in danger from a static building that can’t chase it, then it retains the old behavior of fleeing directly away from the attacker.

MoveSafely() has a safety margin. The margin is wider for a worker, and for a unit that has no regular attack (like a flying detector or a spellcaster). This is a big improvement that makes overlords safer. It has more effect in practice than the above change of seeking defenders. The reason there was no safety margin before is that I forgot it—I let myself be interrupted before I had entirely finished the feature. Concentration is important!

zerg

A bug caused gas mining to go severely wrong in a small proportion of games, persistently mining gas when it needed minerals more, a weakness that I originally fixed in version 1.0. In one game, only 3 drones survived and all of them mined gas the rest of the game even as gas built up to 8000 and minerals were out. I didn’t pin the cause down 100%, but the only code that could have caused it was a check that said “hey, I have too many drones and some are idle, there’s no loss in mining gas whether I need it or not.” I commented out the check, which never worked quite as intended anyway, and I haven’t seen the bug since. The ultimate error is likely in the worker manager.

All-new spore building code fixes further spore placement bugs beyond what the building manager changes fix. It is rather a lot of code change for a small behavior change, but the new code is more general and modifiable and future improvements will be easier.

• Limits on making sunkens and spores are slightly altered. Sunkens to protect against vultures and dark templar are possible minutely later in the game. It is a little more willing to add a spore despite already having a spire to defend with scourge.

• The building placer is a tiny bit smarter about sunken placement to stop cannon rushes and bunker rushes. I don’t notice any practical improvement.

• Steamhammer rarely had more than 1 queen on the map, though it is configured to keep up to 6 and often decided to make more than 1. Something is not right in the strategy boss. I switched it to make queens in batches, as resources allow, rather than one by one on each call “what should I make now?” Now it reaches as many as 2 queens on the map... there is still a bug somewhere. 2 queens are not an efficient number for broodling.

• Minor updates to support multiple defilers. Formerly, Steamhammer never made more than 1 defiler at a time, in part because defiler micro is cpu intensive (it was much more cpu intensive before I fixed its original bugs). I noticed that some opponents were quick to target the defiler, and killed defilers reliably so that little defiling occurred. Making more defilers, currently 2 at a time, is my attempt at a quick fix. It may help, though from games so far I think not much.

There is a small update to the strategy boss, to order more defilers up to a limit. Also, if the enemy is nearly dead, don’t make more than 1 defiler; it won’t be useful. Trivial changes to the micro controller for defilers, MicroDefilers, slightly improve efficiency; it already supported multiple defilers.

• Small adjustments to ZvZ counters in the strategy boss. Nobody will notice.

configuration

Config::Debug::DrawDefenseClusters draws the air defense and ground defense clusters used by MoveSafely() to find defenders to flee toward. A unit that can shoot both air and ground will belong to both an air defense cluster and a ground defense cluster. Static defense buildings are included in the clusters, so that (for example) an overlord fleeing a corsair may take refuge with a spore colony.

Config::Skills::MaxDefilers is added. It’s currently set to 2.

openings

• Added 9PoolSpeedSpire.

• Two related but different openings were named Over10HatchHydra. Oops. I renamed one of them to Over10HatchHydraB.

AIIDE 2020 - what Steamhammer learned

Steamhammer’s tables are fuller than others, partly because Steamhammer records more information than most bots and partly because I put more effort into analyzing my own bot’s results. Even so, the game records contain far more information than is summarized here. I have many features in mind that I’d like to add to my analysis scripts.

Some bottom line findings: 1. My preparation for specific opponents was largely successful, as far as it went. All prepared openings had at least a fair win rate, and most were among the most successful openings Steamhammer discovered throughout the tournament. 2. Steamhammer’s gas steal skill had value against many opponents, even though my first analysis of the skill suggested that it might not. (I have known for a long time that my first analysis had missed the truth.) It was able to judge pretty accurately whether stealing gas was effective versus a given opponent, so it could exploit it when successful and reduce the cost of trying it when unsuccessful.


#1 stardust

openinggameswinsfirstlast
10HatchBurrow186%96146
10HatchHydra10%4949
10Pool9Hatch10%3434
11HatchTurtleHydra70%379
11HatchTurtleMuta10%111111
12-11HatchLing10%6060
12HatchTurtle40%1329
2x10HatchAllIn20%53147
2x10HatchSlow10%3838
3HatchHydra10%00
3HatchHydraBust10%5858
3HatchLateHydras+110%5959
3HatchLingExpo10%5454
3HatchLurker10%104104
4HatchBeforeLair10%101101
4PoolHard10%11
4Scout20%4348
5HatchBeforeGas10%7070
5HatchPoolLing10%148148
5HatchPoolLingBurrow10%120120
5PoolHard2Player20%36118
5Scout10%4545
7HatchSpeed30%41117
8DroneGas10%3232
8Gas7PoolLurker B10%5151
8Hatch7Pool20%47139
8Hatch7PoolBurrow10%6363
8Hatch7PoolSpeed10%3535
9Hatch8Pool20%6771
9HatchMain9Pool9Gas20%5062
9PoolHatch10%9999
9PoolHatchBurrow10%4646
9PoolHatchSpeed10%6969
9PoolHatchSpeedSpire20%3773
9PoolSpeedAllIn10%3333
9PoolSpireSlowlings10%5555
AntiTyrLurker10%6666
AntiZeal_12Hatch70%8138
GuardianRush10%4040
Over10Hatch20%683
Over10Hatch1Sunk30%224
Over10Hatch2Sunk40%516
Over10Hatch2SunkHard20%1452
Over10HatchBurrow10%105105
Over10HatchBust297%74145
Over10HatchHydra20%8691
Over10HatchSlowLings20%420
OverhatchLateGas20%7795
OverpoolHydra10%3939
OverpoolSpeed10%126126
OverpoolSunk10%5656
OverpoolTurtle50%11134
Overpool_3HatchLing10%149149
Overpool_4HatchLing20%5768
PurpleSwarmBuild20%129140
QueenRush10%144144
Sparkle 3HatchMuta10%137137
ZvP_2HatchFakeMuta10%130130
ZvP_4HatchPoolHydra20%4464
ZvP_Overpool3Hatch10%7272
ZvT_2HatchMuta10%6565
ZvZ_12HatchMain20%61142
ZvZ_12PoolLingB10%3131
63 openings1502%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Heavy rush14899%2%10167%2%68%32%
Unknown21%0%4933%2%0%50%
timing#medianearlylate
my combat unit1503:021:515:35
my gas1483:231:157:50
enemy scout1501:571:172:41
enemy combat unit1502:382:214:47
enemy gas1504:163:598:20
enemy air unit59:497:4711:21
enemy cloaked unit59:497:4711:21
game duration1508:146:1618:36
gas steal#medianearlylatewinsenemy gas
gas steal decision152:131:483:350%4:25
gas steal success112:092:002:270%4:27
none or failed139---2%4:15
gas steal killed112:442:382:59


Steamhammer managed 3 wins with 2 different openings, but basically nothing worked despite trying the full range from 4 pool to hive rush. Stealing gas did not help, but the situation was desperate so Steamhammer tried it 10% of the time. An interesting number is the enemy scout timing: The scout probe arrived at the zerg base with more consistent timing (arriving in a narrower time window) than against any other opponent. Part of Stardust’s recipe is good scouting.


#2 purplewave

openinggameswinsfirstlast
11Gas10PoolLurker10%4343
11Gas10PoolMuta10%6565
11HatchTurtleHydra30%189
11HatchTurtleMuta20%1419
12-11Hatch20%4656
12Hatch12Pool10%8181
12HatchTurtle1315%10147
2HatchLingAllInSpire10%6969
2HatchLurkerAllIn20%2584
2HatchLurkerPure1315%85148
2HatchMutaPure10%128128
2x10HatchSlow10%111111
3HatchHydra10%140140
3HatchHydraExpo20%2467
3HatchLing30%075
3HatchLingBust210%5555
3HatchLingExpo20%74138
3HatchLurker10%6060
5HatchBeforeGas20%116144
5HatchPoolLing10%6868
5PoolHard2Player10%146146
6PoolHide10%118118
6PoolSpeed20%5862
6Scout10%149149
7DroneHatch10%141141
8-8HydraRush10%109109
8Gas7PoolLurker B10%108108
8Hatch7Pool1513%37127
973HydraBust10%104104
9Hatch8Pool10%7272
9HatchExpo9Pool9Gas714%51143
9PoolExpo10%4848
9PoolHatch30%34119
9PoolHatchSpeed7DroneB10%6666
9PoolHatchSpeedAllInB20%8896
9PoolHatchSpeedSpire10%3131
9PoolSpeedAllIn10%5353
9PoolSunkHatch10%9898
AntiFact_13Pool10%4545
AntiFact_2Hatch10%6161
AntiFactoryHydra10%7373
AntiWraith_2Hatch10%114114
AntiZeal_12Hatch110%4112
Over10Hatch40%518
Over10Hatch+110%7171
Over10Hatch11Pool10%7979
Over10Hatch1Sunk10%99
Over10Hatch2Sunk10%1616
Over10Hatch2SunkHard40%3100
Over10HatchBust10%2323
Over10HatchHydra10%8080
OverhatchExpoLing10%121121
OverhatchExpoMuta40%828
OverhatchLateGas10%2929
Overpool+110%115115
Overpool2HatchLurker10%110110
OverpoolHatch10%6464
OverpoolHide10%9393
OverpoolSpeed30%3382
OverpoolTurtle30%213
OverpoolTurtle 010%4242
Overpool_3HatchLing10%106106
ZvP_2HatchMuta10%6363
ZvP_3BaseSpire+Den10%102102
ZvP_3HatchMuta10%4949
ZvP_3HatchPoolHydra10%101101
ZvT_13Pool10%9999
ZvZ_Overgas8Pool10%9797
ZvZ_Overpool11Gas10%7070
69 openings1505%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Fast rush--64%0%0%0%
Heavy rush13389%5%7147%4%47%26%
Naked expand--21%100%0%0%
Safe expand1510%7%2215%0%7%27%
Turtle11%0%107%0%0%0%
Unknown11%0%3926%5%0%0%
timing#medianearlylate
my combat unit1503:061:537:55
my gas1503:251:1411:39
enemy scout1502:111:1914:11
enemy combat unit1492:552:186:22
enemy gas1475:113:518:40
enemy air unit10211:074:3916:47
enemy cloaked unit8711:427:1516:58
game duration15013:095:4625:41
gas steal#medianearlylatewinsenemy gas
gas steal decision152:131:583:000%5:10
gas steal success102:222:182:410%5:16
none or failed140---5%5:11
gas steal killed103:052:535:08


Steamhammer again desperately tried every tech and timing known to zerg, and this time found a little success with a few of them—a sunken build, a lurker build, and two 2-hatch zergling wave builds. PurpleWave largely stuck with 2 gates. Stealing gas barely delayed Protoss from taking gas, but Steamhammer still tried 10% of the time—if you’re losing almost all games, it doesn’t hurt.


#3 bananabrain

openinggameswinsfirstlast
11HatchTurtleHydra2730%2149
12-12Hatch10%6363
2HatchHydra10%1515
3HatchHydraExpo10%5555
3HatchLateHydras+110%11
3HatchLingBurrow1828%5139
3HatchLingBust22938%4140
4HatchBeforeGas10%99
4PoolHard10%1010
5PoolHard10%143143
973HydraBust10%00
9PoolHatchSpeedAllInB10%5757
AntiFact_13Pool2438%3137
DefilerRush333%144147
OverhatchExpoLing10%6161
OverhatchExpoMuta10%9494
OverhatchLateGas10%9898
OverpoolSunk10%110110
Overpool_3HatchLing10%3939
Sparkle 2HatchMuta10%4848
ZvP_3HatchPoolHydra1020%26120
ZvT_12PoolMuta812%46146
ZvT_13Pool1547%108148
ZvT_3HatchMuta10%8181
24 openings15029%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Fast rush128%33%75%0%17%42%
Heavy rush4228%21%3020%10%19%26%
Naked expand43%25%53%80%0%25%
Proxy--53%0%0%0%
Safe expand7147%31%3725%38%21%31%
Turtle2114%38%1812%67%10%43%
Unknown--4832%23%0%0%
timing#medianearlylate
my combat unit1503:111:474:11
my gas1453:212:136:42
enemy scout1501:451:156:55
enemy combat unit1503:092:196:37
enemy gas1395:222:479:41
enemy air unit1316:022:4711:18
enemy cloaked unit967:113:2614:06
game duration15010:224:4132:00
gas steal#medianearlylatewinsenemy gas
gas steal decision652:131:483:2337%5:19
gas steal success462:191:542:4039%6:04
none or failed104---25%5:07
gas steal killed465:472:4520:00


BananaBrain was the first opponent weak enough that Steamhammer was able to find answers and did not feel a need to throw in the kitchen sink. 2 hatch muta builds were the most successful (and the best was one specialized for play against terran), but zergling builds and hydra builds were also OK. I love that the defiler rush won a game (it’s not at all a practical opening, but against a bot...). Unlike Stardust and PurpleWave, unpredictable BananaBrain played a variety of builds—for example, the appearance of an enemy cloaked unit at 3:26 in one game suggests a dark templar rush. The gas steal was successful and delayed protoss from taking gas for nearly an entire minute, so Steamhammer went with it frequently.


#4 dragon

openinggameswinsfirstlast
2HatchLingAllInSpire850%35140
3HatchLurker1656%0148
4PoolSoft520%1747
5HatchPool5985%5146
5PoolHard2Player10%11
6PoolSpeed10%44
9PoolSpeedAllIn20%23
UltraRush333%142149
ZvT_3HatchMuta771%121147
ZvT_3HatchMutaExpo4078%49145
ZvT_7Pool850%5384
11 openings15070%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Factory5637%70%3624%53%46%25%
Heavy rush21%50%11%100%0%50%
Naked expand1711%82%1510%93%18%35%
Safe expand128%33%128%83%8%58%
Turtle11%100%11%100%0%0%
Unknown--4631%74%0%0%
Worker rush6241%74%3926%67%42%29%
timing#medianearlylate
my combat unit1413:171:477:58
my gas1133:471:4710:51
enemy scout1492:151:056:47
enemy combat unit1212:392:218:45
enemy gas1186:022:4311:45
enemy air unit1089:154:2217:01
enemy cloaked unit859:545:4316:34
game duration15015:073:0137:21
gas steal#medianearlylatewinsenemy gas
gas steal decision392:211:564:2072%6:02
gas steal success172:222:143:0665%7:07
none or failed133---71%5:52
gas steal killed174:263:185:08


Steamhammer upset Dragon. The success of 5 hatcheries before spawning pool means that Dragon was not aggressive early, to its detriment—or that Steamhammer recognized any early aggression as a rush and reacted correctly. 3 hatchery mutalisk builds were also good. Even 3 hatchery lurker was not bad, though on the face it appears unsuited to counter Dragon’s play style. The gas steal was not successful in terms of win rate, but Steamhammer noticed that it delayed Dragon’s gas for a long time so it tried anyway. Fewer than half the attempts to steal gas ended with the extractor successfully made, though. The 37 minute game (here 37:21, officially 37:22) was Steamhammer’s longest game of the tournament, except for a couple games versus EggBot that went to the 60 minute limit and had to be adjudicated on points.


#5 mcrave

openinggameswinsfirstlast
12PoolLurker10%5555
3HatchLingBurrow520%97126
8DroneGas1164%106148
9HatchMain9Pool9Gas20%52138
9PoolHatchSpeedAllInB10%1919
9PoolSpire20%5995
Over10HatchBust1942%62149
Over10PoolLing10%00
OverpoolSpeed1520%5135
OverpoolSunk2138%30128
OverpoolTurtle2348%66139
ZvP_3HatchMuta10%134134
ZvZ_12HatchExpo10%77
ZvZ_Overgas9Pool20%13
ZvZ_OverpoolTurtle4558%2146
15 openings15043%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Heavy rush2013%35%85%50%0%70%
Naked expand11879%45%3322%42%21%69%
Turtle96%44%43%25%0%78%
Unknown21%0%10469%42%0%50%
Worker rush11%0%11%100%0%0%
timing#medianearlylate
my combat unit1502:262:133:15
my gas1462:321:313:30
enemy scout1502:470:375:51
enemy combat unit1502:341:116:03
enemy gas1303:232:3211:09
enemy air unit1234:313:3710:10
enemy cloaked unit515:0611:4524:23
game duration15010:583:4129:42
gas steal#medianearlylatewinsenemy gas
gas steal decision102:001:542:4830%3:15
gas steal success0-----
none or failed150---43%3:23
gas steal killed0---


Steamhammer failed to recognize McRave’s build in 2/3 of games, though we know from yeterday’s post exactly what they were, and that they should not have been hard to understand. I put more effort into recognizing rushes and proxies that change the whole course of the game than into regular builds, and the result is that Steamhammer’s understanding and prediction are sometimes spectacularly unhelpful. The 8DroneGas build is actually a 9 pool which makes a second hatchery; it’s called that because it ends up with 8 drones while flooding zerglings (it’s not the Styx build, but related). 5 games had cloaked units; I think that means that McRave researched burrow, because it does use burrow and does not seem to ever make lurkers. Steamhammer was unable to steal gas in 10 attempts, so it gave up trying.


#6 microwave

openinggameswinsfirstlast
6PoolBurrow10%5050
8-8HydraRush10%131131
9Hatch8Pool520%6887
9PoolHatchSpeedSpire10%6060
OverhatchLing10%22
OverpoolBurrow10%121121
ZvZ_12HatchExpo540%117141
ZvZ_12PoolLing1164%0149
ZvZ_12PoolMain333%171
ZvZ_Overpool11Gas4473%3147
ZvZ_Overpool9Gas6489%8148
ZvZ_OverpoolTurtle1354%9140
12 openings15071%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Fast rush128%67%85%88%8%67%
Heavy rush4429%75%3221%91%20%32%
Naked expand9463%70%4228%67%23%45%
Turtle--43%75%0%0%
Unknown--6443%62%0%0%
timing#medianearlylate
my combat unit1502:261:573:14
my gas1502:061:382:45
enemy scout1502:251:174:53
enemy combat unit1502:411:495:25
enemy gas1295:212:349:37
enemy air unit1157:343:4615:33
enemy cloaked unit0---
game duration15013:323:4130:36
gas steal#medianearlylatewinsenemy gas
gas steal decision61:581:502:200%5:04
gas steal success12:212:212:210%6:40
none or failed149---72%5:16
gas steal killed13:163:163:16


Steamhammer found a variety of overpool openings to be best. Overpool is flexible; those openings play out quite differently. Microwave didn’t play 5 pool often because it didn’t work: Steamhammer’s rush recognition is improved this year, and it reacted well. The burrow openings and 8-8 dawn hydra rush are not appropriate for ZvZ; those choices could be improved. Unlike McRave, Microwave did not use burrow. Stealing gas failed, so Steamhammer gave it up quickly.


#8 daqin

openinggameswinsfirstlast
10HatchLing10%139139
11Gas10PoolLurker10%6363
12-12Hatch10%4242
12Hatch_4HatchLing20%82126
2.5HatchMuta10%9999
2HatchHydraBust20%5131
3HatchHydra20%20113
3HatchHydraBust30%497
3HatchHydraExpo10%5353
3HatchLateHydras+110%107107
3HatchLing5944%0147
3HatchLingBust220%2269
4HatchBeforeGas2520%13144
4HatchBeforeLair10%142142
5HatchBeforeGas20%12
5HatchPool10%128128
5PoolHard2Player10%6666
5Scout10%9393
973HydraBust40%373
9Pool8GasLurker10%9191
9PoolHatchSpeed10%3838
9PoolHatchSpeedSpire210%114114
9PoolHatchSpire10%6767
9PoolSpireSlowlings10%3131
9PoolSunkHatch10%9292
AntiFact_2Hatch10%8787
AntiFact_Overpool9Gas10%141141
AntiFactory210%116116
Over10Hatch1Sunk10%7676
OverhatchExpoMuta30%1747
OverpoolSpeed10%7272
OverpoolTurtle 020%106146
Proxy8HatchNatural10%4141
Sparkle 3HatchMuta617%120136
ZvP_2HatchMuta10%2525
ZvP_3BaseSpire+Den10%115115
ZvP_3HatchPoolHydra714%133149
ZvT_2HatchMuta10%5757
ZvT_3HatchMuta10%4343
ZvT_7Pool10%5959
ZvZ_12PoolLing10%7777
ZvZ_12PoolLingB20%103129
ZvZ_Overpool11Gas10%8888
43 openings15022%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Heavy rush--107%20%0%0%
Naked expand--53%80%0%0%
Safe expand3523%11%4832%21%37%6%
Turtle11476%25%8557%20%59%0%
Unknown11%100%21%0%0%0%
timing#medianearlylate
my combat unit1503:111:515:01
my gas1503:221:475:53
enemy scout1491:301:1511:34
enemy combat unit1504:494:066:51
enemy gas1485:424:438:31
enemy air unit3813:159:1026:30
enemy cloaked unit4812:114:4317:37
game duration15011:166:2236:26
gas steal#medianearlylatewinsenemy gas
gas steal decision312:141:583:0635%6:16
gas steal success312:222:083:1335%6:16
none or failed119---18%5:32
gas steal killed312:532:3813:06


DaQin upset Steamhammer badly, and zerg fell back on exploring widely. One ling bust and a few macro builds were able to save some games against DaQin’s consistent forge expand (which Steamhammer often misrecognized as Turtle because it did not actively look for the expansion nexus). The gas steal is measured to increase the overall win rate from 18% to 22%, not bad.


#9 zzzkbot

openinggameswinsfirstlast
8Hatch7Pool560%103133
9PoolHatchSpire425%14148
9PoolSunkHatch3067%3149
9PoolSunkSpeed1771%0136
OverhatchLing1464%108140
OverpoolSunk2050%1143
ZvZ_12Pool10%7979
ZvZ_OverpoolTurtle5997%13147
8 openings15075%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Fast rush4027%80%107%100%25%68%
Turtle11073%73%2718%70%22%78%
Unknown--11375%73%0%0%
timing#medianearlylate
my combat unit1502:252:143:06
my gas1482:382:017:07
enemy scout1502:380:394:01
enemy combat unit1502:411:534:31
enemy gas1215:272:248:21
enemy air unit626:346:238:35
enemy cloaked unit0---
game duration1507:544:2615:23
gas steal#medianearlylatewinsenemy gas
gas steal decision82:372:013:0175%5:27
gas steal success0-----
none or failed150---75%5:27
gas steal killed0---


ZZZKBot switches between its famous 4 pool (recognized as Fast rush; see the 100% win rate when the strategy was recognized) and a build with sunkens, two hatcheries, and 6 sudden mutalisks (recognized as Turtle). It seems that part of Steamhammer’s difficulty with ZZZKBot (I consider a 75% win rate to be low in this case) is due to poor scouting: See the rate of Unknown enemy strategies. A bigger part of it may be a problem with the exploration policy. ZvZ_OverpoolTurtle scored 97% and was discovered early, but was played in only 59 games out of 150.

Steamhammer does not use enemy scout timing as a clue to the enemy strategy, and it should. When a scout appears at your base in 39 seconds it must have been sent almost immediately. Either the enemy is rushing, or is terrified that you might. A comparison of past scout timings versus recognized strategies for this opponent could be strong evidence.

ZZZKBot takes gas only in its muta strategy, and then it has sunkens so that a gas steal cannot succeed. Steamhammer figured that out fairly quickly.


#10 ualbertabot

openinggameswinsfirstlast
973HydraBust10%129129
AntiZeal_12Hatch771%0142
Over10Hatch475%2141
OverpoolTurtle13799%1148
4 openings14996%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Factory107%100%1711%100%0%50%
Fast rush2819%93%2315%96%14%36%
Heavy rush11174%96%6040%93%44%22%
Naked expand--107%100%0%0%
Unknown--3926%97%0%0%
timing#medianearlylate
my combat unit1492:262:223:15
my gas1472:582:544:46
enemy scout1402:021:187:41
enemy combat unit1182:391:424:33
enemy gas1273:382:3713:12
enemy air unit3314:3110:4616:33
enemy cloaked unit3214:162:3716:33
game duration1498:273:4220:54
gas steal#medianearlylatewinsenemy gas
gas steal decision0-----
gas steal success0-----
none or failed149---96%3:38
gas steal killed0---


Steamhammer recorded only 149 games against UAlbertaBot, because it crashed one game, its only crash in the tournament. Against every other opponent, Steamhammer recorded all 150 games.

There was no need to test the gas steal. If you’re winning nearly all games, spending a drone to vary your play is not likely to gain anything. Another point is that UAlbertaBot often takes gas quite late, so stealing gas early is unlikely to pay off.


#11 willyt

openinggameswinsfirstlast
11Gas10PoolLurker4774%4149
12-12Hatch10%4646
2HatchLurker10%115115
4PoolHard520%258
9HatchMain9Pool9Gas1638%7148
9PoolSpeed3358%1141
9PoolSpeedAllIn2854%3145
GuardianRush540%123143
Over10Hatch2Sunk10%146146
Overpool_3HatchLing10%113113
Sparkle 3HatchMuta1145%65132
ZvT_3HatchMuta10%00
12 openings15055%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Factory--11%0%0%0%
Fast rush--11%0%0%0%
Heavy rush1611%62%1510%27%12%50%
Naked expand8657%53%3523%100%17%52%
Safe expand4832%56%3020%77%25%31%
Unknown--6845%31%0%0%
timing#medianearlylate
my combat unit1502:421:463:38
my gas1451:491:455:17
enemy scout1422:111:387:19
enemy combat unit1502:592:056:41
enemy gas1125:134:0410:07
enemy air unit1117:1310:4530:58
enemy cloaked unit2214:237:1019:33
game duration1508:484:4231:49
gas steal#medianearlylatewinsenemy gas
gas steal decision272:131:482:4367%5:45
gas steal success232:211:562:5770%6:19
none or failed127---53%5:11
gas steal killed234:063:004:43


WillyT was a tough opponent for Steamhammer. The choice of zerg builds does not seem strong. I have no idea how the guardian rush won 2 games out of 5.


#12 ecgberht

openinggameswinsfirstlast
11HatchTurtleLurker10%11
11HatchTurtleMuta757%8148
12HatchTurtle10%119119
9PoolLurker4791%0149
9PoolSpeed2576%3142
AntiStyx_9Pool475%121141
HiveRush875%89140
Over10HatchBust2282%2135
OverpoolLurker3591%4147
9 openings15083%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Factory3926%79%2416%79%28%26%
Fast rush3020%80%2114%90%10%40%
Heavy rush5637%89%2315%87%18%39%
Naked expand64%67%64%83%17%33%
Proxy85%75%53%60%0%50%
Safe expand85%100%85%75%0%50%
Unknown--5537%87%0%0%
Worker rush32%67%85%62%0%33%
timing#medianearlylate
my combat unit1502:182:113:17
my gas1501:551:457:07
enemy scout1441:270:305:18
enemy combat unit1483:011:556:53
enemy gas985:052:518:43
enemy air unit495:584:0119:55
enemy cloaked unit315:545:217:15
game duration1508:363:5222:29
gas steal#medianearlylatewinsenemy gas
gas steal decision222:171:485:4586%5:10
gas steal success132:232:005:5185%5:24
none or failed137---83%5:03
gas steal killed133:272:176:10


Ecgberht is a tricky opponent. If it knew how to defeat fast lurker builds, it would score a lot higher against Steamhammer.


#13 eggbot

openinggameswinsfirstlast
2HatchHydraBust367%3286
3HatchHydra786%70105
3HatchHydraBust367%52103
3HatchHydraExpo8100%15137
3HatchLateHydras+1683%1375
3HatchLingBust26100%12121
4HatchBeforeGas6100%7149
4HatchBeforeLair11100%16142
5HatchBeforeGas8100%1118
6PoolHide19100%5145
973HydraBust9100%6130
9PoolHide10100%27115
9PoolSunkHatch11100%0138
9PoolSunkSpeed7100%18148
AntiStyx_9Pool6100%8129
OverpoolHide14100%2146
ZvP_3BaseSpire+Den10100%11141
ZvP_3HatchPoolHydra683%30147
18 openings15097%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Contain5637%98%3322%100%23%43%
Proxy3523%97%2517%80%14%37%
Turtle5939%95%3725%100%20%31%
Unknown--5537%100%0%0%
timing#medianearlylate
my combat unit1502:261:584:09
my gas1393:432:388:31
enemy scout791:290:3110:17
enemy combat unit326:504:318:59
enemy gas0---
enemy air unit0---
enemy cloaked unit0---
game duration1506:504:0460:00
gas steal#medianearlylatewinsenemy gas
gas steal decision0-----
gas steal success0-----
none or failed150---97%-
gas steal killed0---


EggBot is a cannon bot. Its builds were recognized as Proxy for close cannons, Contain for cannons farther away from zerg bases, or Turtle for distant cannons. Steamhammer tried a variety of openings, discarding one as soon as it had lost a single game because there were others that still scored 100%. Steamhammer understood that EggBot never took gas, so gas steal would gain nothing.


overall

totalZvTZvPZvZZvR
openinggameswinsgameswinsgameswinsgameswinsgameswins
10HatchBurrow186% 186%
10HatchHydra10% 10%
10HatchLing10% 10%
10Pool9Hatch10% 10%
11Gas10PoolLurker4971% 4774% 20%
11Gas10PoolMuta10% 10%
11HatchTurtleHydra3722% 3722%
11HatchTurtleLurker10% 10%
11HatchTurtleMuta1040% 757% 30%
12-11Hatch20% 20%
12-11HatchLing10% 10%
12-12Hatch30% 10% 20%
12Hatch12Pool10% 10%
12HatchTurtle1811% 10% 1712%
12Hatch_4HatchLing20% 20%
12PoolLurker10% 10%
2.5HatchMuta10% 10%
2HatchHydra10% 10%
2HatchHydraBust540% 540%
2HatchLingAllInSpire944% 850% 10%
2HatchLurker10% 10%
2HatchLurkerAllIn20% 20%
2HatchLurkerPure1315% 1315%
2HatchMutaPure10% 10%
2x10HatchAllIn20% 20%
2x10HatchSlow20% 20%
3HatchHydra1155% 1155%
3HatchHydraBust729% 729%
3HatchHydraExpo1267% 1267%
3HatchLateHydras+1956% 956%
3HatchLing6242% 6242%
3HatchLingBurrow2326% 1828% 520%
3HatchLingBust23845% 3845%
3HatchLingExpo30% 30%
3HatchLurker1850% 1656% 20%
4HatchBeforeGas3234% 3234%
4HatchBeforeLair1385% 1385%
4PoolHard714% 520% 20%
4PoolSoft520% 520%
4Scout20% 20%
5HatchBeforeGas1362% 1362%
5HatchPool6083% 5985% 10%
5HatchPoolLing20% 20%
5HatchPoolLingBurrow10% 10%
5PoolHard10% 10%
5PoolHard2Player50% 10% 40%
5Scout20% 20%
6PoolBurrow10% 10%
6PoolHide2095% 2095%
6PoolSpeed30% 10% 20%
6Scout10% 10%
7DroneHatch10% 10%
7HatchSpeed30% 30%
8-8HydraRush20% 10% 10%
8DroneGas1258% 10% 1164%
8Gas7PoolLurker B20% 20%
8Hatch7Pool2223% 1712% 560%
8Hatch7PoolBurrow10% 10%
8Hatch7PoolSpeed10% 10%
973HydraBust1656% 1560% 10%
9Hatch8Pool812% 30% 520%
9HatchExpo9Pool9Gas714% 714%
9HatchMain9Pool9Gas2030% 1638% 20% 20%
9Pool8GasLurker10% 10%
9PoolExpo10% 10%
9PoolHatch40% 40%
9PoolHatchBurrow10% 10%
9PoolHatchSpeed20% 20%
9PoolHatchSpeed7DroneB10% 10%
9PoolHatchSpeedAllInB40% 30% 10%
9PoolHatchSpeedSpire40% 30% 10%
9PoolHatchSpeedSpire210% 10%
9PoolHatchSpire520% 10% 425%
9PoolHide10100% 10100%
9PoolLurker4791% 4791%
9PoolSpeed5866% 5866%
9PoolSpeedAllIn3247% 3050% 20%
9PoolSpire20% 20%
9PoolSpireSlowlings20% 20%
9PoolSunkHatch4372% 1385% 3067%
9PoolSunkSpeed2479% 7100% 1771%
AntiFact_13Pool2536% 2536%
AntiFact_2Hatch20% 20%
AntiFact_Overpool9Gas10% 10%
AntiFactory210% 10%
AntiFactoryHydra10% 10%
AntiStyx_9Pool1090% 475% 6100%
AntiTyrLurker10% 10%
AntiWraith_2Hatch10% 10%
AntiZeal_12Hatch2520% 180% 771%
DefilerRush333% 333%
GuardianRush633% 540% 10%
HiveRush875% 875%
Over10Hatch1030% 60% 475%
Over10Hatch+110% 10%
Over10Hatch11Pool10% 10%
Over10Hatch1Sunk50% 50%
Over10Hatch2Sunk60% 10% 50%
Over10Hatch2SunkHard60% 60%
Over10HatchBurrow10% 10%
Over10HatchBust7139% 2282% 307% 1942%
Over10HatchHydra30% 30%
Over10HatchSlowLings20% 20%
Over10PoolLing10% 10%
OverhatchExpoLing20% 20%
OverhatchExpoMuta80% 80%
OverhatchLateGas40% 40%
OverhatchLing1560% 1560%
Overpool+110% 10%
Overpool2HatchLurker10% 10%
OverpoolBurrow10% 10%
OverpoolHatch10% 10%
OverpoolHide1593% 1593%
OverpoolHydra10% 10%
OverpoolLurker3591% 3591%
OverpoolSpeed2015% 50% 1520%
OverpoolSunk4342% 20% 4144%
OverpoolTurtle16887% 80% 2348% 13799%
OverpoolTurtle 030% 30%
Overpool_3HatchLing40% 10% 30%
Overpool_4HatchLing20% 20%
Proxy8HatchNatural10% 10%
PurpleSwarmBuild20% 20%
QueenRush10% 10%
Sparkle 2HatchMuta10% 10%
Sparkle 3HatchMuta1833% 1145% 714%
UltraRush333% 333%
ZvP_2HatchFakeMuta10% 10%
ZvP_2HatchMuta20% 20%
ZvP_3BaseSpire+Den1283% 1283%
ZvP_3HatchMuta20% 10% 10%
ZvP_3HatchPoolHydra2433% 2433%
ZvP_4HatchPoolHydra20% 20%
ZvP_Overpool3Hatch10% 10%
ZvT_12PoolMuta812% 812%
ZvT_13Pool1644% 1644%
ZvT_2HatchMuta20% 20%
ZvT_3HatchMuta1050% 862% 20%
ZvT_3HatchMutaExpo4078% 4078%
ZvT_7Pool944% 850% 10%
ZvZ_12HatchExpo633% 633%
ZvZ_12HatchMain20% 20%
ZvZ_12Pool10% 10%
ZvZ_12PoolLing1258% 10% 1164%
ZvZ_12PoolLingB30% 30%
ZvZ_12PoolMain333% 333%
ZvZ_Overgas8Pool10% 10%
ZvZ_Overgas9Pool20% 20%
ZvZ_Overpool11Gas4670% 20% 4473%
ZvZ_Overpool9Gas6489% 6489%
ZvZ_OverpoolTurtle11777% 11777%
total179954%45070%75031%45063%14996%
openings played15129130304


This is not all of Steamhammer’s zerg openings! The tournament wasn’t long enough for it to try everything.

tournaments and tournament preparation

The CoG conference is underway from today through Thursday. It is of course entirely online in this plague year (did somebody let a defiler loose?). I expect the CoG 2020 tournament results to appear during the conference or not long after. The conference program does not announce a time, as far as I can see. You can look back at my expectations if you like.

I am working hard to prepare Steamhammer for AIIDE 2020. I have already uploaded 3 different test versions one after another to the Starcraft AI Ladder, and I have made good progress on the next test version to go up in a day or two. Each version shows some kind of progress in its play, though the win rate does not always go up. The AIIDE update will be much bigger than the update to the current 3.1 release.

I have been watching a huge number of replays and analyzing results with my software. The purple Dan Gant talked in an Undermind podcast about his tournament preparation process: He examines losing games only, identifies the most frequent game-losing weaknesses, and works to fix those. It’s great method, a direct way to improve tournament results in the short term, especially for a bot which can expect to finish near the top, meaning that it shows relatively rare game-losing weaknesses at its level of play. My goal is different, and I follow a different process. I also want to finish well, and make low-risk short-term improvements, but my top goal is to improve play in the long run rather than the short run. I identify ahead of time aspects of play that I think I can and must improve, and I examine both winning and losing games with an eye on those aspects, often looking at specific opponents that bring out those aspects. The weaknesses in winning games must be fixed too; they are by definition not game-losing, but fixing weaknesses improves play and that’s that, and to my eye winning games often show glaring blunders by Steamhammer. Anyway, at Steamhammer’s level of play, fixing a game-losing weakness often leads it to go wrong in a different way a little later and lose anyhow, so I may have to fix a string of weaknesses before I see results. Those are compound weaknesses, as it were, and I run into a lot of them.

I have learned some things by analyzing the ladder results with my software. One of the things I learned is that I could figure out even more if I wrote more software, and if I had Steamhammer record more information that I could correlate with the game results. I may do that soon, and post data.

The Ladder has new participants since I last wrote about it. Besides Stardust, MadMixP is new and StyxZ is reactivated. Just today, CherryPi joined too. That makes 11 active participants, enough for a small but lively scene. I still recommend joining the ladder if you intend to compete in AIIDE 2020, because it is the best way to test that your bot runs correctly in the AIIDE environment, adhering to the strict time limits and so on. Just letting it run for a day is enough to test for basic correctness (the ladder runs games much faster than BASIL), and if you have a problem you want to find out about it early so there’s time to fix it.

Steamhammer 3.0 change list

I’ve uploaded Steamhammer 3.0 to SSCAIT. Expect source tomorrow. Here’s the change list. Some items I already wrote up, so I only link to the posts here.

There’s a ton of new stuff. This is an infrastructure version, aiming to set the stage for future progress. The new features mean there is a high risk of arthropod vermin. If the new bugs are not too deadly, I expect this version to be only slightly stronger than the current Steamhammer 2.4.2 (which plays identically to the SSCAIT tournament version). Watchers may not be able to tell the difference, except when there is more than one queen on the screen, when it will be obvious. I expect only occasional proxy openings.

skill kit

The skill kit makes it possible to extend the opponent model with any kind of game data, so that in principle Steamhammer can adapt any aspect of its play to the opponent based on experience. To implement a new skill under the skill kit, write a subclass of the abstract class Skill. You need to set a name for the subclass (_name) and implement methods enabled() (should the skill be loaded for this game?), update() (which may carry out the actual skill, or may only collect information), and putData() and getData() (write or parse your data for the game record). You also have to implement feasible() (check quickly, is it possible to execute the skill?), good() (is it a good idea to execute the skill?), and execute() (carry out the skill when feasible and good), but if you prefer you can let update() do all the work, just have feasible() return false, and supply trivial implementations for the others.

• There is a new game record format that records modestly different information about each game, and includes skill kit data. Steamhammer can read records in the old format or the new format, so existing data can be kept.

• The updated gas steal skill uses the skill kit and knows a lot more about Starcraft than the original gas steal skill.

• There is a new enemy unit timing skill. All it does it record data.

• Base ID numbers from the map analysis are now constant across games, so that the numbers can be stored in the opponent model and used to remember the initial base positions.

proxy skills

Steamhammer now has basic proxy skills so that you can write a wide variety of proxy openings. There are new macro locations such as @ enemy natural and new things that you can do with macro locations, like send workers there ahead of time.

It is also possible to use the skill kit to write more sophisticated proxy openings which make dynamic decisions.

production

Fixed: A bug caused distant buildings to start later than necessary because of an error in figuring out when to send the worker.

• Improvements to the handling of production jams: Don’t declare a jam when we are out of resources. Don’t declare a jam when we are maxed on supply. Also, clearing a jam correctly resets the timer so we don’t loop on declaring production jams. The changes correct occasional minor problems, nothing serious.

• If a worker sent to build gets locked down or maelstromed, we immediately assign a new worker. For some reason, Steamhammer used to assign new workers only for stasis.

• If we’re protoss, and we’re constructing a building with a worker from the same base as the building, it’s OK to assign a worker that is carrying minerals or gas. It will barely delay our income. Terran and zerg continue to insist on builders with empty hands.

• Some production code is slightly simplified.

other infrastructure

Mine out blocking minerals on maps that have blocking mineral patches. In the SSCAIT map set, that is Destination and Heartbreak Ridge. WorkerManager sends a worker to mine out the minerals once there are 2 bases and at least 18 workers total. The implementation is not complete and works only for mineral patches with 0 minerals; it doesn’t work on maps where blocking minerals actually contain minerals (mostly quite old maps).

Resource tracking: Keep track of the remaining minerals and gas on the map, as information allows. Since writing those two posts, I extended the code to also keep track of whether a mineral patch is mined out; formerly, the code could not tell the difference between a 0 amount mineral patch and a mineral patch that no longer existed (it’s used in mining out blocking minerals).

• Decide on the value of taking a base, possibly a base that is partially mined out, based in part on the remaining count of mineral patches and the remaining total resources. To get this tuned right I had to retune other aspects of expansion decisions too, or else it would take center bases too soon.

The internal The system to simplify information access is extensively reworked and lets you reach much more information.

Maintain global unit counts every frame. I removed the old UnitUtil::GetAllUnitCount() and UnitUtil::GetCompletedUnitCount() calls. The information is used so often that it’s better to compute the numbers once and for all each frame.

Infer the existence of enemy buildings that we haven’t seen if the buildings are prerequisites of things we have seen. When we see a dark templar, we know there is a templar archives, among other buildings.

Accurately predict enemy building completion times in the UnitInfo system that tracks enemy units. Steamhammer now knows when enemy static defense that it saw under construction will complete, and uses the information in combat simulation (it formerly used a gross approximation that sometimes caused misbehavior). The info is not yet used in recognizing the enemy plan, but it will be valuable when it is. The info also affects squad targeting sometimes.

• A proxy enemy supply depot, engineering bay, or pylon by itself is not an emergency and doesn’t cause the enemy plan to be recognized as Proxy. Don’t overreact.

InformationManager::enemyGasTiming() remembers the time that the enemy first visibly used gas. For example, if we see a vulture, then we know there’s a factory, so we know that the enemy has spent some vespene. It’s one piece of data that goes into deciding whether to steal gas: It’s recorded in the new format game records, and the gas steal skill looks at the numbers from games with no gas steal to get an idea of the enemy’s usual behavior and decide whether stealing gas now will interfere with it.

• A minor improvement to UnitUtil::EnemyDetectorInRange(), which tries to judge whether a cloaked unit of ours is detected by the enemy: Now it knows that a blinded detector can no longer detect.

• I fixed a bug in InformationManager that could cause it to believe that a destroyed pylon existed for 1 extra frame, a bug with no detectable consequences. There should be a Rammstein song about that.

• I removed the WorkerData::depots data structure and its updating code, which was not only unused, but unusable because it was incorrect. I also removed the MacroAct::_race value, which is redundant and was used only for error checks that have never failed in Steamhammer’s life and would be easy to debug if they did.

• I removed various unnecessary includes.

configuration

New macro location @ gas only makes it possible to take a gas-only base (with no minerals) on those rare maps that have them. The zerg strategy boss knows how to do this and will automatically do it sometimes. This is on top of the new macro locations for proxies.

• I removed the macro location @ macro in favor of @ main, which so far means the same thing. Though I’m thinking of splitting them again in the next version, when they may no longer mean the same....

• Added configuration option Config::Debug::DrawResourceAmounts which draws Steamhammer’s idea of the remaining minerals or gas in each mineral patch or geyser—the amount and, if it’s not current, the frame it was last observed. It’s turned on in the uploaded instance, so you’ll see it on the SSCAIT stream. Also Config::Debug::DrawTerrainHeights which draws a number for the terrain height at each tile, with doodad terrain levels in purple.

• Changed the configuration option Config::Debug::DrawWorkerInfo to draw the worker’s job code on each worker and target lines to show where the worker is going. Formerly it drew the worker jobs in a column, which was hard to relate to the game situation. Updated Config::Debug::DrawStrategyBossInfo to add the target queen count to its display of information.

• Renamed configuration option Config::Skills::AutoGasSteal to Config::Skills::GasSteal; it sets whether the gas steal skill is enabled. Renamed Config::Debug::DrawUnitTargetInfo to Config::Debug::DrawUnitTargets because it is shorter.

• Removed configuration options Config::Debug::DrawResourceInfo which was confusing, Config::Skills::RandomGasStealRate which appears to have never been used by any fork, Config::Debug::DrawMouseCursorPosition which I don’t find value in, and Config::Debug::DrawBOSSStateInfo which is not very informative even when using BOSS.

squads

Fixed reaver stuttering, which was caused by a bug. Reavers are slow enough without spending half their movement time stopped.

InformationManager::getNearbyForce() uses the predicted completion time for enemy buildings. This is how the info gets into combat sim.

• The recon squad: Don’t form it before 6 minutes into the game. Formerly the squad was constituted whenever there were “enough” units, which could cause a zergling rush to be weakened by diverting some lings to reconnaissance.

The watch squad: Even if a watch squad zergling is the last zergling on the map, it will remain on station. Formerly, in an emergency it would rejoin the main army, where it did no good and no longer guarded its base from being taken by the enemy. More importantly, stay above ground when detected and endangered. IceBot dealt successfully with the burrowed zerglings: When the SCV could not start construction, it scanned and attacked. The zergling was forced to the surface but instantly reburrowed again and soon died. Oops.

• Squad targeting in the cleanup phase of the game: Don’t send a squad after enemy units that the squad can’t attack. This prevents some cases of zerglings following a floating ebay and the like. There are advantages to following, but I hope this way Steamhammer will be less often distracted from finishing the game.

• Be willing to pull workers a longer distance versus an enemy proxy than versus zerglings. Keeping the workers near their minerals saved many games against zergling attacks, but prevented the workers from engaging proxy buildings. That’s fixed.

• I made changes to try to retreat behind static defense instead of retreating to around static defense, but it didn’t work. Also unsuccessful were changes to cluster regrouping to get late-arriving units to join the fight as they should. The changes are still in the code, though; they’re no worse.

queens

• The maximum count of queens is configured to 6. The previous Steamhammer was already able to handle that, but I didn’t have time to test it before the tournament so I kept it configured to 1 queen max. When 2 or more queens are near each other, they fly in wacky looping patterns to keep away from each other so that they don’t all engage the same target at the same time. That’s a pre-existing behavior, but with 1 queen you don’t get to see it.

• Queens are better at avoiding danger. I widened the safety margin by 1 tile, which made a bigger difference than I expected. Also, queens now recognize science vessels and dark archons as dangers and try to stay away from them.

• I fixed a bug (introduced in tournament version 2.4.1 in December) that made queens less likely to succeed in infesting a command center. Moving around was taking priority over infesting.

• The strategy boss knows how to make higher numbers of queens. It decides how many, and what research to do in the queen’s nest, by looking at enemy unit counts. It used to get the queen energy upgrade too early; now it only gets the energy upgrade if there are many queens to benefit from it, or if the economy is so booming that the expense is negligible.

• The top priority broodling target is a nuking ghost. That brings queens in line with other attacking units.

• Be willing to broodling a less important enemy unit if the enemy doesn’t seem to have any of the most important ones. For example, if you make a lot of tanks Steamhammer may make queens to broodling them. Later in the game, if there are no tanks to be found the queens will be happy to broodling goliaths instead; formerly it would insist on tanks no matter what. Broodling becomes more valuable.

• If there is high total queen energy (because there are a lot of queens), be more willing to use ensnare and parasite instead of broodling when more than one spell is available. Formerly the broodling > ensnare > parasite hierarchy was more rigid. The more flexible queen behavior is better.

• Steamhammer is able to make infested terrans. I fixed the production system bug that prevented it. It uses them very weakly, so I set it to make only 1 at a time and leave time between them.

zerg

Emergency reaction: If too many drones are lost, or a hatchery is lost, break out of the opening. Steamhammer as zerg is too inclined to stick to its opening when it is busted.

Fixed a bug in spellcaster micro that could cause a queen or defiler to go idle. That was painful when it happened; a potentially valuable unit would stop on the map and do nothing for the rest of its life.

Lurker micro improvement: A lurker will not unburrow if an unseen or undetected enemy is thought to be in range to attack it. Formerly, a lurker with no target would unburrow immediately to seek a target, then die to the bunker it could not see at the top of the ramp, or to an untargetable dark templar that was standing next to it. The ramp misbehavior especially caused a lot of unnecessary lurker losses (we saw an example of the same misbehavior from PurpleSwarm in a recent broadcast), but the DT misbehavior is also a key blunder in some games. There is a bug that will still cause a bad unburrow below a ramp sometimes, but at least it’s less common.

• In ZvZ, be less eager to make a defensive evolution chamber right away. Steamhammer has made a lot of unnecessary evos.

• In ZvT and ZvZ, when adding spore colonies, place the first spore in the location closest to the enemy, considering Steamhammer’s main base, natural, and any proxy it may have. (In ZvP, the first spore goes into the natural as DT defense.) There were cases where Steamhammer would place the spore in its main when the natural was closer to the enemy base, and it became impossible to protect the natural from wraiths. At least force them to fly around to a more distant target!

• Drones may burrow for safety when an irradiated unit comes near. This protects them against the eraser trick and other irradiate hazards. I expect that by the time irradiate is researched, burrow will usually be available.

• If the opening book says it wants a hatchery (and no drones have been lost), trust it and make the hatchery. This is to accomodate rare openings which deliberately make hatcheries early. Formerly a safety rule might fire and say “No, you don’t need that hatchery yet.”

• The unit mix versus battlecruisers is adjusted slightly. I hope it will perform better against MadMix’s battlecruisers.

• Don’t make more devourers than needed to counter enemy air. There was already an overall max devourer limit, and a limit depending on how many mutalisks there are. I hope that now, with all factors accounted for, Steamhammer will finally stop overdoing it.

• If Steamhammer is maxed and rich, get overlord sight range.

• Plaguing a cloaked ghost gets a high value, even compared to plague on other cloaked units. It’s to help defend against nukes. Steamhammer really, really does not want to get nuked.

openings

A lot of new openings mysteriously appeared. Where do they come from?

how to defile

We have the next round of SSCAIT results. I was hoping for Killerbot by Marian Devecka over ZNZZBot, because Steamhammer is a favorite over Killerbot. But ZNZZBot squeaked a win by crash. Steamhammer will face ZNZZ in loser’s round 3 and almost certainly be eliminated. Oh well.

one little plague

A highlight from Steamhammer-Icebot on Fighting Spirit. In old days, Steamhammer would have finished a winning game like this by brute force, with mass ultralisks or mass guardians. The actual ending did feature brute force, but more elegantly applied.

a plague on all your tanks!

Dark swarm ensured that zerglings would break the front. Rubble of bunkers and turrets lies everywhere. Tanks rain splash damage from above, but as zerg reduced the natural, the defiler (selected) threw a plague over every tank. When the mutalisks visited them, the tanks popped like so many bubbles.

Very satisfying. All that work on defilers was worth it.

Steamhammer and bugs

I’m pleased with Steamhammer’s reliability this tournament. I watched all 88 games, and for the first time ever I saw no losses caused by crippling bugs. There were 2 games with terrible play due to bugs, but in both cases Steamhammer recovered and won anyway. There was also a bug that occasionally caused multiple drones to be sent to fail to scout the enemy: Lose one, send another, repeat. That would lose games for sure against an even opponent, but in practice it occurs in games that Steamhammer will lose no matter what. I think I know the cause, and it will be fixed soon.

I surmise that Steamhammer is especially prone to reliability problems because it aspires to do everything. It plays over 150 opening builds of all kinds; failing to adapt to all the misadventures of the opening causes a lot of snags. I count only 3 zerg abilities yet to be implemented: Nydus canals, infested terrans, and lifting off an infested command center, all on my list for coming months. (Drop is technically implemented even though not yet used by zerg. I guess overlord sight range is not implemented either, but it’s trivial if I ever want it.) More features means more bugs; fixing bugs in defiler play was a big time sink last year.

Another source of reliability hitches is my habit of swapping in new plans as fast as I can make them. A number of Steamhammer’s internal modules are half-rewritten, stuck in the middle of a transition from an old design that is not flexible enough to a new design that is not finished enough. It would be more efficient to complete one task before moving on to the next. But then I would be making progress on only one front at a time, and it wouldn’t be as much fun. I like the variety.

Anyway, after burnishing the 2.x versions for over a year, I’ve remedied almost all of the worst bugs. It is past time to get back to major features and structural work, so that I can add a new round of bugs. To symbolize that, I’ll be calling the next version 3.0 even though it doesn’t in reality have any new feature worthy of a major version number. It will in time.

AIIDE 2019 - what Steamhammer learned

Today is Steamhammer. With a mid-rank finish and the widest range of builds, plus informative game records, Steamhammer may give us the best insight into how other bots played.

The tournament was 100 rounds, and Steamhammer was configured to remember the previous 100 game records, because in play there is no reason to remember more (earlier records are increasingly discounted). Steamhammer also had pre-learned game records for many opponents, so when the game record count reached 100, new records added caused old pre-learned records to drop away. Not all 100 tournament games happened for each opponent, but the pre-learned games filled in the small gaps so that Steamhammer ended up with exactly 100 game records per opponent in every case.

The “opening” table counts Steamhammer’s opening choices. The “plan” table shows the plan that Steamhammer first predicted that the opponent would play, then recognized that the opponent was playing. Both prediction and recognition can be wrong. The timing table is new this year, an attempt to get a little more information out of Steamhammer’s rich game records. For some events, it gives the count of games in which the event occurred, and the median time, earliest time, and latest time it occurred in those games when it did. The times are given under the assumption that 1 second of game time is exactly 24 frames, a simplification.

gas steal attempt - When Steamhammer sent out the drone to steal gas (if it did).
gas steal success - Whether the gas steal attempt succeeded in taking the opponent’s gas. Steamhammer doesn’t record the time it happens, so this is only a success count.
enemy scout - When the enemy scout first reached Streamhammer’s base.
enemy combat units - When the first enemy combat unit was seen.
enemy air units - When the enemy is first known to have tech for flying units (except overlords).
enemy cloaked units - When the enemy is first known to have tech for cloaked units.


#1 locutus

openinggameswins
11Gas10PoolMuta10%
12Hatch12Pool10%
2.5HatchMuta20%
2HatchHydra10%
2HatchHydraBust40%
2HatchLingAllInSpire10%
3HatchHydraBust50%
3HatchHydraExpo10%
3HatchLateHydras+150%
3HatchLingBust230%
4HatchBeforeGas10%
4HatchBeforeLair50%
5HatchBeforeGas20%
5PoolHard2Player20%
5Scout10%
7PoolSoft10%
8-8HydraRush10%
8Hatch7Pool10%
8Pool10%
9Pool20%
9PoolHatch20%
9PoolSpeedAllIn10%
AntiFact_Overpool9Gas10%
DefilerRush20%
Over10Hatch2Sunk10%
Over10HatchSlowLings10%
Over10PoolMuta10%
OverhatchExpoLing20%
OverhatchExpoMuta20%
Overpool2HatchLurker10%
OverpoolHatch10%
OverpoolHydra120%
OverpoolSpeed40%
OverpoolSunk10%
Overpool_4HatchLing20%
PurpleSwarmBuild10%
Sparkle 1HatchMuta10%
Sparkle 2HatchMuta10%
ZvP_3BaseSpire+Den10%
ZvP_3HatchPoolHydra20%
ZvP_4HatchPoolHydra1421%
ZvT_12PoolMuta20%
ZvZ_12PoolLing10%
ZvZ_12PoolLingB10%
ZvZ_Overpool9Gas10%
45 openings1003%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Heavy rush--44%0%0%0%
Safe expand5656%2%4444%5%43%5%
Turtle4444%5%4545%2%43%9%
Unknown--77%0%0%0%
timing#medianearlylate
gas steal attempt431:290:002:34
gas steal success23---
enemy scout1001:351:116:51
enemy combat units1005:234:107:58
enemy air units712:057:3921:34
enemy cloaked units811:244:3921:34


It looks like Locutus opened forge-expand every game. It worked. Steamhammer desperately tried everything, including ZvZ builds and island builds, and finally squeezed 3 wins with a risky extreme macro opening, 4 hatcheries before spawning pool, which was able to win one game in five. I should add 5 and 6 hatch before pool and see if they help.

Locutus rarely made corsairs or dark templar. I wonder what its criteria are? Maybe it won before it got that far. The scout was usually quite early, and the first combat unit was seen late, as expected for a cannon-first opener.

I played over the 3 wins. They were in rounds 65, 70, and 73; after that, I expect that Locutus found a way to win. In 2 games, Steamhammer pulled ahead in early economy with its greedy opening, then struggled to defend and fell into a losing position. But Locutus got most of its units stuck in its base, and Steamhammer was able to turn it around and win after a hard fight with critical defiler support. In the third win, Locutus chose a zealot-archon unit mix that Steamhammer knows how to cope with, and zerg powered through.


#2 purplewave

openinggameswins
10Pool9Gas10%
11HatchTurtleHydra5044%
11HatchTurtleLurker10%
11HatchTurtleMuta1520%
12Hatch_4HatchLing10%
2HatchLingAllInSpire10%
3HatchHydraExpo10%
3HatchLing10%
3HatchLingExpo10%
4HatchBeforeLair10%
5PoolSoft10%
7Pool12Hatch10%
9PoolBurrow10%
AntiZeal_12Hatch10%
HiveRush10%
Over10Hatch20%
Over10Hatch1Sunk30%
Over10Hatch2Sunk10%
OverhatchLateGas10%
Overpool+110%
OverpoolSpeed10%
OverpoolTurtle20%
ZvP_3HatchPoolHydra10%
ZvT_7Pool10%
ZvZ_Overpool9Gas933%
25 openings10028%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Fast rush--22%0%0%0%
Heavy rush9999%28%9090%24%90%4%
Safe expand--33%100%0%0%
Turtle--11%100%0%0%
Unknown11%0%44%50%0%0%
timing#medianearlylate
gas steal attempt411:131:092:36
gas steal success37---
enemy scout982:131:1915:06
enemy combat units992:352:155:59
enemy air units5113:575:1520:37
enemy cloaked units4814:016:0217:11


PurpleWave in contrast went with mostly 2 gate openings against Steamhammer; that’s what “heavy rush” means for protoss. Steamhammer countered with early sunkens plus hydras or, less successfully, mutalisks (this version had a bug that weakened mutalisk play). There are also 3 wins with a ZvZ fast mutalisk opening. 2 gates should beat that, so protoss either played poorly or chose a different build in those games.


#3 bananabrain

openinggameswins
10HatchHydra10%
11Gas10PoolLurker20%
11Gas10PoolMuta1010%
11HatchTurtleHydra10%
12Hatch_4HatchLing10%
2.5HatchMuta10%
2HatchLingAllInSpire10%
3HatchHydra20%
3HatchHydraBust10%
3HatchHydraExpo10%
3HatchLateHydras10%
3HatchLingExpo911%
5PoolHard10%
6Pool10%
6PoolSpeed10%
7-7HydraLingRush10%
8Gas7PoolLurker B10%
9HatchMain9Pool9Gas10%
9PoolBurrow10%
9PoolSpeed10%
9PoolSpire10%
AntiFact_2Hatch1540%
AntiFact_Overpool9Gas10%
AntiZeal_12Hatch100%
Over10Hatch1Sunk10%
Over10HatchBust2825%
OverpoolSpeed10%
OverpoolTurtle 010%
ZvP_Overpool3Hatch20%
ZvT_3HatchMuta10%
30 openings10015%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Heavy rush7070%14%3232%3%33%39%
Naked expand22%0%11%100%0%50%
Proxy--44%0%0%0%
Safe expand2323%17%1616%31%17%35%
Turtle55%20%1010%20%0%20%
Unknown--3737%16%0%0%
timing#medianearlylate
gas steal attempt501:261:091:38
gas steal success31---
enemy scout1001:561:213:17
enemy combat units1002:562:198:19
enemy air units835:192:5111:41
enemy cloaked units616:263:2714:05


BananaBrain contrasts with both previous opponents in that it played a variety of builds. Steamhammer was unable to predict what was coming. It looks strange that the best reaction was an opening designed to counter terran factory-first builds that include a vulture runby, but in fact it is a mildly specialized 2 hatch mutalisk variant and not so surprising. BananaBrain made corsairs and dark templar in most games.


#4 daqin

openinggameswins
10HatchHydra10%
10Pool9Hatch10%
11Gas10PoolLurker119%
11Gas10PoolMuta10%
11HatchTurtleLurker10%
12Hatch12Pool10%
12HatchTurtle20%
12Hatch_4HatchLing20%
2HatchHydraBust10%
2HatchLurker10%
3HatchHydra10%
3HatchHydraBust10%
3HatchHydraExpo40%
3HatchLing10%
3HatchLingBust21020%
3HatchLingExpo10%
4HatchBeforeGas30%
4HatchBeforeLair30%
4PoolSoft10%
5HatchBeforeGas20%
5Scout10%
8-8HydraRush10%
8Hatch7Pool10%
8Hatch7PoolSpeed1916%
9GasLair10%
9HatchExpo9Pool9Gas20%
9PoolBurrow10%
9PoolSpeedAllIn10%
AntiFact_2Hatch10%
AntiFactory10%
OverhatchExpoLing30%
OverhatchExpoMuta10%
OverhatchLateGas10%
Overpool+110%
OverpoolSunk10%
ZvP_2HatchMuta10%
ZvP_3BaseSpire+Den110%
ZvZ_12Gas11Pool10%
ZvZ_12HatchMain10%
ZvZ_12Pool10%
40 openings1006%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Heavy rush--44%0%0%0%
Proxy--66%0%0%0%
Safe expand1111%9%2323%13%18%0%
Turtle8989%6%6363%5%62%4%
Unknown--44%0%0%0%
timing#medianearlylate
gas steal attempt431:261:091:58
gas steal success24---
enemy scout991:341:149:35
enemy combat units1005:264:076:58
enemy air units319:478:5416:19
enemy cloaked units369:447:2314:39


DaQin played forge-expand and has similar timings to Locutus, for the same reasons. The fast scout is to allow adjustment of the cannon count and timing, and the late combat units are due to getting a gateway later. Steamhammer couldn’t find any better reaction than to try to bust with zerglings, either early or late, and it was not particularly successful.


#6 zzzkbot

openinggameswins
2.5HatchMuta10%
3HatchLingExpo10%
9HatchExpo9Pool9Gas367%
9PoolLurker933%
9PoolSpeedAllIn10%
9PoolSunkHatch1258%
9PoolSunkSpeed933%
OverpoolSunk1338%
ZvZ_Overgas9Pool1258%
ZvZ_Overpool9Gas3982%
10 openings10059%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Turtle100100%59%7979%71%79%21%
Unknown--2121%14%0%0%
timing#medianearlylate
gas steal attempt261:141:111:37
gas steal success12---
enemy scout992:550:377:23
enemy combat units1004:062:254:43
enemy air units665:295:0310:11
enemy cloaked units0---


ZZZKBot mostly played a turtle-into-mutalisks strategy against Steamhammer, and was somewhat successful. You can read the idea straight out of the tables above. The 2:25 earliest timing but 4:06 median timing for combat units says that ZZZKBot sometimes rushed zerglings, but usually not.


#7 microwave

openinggameswins
11Gas10PoolLurker2843%
11Gas10PoolMuta1520%
2HatchHydra10%
3HatchLing10%
3HatchLingBust210%
5PoolHard10%
6Pool10%
7-7HydraLingRush10%
9GasLair10%
9HatchMain9Pool9Gas10%
9PoolLurker10%
OverhatchLing10%
OverhatchMuta2030%
OverpoolLurker10%
PurpleSwarmBuild10%
Sparkle 1HatchMuta812%
ZvZ_12HatchExpo10%
ZvZ_12HatchMain20%
ZvZ_Overpool11Gas10%
ZvZ_Overpool9Gas10%
ZvZ_OverpoolTurtle1225%
21 openings10025%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Heavy rush77%29%22%50%0%86%
Naked expand8989%26%2323%17%25%73%
Turtle44%0%11%0%0%75%
Unknown--7474%27%0%0%
timing#medianearlylate
gas steal attempt541:300:421:57
gas steal success1---
enemy scout1002:391:373:47
enemy combat units1002:272:143:58
enemy air units396:255:219:19
enemy cloaked units0---


Microwave played a 9 pool speed build into expansion and then spire, which you cannot read out of the plan table because Steamhammer didn’t recognize it accurately. But in the timing table you can see that combat units (zerglings) were early and air units (mutalisks) were not late.

Steamhammer was not able to steal Microwave’s gas. It probably should have stopped trying.


#8 iron

openinggameswins
2.5HatchMuta10%
5HatchBeforeGas10%
5Scout10%
7-7HydraLingRush4384%
8Gas7PoolLurker B10%
AntiFact_13Pool1155%
AntiFactory3964%
OverhatchExpoMuta10%
OverhatchMuta10%
Sparkle 2HatchMuta10%
10 openings10067%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Factory100100%67%9191%70%91%9%
Unknown--99%33%0%0%
timing#medianearlylate
gas steal attempt301:261:252:03
gas steal success0---
enemy scout873:270:3415:09
enemy combat units1002:592:295:27
enemy air units2313:5310:1120:07
enemy cloaked units696:395:3511:47


Look at that huge range of scout timings! 0:34 means that the scout SCV was sent immediately at the start of the game and went directly to the zerg base. 15:09 probably means that no enemy unit got into the base until the end of the game when Steamhammer lost (Steamhammer is on BWAPI 4.1.2 and cannot detect scans). Steamhammer prevented the scout entirely in 13 out of the 100 games by its own count; 15:09 is probably the same. Steamhammer was not able to steal Iron’s gas, and did eventually give up trying.


#9 xiaoyi

openinggameswins
12Hatch13Pool10%
2HatchLingAllInSpire1619%
2HatchLurkerAllIn10%
3HatchLurker10%
3HatchPoolMuta10%
5PoolSoft10%
7-7HydraLingRush3669%
7PoolMid2475%
AntiFact_13Pool933%
AntiFactory10%
AntiFactoryHydra812%
Over10Hatch10%
12 openings10050%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Factory9898%51%7474%41%74%21%
Naked expand--11%100%0%0%
Safe expand--33%33%0%0%
Unknown22%0%2222%82%0%50%
timing#medianearlylate
gas steal attempt461:261:052:08
gas steal success1---
enemy scout922:371:347:29
enemy combat units1002:392:253:22
enemy air units5512:238:5516:30
enemy cloaked units617:395:4217:07


Steamhammer liked 7 pool against XiaoYi, just as Microwave did, but also liked its dawn hydra rush.


#10 mcrave

openinggameswins
2HatchHydraBust580%
3HatchHydraBust667%
9PoolHatch1984%
Over10Hatch2Sunk3288%
Over10Hatch2SunkHard2692%
OverpoolTurtle1283%
6 openings10086%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Heavy rush9797%87%6464%80%63%19%
Safe expand22%100%1111%100%0%0%
Turtle11%0%77%100%0%0%
Unknown--1818%94%0%0%
timing#medianearlylate
gas steal attempt531:281:111:33
gas steal success33---
enemy scout922:211:149:55
enemy combat units982:422:158:51
enemy air units6910:025:0614:18
enemy cloaked units3010:295:0116:39

#11 ualbertabot

openinggameswins
5Scout2875%
Over10Hatch2Sunk10%
OverpoolTurtle7197%
3 openings10090%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Factory55%100%88%100%0%0%
Fast rush44%100%1111%100%0%25%
Heavy rush8686%88%4747%87%48%24%
Naked expand55%100%1010%100%0%40%
Unknown--2424%83%0%0%
timing#medianearlylate
gas steal attempt431:120:001:16
gas steal success23---
enemy scout792:111:194:23
enemy combat units612:431:464:33
enemy air units1014:2012:0216:57
enemy cloaked units1214:252:3816:57


Thanks to pre-learning, I expected Steamhammer to play its overpool turtle build every game. I’m not sure why it didn’t. I also don’t know how it hit on the 5 scout build, which means send out a drone at 5 supply to scout very early, then leave all decisions to the strategy boss. It’s a logical try against a random opponent, especially one that has a single strategy for each race, and it was fairly successful. But it did not appear in the pre-learned data.


#12 aitp

openinggameswins
7-7HydraLingRush1292%
9HatchExpo9Pool9Gas30100%
AntiFact_13Pool22100%
AntiFactory2195%
AntiFactoryHydra1493%
ZvT_3HatchMuta10%
6 openings10096%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Factory8787%97%3030%97%28%62%
Fast rush44%100%44%100%0%50%
Heavy rush44%100%22%100%25%50%
Turtle44%100%55%60%0%25%
Unknown11%0%5959%98%0%0%
timing#medianearlylate
gas steal attempt441:251:121:58
gas steal success3---
enemy scout253:312:4119:11
enemy combat units1003:231:578:09
enemy air units3111:277:4619:34
enemy cloaked units597:385:1916:34


AITP scored zip against both mass zerglings (9HatchExpo9Pool9Gas) and against fast mutalisks (AntiFact_13Pool). And it successfully scouted Steamhammer’s base only 25% of the time. If you don’t scout reliably, it will be hard to withstand rushes.


#13 bunkerboxer

openinggameswins
9PoolExpo42100%
9PoolSunkHatch31100%
9PoolSunkSpeed27100%
3 openings100100%
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Proxy6666%100%3535%100%36%36%
Unknown--4242%100%0%0%
Worker rush3434%100%2323%100%15%53%
timing#medianearlylate
gas steal attempt401:351:321:37
gas steal success33---
enemy scout912:101:473:47
enemy combat units842:432:093:27
enemy air units0---
enemy cloaked units0---


Steamhammer was not able to judge whether BunkerBoxeR was playing a proxy (with its proxy bunker) or a worker rush (since it sent SCVs in support). But it didn’t matter. The reactions are nearly the same. Since BunkerBoxeR never wants gas, stealing its gas was a waste.


overall

totalZvTZvPZvZZvR
openinggameswinsgameswinsgameswinsgameswinsgameswins
10HatchHydra20% 20%
10Pool9Gas10% 10%
10Pool9Hatch10% 10%
11Gas10PoolLurker4132% 138% 2843%
11Gas10PoolMuta2715% 128% 1520%
11HatchTurtleHydra5143% 5143%
11HatchTurtleLurker20% 20%
11HatchTurtleMuta1520% 1520%
12Hatch12Pool20% 20%
12Hatch13Pool10% 10%
12HatchTurtle20% 20%
12Hatch_4HatchLing40% 40%
2.5HatchMuta50% 10% 30% 10%
2HatchHydra20% 10% 10%
2HatchHydraBust1040% 1040%
2HatchLingAllInSpire1916% 1619% 30%
2HatchLurker10% 10%
2HatchLurkerAllIn10% 10%
3HatchHydra30% 30%
3HatchHydraBust1331% 1331%
3HatchHydraExpo70% 70%
3HatchLateHydras10% 10%
3HatchLateHydras+150% 50%
3HatchLing30% 20% 10%
3HatchLingBust21414% 1315% 10%
3HatchLingExpo128% 119% 10%
3HatchLurker10% 10%
3HatchPoolMuta10% 10%
4HatchBeforeGas40% 40%
4HatchBeforeLair90% 90%
4PoolSoft10% 10%
5HatchBeforeGas50% 10% 40%
5PoolHard20% 10% 10%
5PoolHard2Player20% 20%
5PoolSoft20% 10% 10%
5Scout3168% 10% 20% 2875%
6Pool20% 10% 10%
6PoolSpeed10% 10%
7-7HydraLingRush9377% 9179% 10% 10%
7Pool12Hatch10% 10%
7PoolMid2475% 2475%
7PoolSoft10% 10%
8-8HydraRush20% 20%
8Gas7PoolLurker B20% 10% 10%
8Hatch7Pool20% 20%
8Hatch7PoolSpeed1916% 1916%
8Pool10% 10%
9GasLair20% 10% 10%
9HatchExpo9Pool9Gas3591% 30100% 20% 367%
9HatchMain9Pool9Gas20% 10% 10%
9Pool20% 20%
9PoolBurrow30% 30%
9PoolExpo42100% 42100%
9PoolHatch2176% 2176%
9PoolLurker1030% 1030%
9PoolSpeed10% 10%
9PoolSpeedAllIn30% 20% 10%
9PoolSpire10% 10%
9PoolSunkHatch4388% 31100% 1258%
9PoolSunkSpeed3683% 27100% 933%
AntiFact_13Pool4274% 4274%
AntiFact_2Hatch1638% 1638%
AntiFact_Overpool9Gas20% 20%
AntiFactory6273% 6174% 10%
AntiFactoryHydra2264% 2264%
AntiZeal_12Hatch110% 110%
DefilerRush20% 20%
HiveRush10% 10%
Over10Hatch30% 10% 20%
Over10Hatch1Sunk40% 40%
Over10Hatch2Sunk3580% 3482% 10%
Over10Hatch2SunkHard2692% 2692%
Over10HatchBust2825% 2825%
Over10HatchSlowLings10% 10%
Over10PoolMuta10% 10%
OverhatchExpoLing50% 50%
OverhatchExpoMuta40% 10% 30%
OverhatchLateGas20% 20%
OverhatchLing10% 10%
OverhatchMuta2129% 10% 2030%
Overpool+120% 20%
Overpool2HatchLurker10% 10%
OverpoolHatch10% 10%
OverpoolHydra120% 120%
OverpoolLurker10% 10%
OverpoolSpeed60% 60%
OverpoolSunk1533% 20% 1338%
OverpoolTurtle8593% 1471% 7197%
OverpoolTurtle 010% 10%
Overpool_4HatchLing20% 20%
PurpleSwarmBuild20% 10% 10%
Sparkle 1HatchMuta911% 10% 812%
Sparkle 2HatchMuta20% 10% 10%
ZvP_2HatchMuta10% 10%
ZvP_3BaseSpire+Den120% 120%
ZvP_3HatchPoolHydra30% 30%
ZvP_4HatchPoolHydra1421% 1421%
ZvP_Overpool3Hatch20% 20%
ZvT_12PoolMuta20% 20%
ZvT_3HatchMuta20% 10% 10%
ZvT_7Pool10% 10%
ZvZ_12Gas11Pool10% 10%
ZvZ_12HatchExpo10% 10%
ZvZ_12HatchMain30% 10% 20%
ZvZ_12Pool10% 10%
ZvZ_12PoolLing10% 10%
ZvZ_12PoolLingB10% 10%
ZvZ_Overgas9Pool1258% 1258%
ZvZ_Overpool11Gas10% 10%
ZvZ_Overpool9Gas5070% 1030% 4080%
ZvZ_OverpoolTurtle1225% 1225%
total120052%40078%50028%20042%10090%
openings played1112493293


Steamhammer knows 142 different openings. In the whole tournament, it was only able to try 111 of them! It tried the most openings versus protoss, since it was looking everywhere for an escape from the overwhelming top protoss bots. Most openings were tried only a few times and lost every game, which means that Steamhammer would have performed better without them. That’s expected and even intentional; my plan is to add smarts until it is able to make good guesses about what to try. The work is underway.

Steamhammer 2.3.6 uploaded

I’ve uploaded Steamhammer 2.3.6 to SSCAIT. The main purpose of this point release is to fix a combat simulation bug that I cleverly—nay, brilliantly inserted just before the AIIDE tournament, to ensure that Steamhammer’s results didn’t discourage other bot authors. The bug caused deviations from excellence such as scoring 67% against Iron rather than 95%. The bug had a variety of effects, but the most important is that mutalisks were afraid of enemies that they could not see, even enemies like vultures that could not shoot back. Come into view and die, stay out of sight and live forever.

After AIIDE prep I wanted to do something fun, so I also added queen skills, improved defiler plague, and fixed a bunch of easier bugs and weaknesses, including a few important ones. Important changes are in bold.

combat simulation

Setup of combat simulation is corrected. In the AIIDE version I added code in the CombatSimulation class (which works the details of setting up a combat sim) to bypass the combat sim and return a short-circuit result in certain easy cases where the enemy has undetected cloaked units. FAP does not simulate cloaking and detection, so it was an important improvement. I reversed a condition in an important bit of code, which had the effect that the short-circuit worked correctly in the cases where it was supposed to, but also worked in cases where it was not supposed to. Ouch.

related to bases

An infested command center was misrecorded as belonging to both sides. That was a fun bug! There was a correct record saying it was zerg, and a leftover incorrect record claiming that it was still terran. I didn’t test mind control, but the bug must have affected that too. The most obvious effect was that a squad might be ordered to attack the location of the “enemy base,” after which they would gather around the infested CC and warm their hands (well, claws).

• A lifted command center no longer establishes a base. The code that checked “does somebody own this base?” did not consider whether a command center in the correct location might be in the air. That generally led units to collect underneath the lifted CC until it was either shot down or moved away from the base location. It didn’t cause any losses that I saw, but it did cause bad play.

Workers start transferring to a new base before the base’s resource depot completes. It’s something of a big deal, because Steamhammer zerg deliberately overproduces drones to populate a new base as soon as the hatchery starts, so that the base can become productive as early as possible. But then it didn’t transfer the drones until the hatchery completed. Now it computes the distance and transfers the drones to arrive after the hatchery finishes. It uses the shorter air distance instead of the true ground distance so workers are sent later than they could be, but it’s nevertheless an honorable improvement. Be afraid of the big macro.

queens

For fun, I added broodling and ensnare and made command center infestation more reliable. Steamhammer already had parasite skills. Parasite was more successful than I expected; in recent games I think the queen sometimes paid for itself in information about the enemy. Broodling and ensnare make games more fun when they come up, especially ensnare, and they’re not too costly. There remains a lot of room to improve queen play, especially queen maneuvering and coordination.

Broodling. If Steamhammer sees enough enemy units that want to turn into broodlings (like tanks, or high templar, or ultralisks), it will eventually make 1 or 2 queens and research broodling. Making 2 queens is new behavior. If broodling is researched, then broodling is the queen’s highest priority: The queen will stay home until it has enough energy, then join the army and broodling any enemy that wants it enough. Only if there is extra energy will it consider ensnare or parasite.

Ensnare. If Steamhammer sees a substantial number of enemies that enjoy being ensnared, it will eventually produce a queen, research ensnare, and oblige them. If ensnare is researched, then ensnare has priority over parasite: Steamhammer will only use parasite if the queen has enough energy that a future ensnare could still happen. (Ensnare and parasite both cost 75 energy.) The ensnare code works similarly to plague: It scans around and scores the possible ensnare targets to choose the best. It likes to ensnare fast units, and it likes to reveal cloaked units with ensnare, and of course it likes to goop up as many enemies as possible. Also, I updated FAP to understand that ensnare slows down the movement and firing rate of units. FAP’s understanding of ensnared movement is approximate, but its understanding of firing rate is nearly accurate. That way Steamhammer understands that ensnared units are weaker, and now might be a good time to attack them.

• If ensnare or broodling is researched, eventually also research the queen energy upgrade.

Infest command centers more reliably. Formerly, Steamhammer had no special infestation skill at all. It could infest a command center solely as a side effect of the queen’s behavior of staying with the army; if the army was hitting a command center, then the queen was in infestation range because the army was there. If the queen didn’t have energy for a spell, it stayed home and could not infest. Now the queen wakes up whenever an infestable command center is seen on the map, and moves toward it. Also, formerly the army might destroy the command center before the queen could infest it. Now the army recognizes when a queen is near and stops attacking the command center when it becomes infestable (below 1/2 HP). The army is more efficient, and more command centers turn to the dark side where they belong.

• Change to queen behavior that mainly affects cases where Steamhammer is contained to its natural: If a queen has enough energy to cast a spell, then its fallback retreat position is the front defense point, where it may be able to do some good. Otherwise its fallback retreat is the main base, where it should be relatively safe to sit and gain energy. This can make the queen more useful in a bad situation, but the queen is not likely to help much.

defilers

• There was an awesome extra digit in the constant “how many HP can plague eat up at most?” that Steamhammer uses in its forecast of how much damage a given plague will do. Oh... that is why it insisted on plaguing buildings even as I discounted them more and more—it thought it would do awesome damage! After fixing it, Steamhammer still loves to plague buildings; the practical effect of the fix is limited. But it has shifted its preference somewhat toward enemy units.

• I simplified the plague scoring code and tweaked it. Plague gets a higher score for putting a terran building into the red (so that it burns down if not repaired), and it will plague even a single enemy unit if it seems worth it.

The defiler might retreat to the main base and be useless when Steamhammer was contained to its natural and needed the defiler there to break out. I changed the defiler’s fallback retreat point to be the front defense point, which is also where any sunken colonies are placed. It’s not quite the same as the queen’s fallback retreat behavior. The queen needs a safe place to gather energy, the defiler can consume.

zerg

The finishing unit mix is drone-mutalisk. Formerly, when the opponent looked dead and Steamhammer wanted to chase down its last buildings, it made mutalisks plus whatever ground unit came out of the usual unit mix calculation, usually zerglings. That had rare unfortunate results when Steamhammer made too many ground units and could not get mutalisks. The drone count is capped at 75, so with a drone-mutalisk mix, Steamhammer will not run itself out of supply to make mutalisks and should almost never fail to finish off the opponent.

Ensure that there is at least one zergling or hydralisk in the army at all times after the opening book. Steamhammer scouts the enemy army primarily with its own army. If its army was wiped out in battle, it might sit back behind sunkens and drone up, thinking that the enemy army was also weak, and never learn better because it didn’t have forward units to see the enemy move out. “You mean, if I keep my eyes closed, I’m not safe after all?”

If terran or protoss has too much air, make a defensive spore colony even if Steamhammer also has a spire. Formerly, Steamhammer skipped the spore if it had a spire, because it used to be that scourge was defense enough. But if the enemy has too many air units, scourge is not enough. McRave (after an update this summer) is especially good at massing its corsairs and shooting down scourge. (In ZvZ, Steamhammer follows different rules for making defensive spores.)

• A temporary production freeze happened if Steamhammer wanted to upgrade air carapace... at the same time that it was morphing a greater spire. All production stopped until the greater spire completed. It was surprisingly common, it seemed to happen in most games where Steamhammer got a greater spire. Anyway, fixed now.

openings

• Added a protoss opening GoonObserver to directly counter DT rushes and other cloak rushes. Unfortunately the automatic “oh no, cloaked units, hurry and build cannons” reaction still happens and tends to delay the observers, but it’s still not a bad counter.

Steamhammer can’t finish the game

Finishing off the enemy just means destroying all their buildings. It sounds simple, but it is a sophisticated skill, and there are a lot of ways to go wrong. Steamhammer has a number of special provisions for quickly finding the last enemy remnants, but small loopholes persist and occasionally a game slips through one.

PurpleSpirit-Steamhammer on La Mancha is an example. It’s an entertaining game, thanks to the purple habit of playing all over the map, but I want to focus on the end, after PurpleSpirit has lost, when Steamhammer fails to destroy the floating terran buildings that are right over its head. That part is entertaining too, but not for the same reason.

the beginning of the end

Everything terran on the ground is destroyed, except one command center which was infested instead. The remaining terran force is 2 full-strength battlecruisers, and the remaining terran infrastructure is 2 floating ebays. Steamhammer is maxed and banking resources, but its only anti-air units are 8 scourge, plus a defiler with plague. Notice how much game time is left?

One of Steamhammer’s special game-finishing skills is that it makes mutalisks to chase down the residue of the enemy. The condition is, if the enemy has no known bases and no known anti-air units, then Steamhammer will tech to mutalisks and make mutas its primary unit. The mutas scout faster than ground units, and can find floating buildings and island bases that ground units can’t reach. But here terran still has battlecruisers, so the mutalisk rule does not kick in. First the terran army, such as it is, must be defeated.

swarm all over

Some scourge have hit, and the battlecruisers are no longer at full HP. But Steamhammer has been replacing losses primarily with more zerglings and ultralisks, which are of no use. Oops, the unit mix is wrong. Now there are only 2 scourge, and a battlecruiser can kill a scourge in one shot—2 battlecruisers, if not distracted by other targets, are safe from 2 scourge. The ebays choose to park over the terran natural, and zerg units have congregated there. The battlecruisers seek zerg stuff to shoot, and the defiler responds by blanketing the area in defensive swarm, consuming zerglings like crazy.

some damage has been done

Well, the 2 scourge hit one of the battlecruisers, which was distracted seeking zerg units that strayed from under dark swarm. And Steamhammer is now making 3 new pairs of scourge to replace various losses; if it can keep this up, the battlecruisers will eventually fall. Best of all, the defiler has plagued the terran buildings, despite the zerg units underneath. That will put the ebays into the yellow. One more plague should put them into the red, after which they will burn down.

nothing happens after this

Whew, finally the battlecruisers are shot down by scourge.

But that’s all she wrote. The swarms wore off and there was no need to renew them. The defiler did not plague again because it thought the zerg units underneath were more valuable. Scourge are coded to avoid floating buildings, because it is usually wasteful to spend gas destroying them. The mutalisk rule is engaged, and there is supply to build 1 mutalisk, but Steamhammer happened to choose to spawn zerglings first, and after that there was no supply to make a mutalisk. The game timed out with no more progress.

Finishing off the enemy can be hard. In this case, Steamhammer had the wrong unit mix; to make zerglings and ultralisks when all enemies were in the air was no good. The mutalisk rule should make mutalisks only, not mix them with other units. The scourge might have understood that when only floating buildings are left, they are good targets. Also the zerg ground units that can’t shoot up might have known better than to chase floating buildings (though it can be useful when they track a building trying to escape), and the defiler might have realized that damage to its own units was irrelevant when it could eliminate the enemy. That is a lot of flaws, and yet Steamhammer rarely fails to finish a game!

And fixing all the problems would only narrow the loophole, not eliminate it. In the worst case, Steamhammer would need to be able to destroy some of its own units to clear supply to make mutalisks to finish off the enemy. And that’s a high-end skill that I am in no hurry to add.

Next: The start of CoG 2019 analysis.