archive by month
Skip to content

Randomhammer reuploaded

I noticed that Randomhammer was briefly re-enabled on SSCAIT. I had disabled it before the tournament by uploading an empty zip file. So when Randomhammer played a game versus Feint... it wasn’t much of a game. The bot can only play when it exists.

So I reuploaded Randomhammer 3.3.5. It’s exactly the tournament version of Steamhammer, playing random.

Steamhammer-Microwave rivalry

The round robin phase of the annual SSCAIT tournament is nearly over.

Steamhammer was ahead of Xiao Yi by one loss when Steamhammer’s final game came up—versus Microwave. Even with bugs that keep it out of contention, Microwave is still Steamhammer’s rival. Xiao Yi had unplayed games left, and in any case Steamhammer defeated Xiao Yi 2-0 so in the worst case it would place ahead on tiebreak. Nevertheless it was a tense pairing. The game was a long and difficult hive tech ZvZ that neither bot could play particularly well. Notice Microwave’s use of overlords to discover and eliminate burrowed drones. The mutas and devourers were all plagued, but too late....

Another difficult Steamhammer game was versus Ecgberht.

Addendum: BetaStar and BananaBrain will likely end up tied for #2-#3. They scored 1-1 against each other. Will the seeding order for the elimination phase be decided arbitrarily, or what?

Steamhammer games and status

Steamhammer played an excellent game versus Monster today. The game is kind of long and boring to watch, with repetitive action, but I’m pleased by the good play against stubborn defense. Steamhammer wasted some resources and missed some opportunities, but made no severe mistake at any point. It even expanded at a good time, which is depressingly rare in its ZvZs. Near the end, Steamhammer tried to put the cherry on top by ensnaring Monster’s mutalisks, but the mutas zoomed by too fast, the ensnare missed, and the queen was shot down. Oh well, dropping the cherry didn’t change the rest!

For a game that is not in the least excellent but is interesting for its mistakes, I like yesterday’s Steamhammer-Slater game. I watched the game live, and when Steamhammer bumbled the defense of its natural I steeled myself for a quick upset. But it was not so quick after all. The game is a showcase of ways to go wrong on both sides. Some of Steamhammer’s mistakes remain unresolved because my planned fixes are complicated and need to be implemented as projects.

The latency compensation bug is still making me scratch my head. The easiest way to work around it is to use the Micro module’s order tracking; Steamhammer already keeps track of what orders it has given to units, including larvas, so it doesn’t need to rely on BWAPI to keep it straight. I traced the backbone of the production code and added the minimal workaround, a two-line addition to the code that decides whether a unit should be added to the set of candidate producers. And... it didn’t work. In order to control where zerg units are made, to do things like make drones at bases that don’t have enough drones, there is a special-case low-level routine, and it ignores the set of candidate producers and does its own calculations from scratch—slightly complicated calculations that the candidates don’t make easier. I’m still thinking about the right fix. Maybe I can find a way to make it simple and powerful at the same time.

It is, by the way, a serious bug. In Steamhammer, the effect is to sometimes—at predictable times—drop a unit that was queued for production. Among other things, it turns 12 hatch openings into 11 hatch. I had noticed that Steamhammer was playing 11 hatch surprisingly often, but it does have a full suite of intentional 11 hatch openings, so I didn’t realize that it was due to a bug.

apparent latency compensation bug

The just played Simplicity vs BananaBrain is a fine game by Simplicity. The early defense against zealots was especially well done, and Simplicity’s tech and attack decisions were good. Recommended.

In the meantime, I’ve hit a bug that’s slowing me down. I found a reproducible case where production fails because it tries to use the same larva to produce two drones. It looks like slippage in BWAPI’s latency compensation: The production system picks a larva to produce a drone. Ask the type during the same frame after giving the morph order, and you get egg; that is latency comp at work. Ask again a couple frames later, and the egg has turned back into a larva; the production system picks it a second time, and the second morph can only fail. I think it should be easy to work around, but can it be fixed? Latency compensation is not expected to be perfect.

It makes me wonder what other slippages may be hiding under the rug.

only one horrible game

Last year, Steamhammer finished SSCAIT for the first time with no losses due to crippling bugs and only 2 close calls. So far, it is on track to repeat in this year’s SSCAIT. I have seen all its games up to now, and there are no losses due to egregious bugs (only the standard issue flaws) and only one near miss. That’s great compared to Steamhammer’s early years, but I still want to fix the bugs.

The bad game is Steamhammer vs legacy (random zerg). Steamhammer made a number of mistakes in the game and suffered at least 2 bugs. The bug I could not accept is that it built spore colonies to defend against air attack—very early, immediately after scouting legacy’s base and seeing that it had not yet taken gas. It’s not possible to get mutalisks that fast, and without gas there was not even a hint of future risk. In fact, legacy never took its gas and played the whole game with a mass slow zergling plan. If Steamhammer had held on to the drones instead of wasting them on static defense due to a bug, I doubt the attack would have troubled it at all.

I traced the bug to, of all things, an integer overflow. The routine that figures out the time the enemy’s spire will complete returns INT_MAX for “never” if there is no evidence of an enemy spire... and I brilliantly added a margin for the mutas to hatch and fly across the map. In C++, integer overflow is officially undefined, so the compiler retreats to its room and laughs its head off before generating the code that will cause the most possible confusion, because “undefined” means it can do that. I don’t know what it did this time, but it was not as simple as wrapping around from an extreme positive value to an extreme negative value, because that would have caused the bug to show up in half of ZvZ games. No, it’s better if it shows up only when it will cause a disgusting blunder out of nowhere.

Anyway, it was easy to fix. I also fixed a bug that caused multiple commanding of overlords. And I’m writing code to collect data for my main current project. Progress is underway.

Steamhammer 3.4 plans

After every release, I traditionally post about my plans for what’s next. Sometimes I carelessly follow the plans before I can change my mind, though usually I can catch myself before I slip into a rut.

The next release should be 3.4, or 3.4.x if I give numbers to some test versions. Like last year, I will treat the tournament season as over, and go into infrastructure work of the kind that introduces new bugs, so that there’s time to iron them out before the next tournament season starts in the fall. The last time I considered plans, I had not decided between the opening timing project and the machine learning evaluation function project. I have to eventually do both and they support each other, so I may end up doing one after the other no matter the order. But for now I’ve decided that opening timing data (with other statistics) is my next item. I think it will make a bigger difference as a first step. I have updated the version number in the code and opened the next file to edit, the work is notionally underway.

When this project is complete (and I may do it in stages rather than all at once), Steamhammer will no longer need long sections in its configuration file telling what openings to play against each race and what the counters are to different enemy strategies. It will decide for itself based on its data. I will likely remove the configuration features altogether, since they don’t fit well with a data-driven architecture. It’s another step toward getting Steamhammer to think for itself rather than to slavishly follow instructions.

All details are up in the air; my plan remains an outline. Writing the code to collect the data I want is easy. Collecting the data I expect to be lengthy but straightforward. The hard part, I think, will be rewriting the opening selection code. The current version uses tricks to shortcut the work, and I won’t be able to get away with that any more, so I expect I’ll have to write it more or less from scratch, adding complexity in the process. On the upside, I can code it for modifiability, so that future opening adaptation changes (that I already know I want) will be easier.

Without more planning work, I can’t estimate how long it may take. 3.4 may be ready for AIST S4, or I may enter the current version 3.3.5. Or possibly I’ll fork an interim version with surprise improvements; anything’s possible.

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.

SSCAIT tournament soon

I’ve just uploaded Steamhammer 3.3.5, which will be the SSCAIT tournament version unless it hits a last-minute bug. If you dare to rush through your opponent prep, now’s the time! Expect the change list after the deadline. Optically, this version fixes all the most visible bugs introduced in and since the AIIDE version; the games look cleaner, overlords live longer, bizarre expansion behavior does not happen. Results are only slightly improved, though, in part because of the learning hides bugs issue. I expected better.

Starting on 19 December, there’s been a rush of updates. In fact, every bot updated after 27 November was updated (or re-updated) on 19 December or later, so there’s a gap in the dates.

There is not much to predict about the tournament. I think everyone can foresee that the top finishers of the round robin phase will include Stardust, Krasi0 (if it competes as terran this year), Monster, and PurpleWave, and likely BananaBrain which has been doing well. Halo by Hao Pan is significantly weaker, and there is a gap below Hao Pan and adias (aka SAIDA) of nearly 100 elo before the remaining strong bots. Steamhammer is likely to finish near the middle of the top 16, and then survive not very long in the elimination phase, as in past years.

unexpected infrastructure work in Steamhammer

To fix a bug, to make new features easier, and to improve usability, I updated Steamhammer so that the building manager carries out both steps of constructing a sunken colony or a spore colony, laying down the creep colony and then morphing the creep. Openings that used to say "creep colony", [other steps while we wait for the creep to complete], "sunken colony" now go "sunken colony", [other steps]. If you ask for a creep colony, then that is all you get; other code will have to take care of morphing it, because the building manager no longer does that step by itself, only the two-step process as a unit.

The bug, by the way, is that there was no tracking of what was supposed to happen to each creep colony. When making a sunken and a spore at the same time, they often got swapped, so that instead of (say) a spore in the main and a spore and sunk in the natural, there might be 2 spores in the natural and a useless sunk in the main. If you’ve watched many Steamhammer games, you may have wondered why spores are so often oddly placed—now you know one reason.

I didn’t intend to do any serious infrastructure work, but this piece turned into it. It was worth it, because the bug was causing more trouble after every update, but there was more to it than I realized. The assumption that you build a creep first and later morph it as a separate step turned out to be baked into the codebase. Besides the openings and the building manager, I had to closely analyze parts of the strategy boss, the production manager, and the macro acts themselves, and make changes that risk introducing new bugs. It has worked perfectly in tests so far, but I do not have confidence that reactions and corner cases will work in every situation.

I haven’t dealt with the issue of canceling and restarting sunkens due to the curious hit point change of the sunken colony, which Steamhammer has supported since version 1.4. Changes are needed. After that I think it’s not much extra work to implement delayed morphing of sunkens, like Arrakhammer, so I may do that too. But I could be wrong about the amount of work....

How do these subtle assumptions become so deeply threaded through a codebase, and so hard to change? On the one hand, it’s a failure to separate concerns, so you feel you could have done it better. On the other, how are you supposed to know what concerns you’ll have in the future? Software is hard.

learning hides bugs

Today I uploaded the third tournament test version of Steamhammer. Games of the second test version show that it’s already visibly stronger, with a couple of the worst weaknesses ameliorated. In particular, I fixed the heinous bug “Why would I expand to that base? No, I’ll just build macro hatcheries all around it instead.” Watching a lot of games to verify my changes, I was reminded of a lesson.

Bruce Nielsen, author of Stardust, wrote a comment about the disadvantages of opening learning:

I’ve found it refreshing to work without opening learning, as I was definitely using it in Locutus as a crutch to avoid doing necessary underlying work on stuff like worker defense or reacting to scouting information. While it of course worked to a certain extent, it also resulted in a lot of embarrassing losses from exploring builds that only work in very specific situations.

Learning seeks to adapt to the situation. Empirical learning, which is almost all of what bots do, adapts by experimentation, which means that some experiments will fail—those are the embarrassing losses. To me, the first part is more central, the “necessary underlying work” on skills. The bot’s own skills and tendencies are part of the situation that learning adapts to; if you lack a skill, learning will seek a workaround so that the lack causes fewer losses.

And the same if you have a bug. Steamhammer’s build-beside-the-base bug caused macro games to go off the rails. The loss rate did not increase as much as you might expect, because opening learning compensated by switching to all-in builds that did not lead to macro games. Now I have fixed the bug, and it should switch back to macro builds when appropriate. But the learning is slow, and it will not switch all the way back before the tournament, so Steamhammer’s tournament result may be worse than if the bug had never existed. Even though the bug is fixed, it contaminated my learning data, and having had the bug before makes play worse now.

Learning hides bugs. Which would be fine if it hid them completely, but of course that’s impossible. Bugs and weaknesses hurt less when learning can find a workaround, but still hurt. It becomes harder to evaluate your bot’s play and choose which weaknesses are more important to work on.

It makes me think that, if you’re making a serious evaluation of how well your bot is performing, you need to do some tests with learning turned off. Drop the crutch and try to walk without it. For example, you could take learning data from a previous version and freeze it, and run a test to see if there are regressions in playing strength versus particular opponents or when playing particular builds.

Steamhammer tournament plans

For the upcoming SSCAIT annual tournament, I’ll follow my usual plan. I’ve just uploaded a new test version Steamhammer 3.3.1, which fixes one of the critical bugs (and has another surprise change). I’ll drop frequent test versions until tournament time, and after the deadline I’ll release the tournament version. Time is short, so the changes will be mostly bug fixes and low-risk improvements that are unlikely to break stuff.

I expect the standard long no-upload period while the tournament runs. I will either turn to SCHNAIL, or else I’ll work on one of my machine learning ideas. Just after tournament season is the ideal time to add bugs and their associated major new features, so that the rest of the year can work desperately to fix—I mean, to tune them.

Steamhammer 3.3 change list

I’ve uploaded Steamhammer 3.3 to SSCAIT. The changes to play are slight, and stream viewers are unlikely to notice anything even if they look closely. Nevertheless, it’s an important upgrade. If no disasters strike overnight, I should get source up tomorrow.

BWAPI 4.4.0

Steamhammer is updated to BWAPI 4.4.0, at long last. In AIIDE this year, it was the only updated bot which still relied on the older BWAPI 4.1.2, now Positively Ancient by community consensus.

Part of the change is switching from VS2013 to VS2017. VS2017 has a more capable compiler backend with a stronger optimizer. Steamhammer’s DLL size fell from 1,211,392 bytes for version 3.2.20 to 1,100,800 bytes for 3.3, reflecting the difference in compiler, small changes in Steamhammer’s size, and any changes in the size of BWAPI.lib. That’s about a 9% improvement in object size for the effort of upgrading, surprisingly large. The bot presumably runs faster, but I didn’t measure it. Steamhammer already runs fast, so I doubt any speed improvement matters.

• If the opponent is terran, Steamhammer now tracks enemy comsat scans. Call InformationManager::getEnemyScans() to fetch the current scans. BWAPI 4.4.0 makes enemy scans available, where BWAPI 4.1.2 did not.

errors related to spell units

The spells comsat scan, disruption web, and dark swarm are represented in BWAPI by special units which belong to the player who casts them. Code that looks at units often has to know that. I searched through Steamhammer for code which did not know it, and found cases. Some were due to scans and only had to be fixed because of the 4.4.0 upgrade—it’s a subtlety for authors to be aware of.

• An enemy scan does not imply that the enemy has air tech.

• When deciding how many scourge are needed, don’t count enemy scans as air units.

• In squad targeting, do not target scourge at an enemy scan.

• In micro targeting (which is different from squad targeting), do not target enemy spell units.

• When clearing neutral blocks (like blocking eggs that are part of the map), do not target neutral spell units. A small number of maps have permanent neutral dwebs or swarms.

• In map analysis, don’t mark the areas covered by neutral spells as unwalkable.

• Don’t try to include a spell unit in a squad. I think spell units didn’t get in anyway, but now they are cut off at the first validity check, so it is as safe as can be.

zerg

Research in a hive. Until 4.4.0, a hive could perform no research due to a BWAPI bug. Steamhammer worked around it by getting all its research done before upgrading to hive, crimping its strategy choices. In hive rush openings, it was unable to research overlord speed ever, a serious issue. I’m so glad this is finally cured.

• Research +3 air upgrades. Until 4.4.0, it was not possible to upgrade in a greater spire due to a BWAPI bug, and Steamhammer had a workaround to avoid +3 spire upgrades altogether.

• Trivial bug fix: If Steamhammer lost its queen’s nest at any time after it started morphing its hive, but did not lose the hive, it was unable to replace the queen’s nest. Well, it rarely needed to, but it does have queen skills. The limitation is lifted.

• Indiscernible bug fix: Prevent a production freeze that could have happened if Steamhammer wanted to research burrow, had no hatchery other than a lair or hive, and the lair or hive was busy researching something else. There was virtually no chance of this bug ever occurring.

openings

• No doubt under the influence of an Infernal Compulsion Engine (old tech now superseded by Electric Motives), I added the zerg openings 9Pool8Hatch and 9Pool9Hatch. Crona plays a related opening with success.

Steamhammer on BWAPI 4.4.0

I finally have Steamhammer working locally with BWAPI 4.4.0. I didn’t have much trouble with it this time, on my second try, though I worked slowly.

I want to make a few minor code changes and run tests. I expect it won’t take long. If everything continues to look good, I’ll release Steamhammer 3.3 before long. Its play will be little changed.

Then it will be time to prepare for the annual SSCAIT tournament. (I write it that way even though the T already stands for Tournament. It seems clearer than “SSCAI tournament”.) The current version is essentially the AIIDE version, and the updates seem to have been worth 50 to 100 elo points, a substantial jump. But I did introduce a serious new bug: Steamhammer now often builds hatcheries beside the base it wants to take next, rather than at the base—sometimes several hatcheries. Then, since it hasn’t taken the base, it doesn’t mine there. It’s a terrible weakness, and fixing it has to be the first step.

AIIDE 2020 - Microwave versus Steamhammer

Microwave played more different openings than Steamhammer (no doubt seeking a winning choice), so I put it on the left. Blue is good for Microwave, red is good for Steamhammer.

microwave strategies versus steamhammer strategies

overall6PoolBurrow8-8HydraRush9Hatch8Pool9PoolHatchSpeedSpireOverhatchLingOverpoolBurrowZvZ_12HatchExpoZvZ_12PoolLingZvZ_12PoolMainZvZ_Overpool11GasZvZ_Overpool9GasZvZ_OverpoolTurtle
overall43/150 29%1/1 100%1/1 100%4/5 80%1/1 100%1/1 100%1/1 100%3/5 60%4/11 36%2/3 67%12/44 27%7/64 11%6/13 46%
10Hatch9Pool9gas4/9 44%--0/1 0%------2/2 100%1/5 20%1/1 100%
10HatchMain9Pool9Gas1/4 25%---------0/1 0%1/2 50%0/1 0%
10HatchTurtleHydra0/1 0%----------0/1 0%-
11HatchTurtleMuta0/1 0%-----------0/1 0%
12HatchMain0/1 0%---------0/1 0%--
12Pool5/25 20%----1/1 100%--0/3 0%2/2 100%2/7 29%0/10 0%0/2 0%
12PoolMain1/5 20%--1/1 100%------0/2 0%0/2 0%-
2HatchLurker0/2 0%---------0/1 0%0/1 0%-
3HatchHydraBust0/1 0%----------0/1 0%-
3HatchHydraExpo0/2 0%---------0/1 0%0/1 0%-
3HatchPoolHydra0/2 0%-------0/1 0%-0/1 0%--
4HatchPoolHydra0/1 0%----------0/1 0%-
5Pool0/4 0%-------0/1 0%-0/1 0%0/2 0%-
5PoolSpeed1/3 33%-1/1 100%-----0/1 0%-0/1 0%--
7Pool0/1 0%----------0/1 0%-
7PoolHydraLingRush7D0/1 0%----------0/1 0%-
9Hatch9Pool9Gas0/1 0%----------0/1 0%-
9HatchTurtleHydra0/1 0%------0/1 0%-----
9PoolGasHatchSpeed8D0/1 0%---------0/1 0%--
9PoolHatch0/2 0%----------0/2 0%-
9PoolSpeed17/31 55%1/1 100%-3/3 100%1/1 100%--1/1 100%1/1 100%-4/6 67%4/13 31%2/5 40%
9PoolSpeedLing0/1 0%------0/1 0%-----
9PoolSunken0/7 0%--------0/1 0%0/3 0%0/3 0%-
OverpoolSpeed1/3 33%-----1/1 100%---0/1 0%0/1 0%-
ZvP_11Hatch10Pool2/4 50%------1/1 100%--0/1 0%1/2 50%-
ZvP_2HatchHydra0/9 0%---------0/4 0%0/5 0%-
ZvP_9Hatch9Pool0/1 0%---------0/1 0%--
ZvZ_Overgas11Pool10/20 50%------1/1 100%3/4 75%-4/9 44%0/4 0%2/2 100%
ZvZ_Overpool11Gas0/2 0%----------0/2 0%-
ZvZ_Overpool9Gas1/4 25%----------0/3 0%1/1 100%

Steamhammer’s ZvZ_Overpool9Gas opening was successful against all Microwave tries, but notice that it was the only one: Flecks of blue, or entire streaks, crept into every other Steamhammer attempt. The end result does not look close, but in fact Microwave would have needed only a small increment of skill to turn it around; there was only one strategy it was unprepared to face.

microwave as seen by steamhammer

microwave played#steamhammer recognized
10Hatch9Pool9gas95 Naked expand | 3 Heavy rush | 1 Unknown
10HatchMain9Pool9Gas43 Unknown | 1 Turtle
10HatchTurtleHydra11 Naked expand
11HatchTurtleMuta11 Heavy rush
12HatchMain11 Unknown
12Pool2517 Naked expand | 5 Heavy rush | 3 Unknown
12PoolMain53 Heavy rush | 2 Unknown
2HatchLurker22 Naked expand
3HatchHydraBust11 Naked expand
3HatchHydraExpo21 Naked expand | 1 Heavy rush
3HatchPoolHydra21 Naked expand | 1 Heavy rush
4HatchPoolHydra11 Heavy rush
5Pool44 Fast rush
5PoolSpeed33 Fast rush
7Pool11 Fast rush
7PoolHydraLingRush7D11 Unknown
9Hatch9Pool9Gas11 Naked expand
9HatchTurtleHydra11 Heavy rush
9PoolGasHatchSpeed8D11 Heavy rush
9PoolHatch21 Unknown | 1 Heavy rush
9PoolSpeed3121 Unknown | 7 Naked expand | 3 Heavy rush
9PoolSpeedLing11 Naked expand
9PoolSunken74 Unknown | 3 Heavy rush
OverpoolSpeed32 Unknown | 1 Heavy rush
ZvP_11Hatch10Pool43 Naked expand | 1 Heavy rush
ZvP_2HatchHydra96 Heavy rush | 2 Turtle | 1 Naked expand
ZvP_9Hatch9Pool11 Naked expand
ZvZ_Overgas11Pool2019 Unknown | 1 Turtle
ZvZ_Overpool11Gas22 Unknown
ZvZ_Overpool9Gas44 Unknown

To play ZvZ truly well, Steamhammer needs a more detailed understanding of enemy builds. But even with this crude breakdown, I notice that most of the blue spots are associated with misunderstanding the main idea of Microwave’s play. On the other hand, many misunderstandings also show as red.

steamhammer as seen by microwave

steamhammer played#microwave recognized
6PoolBurrow11 FastRush
8-8HydraRush11 Unknown
9Hatch8Pool54 HeavyRush | 1 Unknown
9PoolHatchSpeedSpire11 NakedExpand
OverhatchLing11 HeavyRush
OverpoolBurrow11 NakedExpand
ZvZ_12HatchExpo55 NakedExpand
ZvZ_12PoolLing118 HeavyRush | 2 Unknown | 1 NakedExpand
ZvZ_12PoolMain33 HeavyRush
ZvZ_Overpool11Gas4436 Turtle | 5 Unknown | 3 NakedExpand
ZvZ_Overpool9Gas6451 Turtle | 8 Unknown | 5 NakedExpand
ZvZ_OverpoolTurtle1313 Turtle

The builds recognized as Turtle genuinely are turtle builds. They get mutalisks fast at the expense of weakness to zergling attack, which they compensate for with sunkens instead of a second hatchery. From the meta-strategy point of view, Steamhammer usually defeats Microwave in games where Steamhammer gains air superiority early, so Steamhammer’s choices make sense.

AIIDE 2020 - Steamhammer versus McRave

I added parsing for Steamhammer. DaQin is nearly the same. The only remaining bot which records data that can be analyzed this way is ZZZKBot, which has a difficult file format, does not keep a recognized enemy strategy, and doesn’t bother to write a newline at the end of its file. I may skip ZZZKBot.

The Steamhammer-McRave strategy crosstable is the most interesting one yet.

steamhammer strategies versus mcrave strategies

overallPoolHatch,12Pool,2HatchMutaPoolHatch,12Pool,2HatchSpeedlingPoolLair,9Pool,1HatchMuta
overall64/150 43%17/33 52%10/22 45%37/95 39%
12PoolLurker0/1 0%--0/1 0%
3HatchLingBurrow1/5 20%1/2 50%-0/3 0%
8DroneGas7/11 64%-1/1 100%6/10 60%
9HatchMain9Pool9Gas0/2 0%--0/2 0%
9PoolHatchSpeedAllInB0/1 0%--0/1 0%
9PoolSpire0/2 0%0/2 0%--
Over10HatchBust8/19 42%7/7 100%-1/12 8%
Over10PoolLing0/1 0%--0/1 0%
OverpoolSpeed3/15 20%1/5 20%0/3 0%2/7 29%
OverpoolSunk8/21 38%0/1 0%2/8 25%6/12 50%
OverpoolTurtle11/23 48%2/6 33%1/1 100%8/16 50%
ZvP_3HatchMuta0/1 0%--0/1 0%
ZvZ_12HatchExpo0/1 0%-0/1 0%-
ZvZ_Overgas9Pool0/2 0%-0/1 0%0/1 0%
ZvZ_OverpoolTurtle26/45 58%6/10 60%6/7 86%14/28 50%

For Steamhammer, either 8DroneGas (a zergling build despite the name) or else ZvZ_OverpoolTurtle (a mutalisk build) may dominate among the openings tried, while McRave’s best was the 1 hatch muta play because no Steamhammer try was better than even against it. It’s possible that switching between different kinds of builds was important, though, because the table suggests that the other counters are likely imbalanced (without a game-theoretic saddle point).

Both sides had trouble identifying the best strategies. If both had played their best strategies then the match would have come out close to 50%, while in fact Steamhammer came out behind, so Steamhammer had more trouble selecting from its excessive range of possibilities. I get the impression of a back-and-forth learning struggle.

steamhammer as seen by mcrave

steamhammer played#mcrave recognized
12PoolLurker11 HatchPool,12Pool,1HatchMuta
3HatchLingBurrow53 HatchPool,Unknown,2HatchLing | 1 HatchPool,Unknown,Unknown | 1 Unknown,Unknown,3HatchMuta
8DroneGas116 HatchPool,9Pool,2HatchLing | 2 PoolHatch,9Pool,2HatchLing | 1 PoolHatch,Unknown,2HatchLing | 1 HatchPool,Unknown,2HatchLing | 1 PoolHatch,Unknown,Unknown
9HatchMain9Pool9Gas21 PoolHatch,12Pool,2HatchLing | 1 HatchPool,Unknown,2HatchLing
9PoolHatchSpeedAllInB11 PoolHatch,9Pool,LingRush
9PoolSpire22 Unknown,Unknown,Unknown
Over10HatchBust197 HatchPool,12Pool,Unknown | 4 HatchPool,12Pool,2HatchLing | 3 Unknown,12Pool,Unknown | 2 HatchPool,Unknown,2HatchLing | 2 HatchPool,Unknown,Unknown | 1 PoolHatch,12Pool,Unknown
Over10PoolLing11 HatchPool,12Pool,Unknown
OverpoolSpeed155 HatchPool,9Pool,LingRush | 4 PoolHatch,12Pool,Unknown | 3 Unknown,12Pool,Unknown | 1 Unknown,9Pool,LingRush | 1 PoolHatch,9Pool,LingRush | 1 HatchPool,12Pool,3HatchMuta
OverpoolSunk218 HatchPool,9Pool,Unknown | 5 PoolHatch,9Pool,LingRush | 2 HatchPool,9Pool,3HatchMuta | 1 PoolHatch,9Pool,Unknown | 1 Unknown,Unknown,Unknown | 1 Unknown,12Pool,3HatchMuta | 1 HatchPool,Unknown,Unknown | 1 HatchPool,12Pool,3HatchMuta | 1 PoolHatch,Unknown,Unknown
OverpoolTurtle237 HatchPool,9Pool,LingRush | 5 Unknown,12Pool,1HatchHydra | 3 Unknown,Unknown,1HatchHydra | 2 HatchPool,Unknown,1HatchHydra | 2 Unknown,9Pool,1HatchHydra | 2 HatchPool,12Pool,1HatchLurker | 1 PoolHatch,12Pool,1HatchLurker | 1 HatchPool,12Pool,1HatchHydra
ZvP_3HatchMuta11 HatchPool,Unknown,2HatchLing
ZvZ_12HatchExpo11 HatchPool,Unknown,2HatchMuta
ZvZ_Overgas9Pool21 PoolLair,Unknown,1HatchMuta | 1 PoolLair,Unknown,Unknown
ZvZ_OverpoolTurtle4515 Unknown,Unknown,Unknown | 10 PoolLair,9Pool,1HatchMuta | 6 PoolLair,12Pool,1HatchMuta | 6 PoolLair,Unknown,1HatchMuta | 2 PoolLair,Unknown,Unknown | 2 Unknown,12Pool,Unknown | 2 Unknown,Unknown,3HatchMuta | 1 PoolLair,9Pool,Unknown | 1 Unknown,12Pool,3HatchMuta

Some curious stuff here. None of Steamhammer’s openings here is 3 hatch mutalisk, so those that are recognized that way may have added a third hatchery later in the game. Steamhammer does have an unfortunate love of laying down an unnecessary hatchery before its spire in ZvZ (3 hatcheries with zerglings is good, 2 hatcheries with mutalisks is good, 3 hatcheries with mutalisks is hard to justify in ZvZ). Looking at the Steamhammer openings tried more often, OverpoolSunk should be recognized as PoolHatch usually (maybe sometimes PoolLair). McRave got it wrong over half the time, without any big effect on its win rate. OverpoolTurtle should be PoolHatch with a hydra followup (this opening is not intended for ZvZ). For ZvZ_OverpoolTurtle, the closest match is PoolLair,9Pool,1HatchMuta. McRave got it right 10 times out of 45 and was close some other times. Failing to recognize anything (likely the scout was denied) was bad.

mcrave as seen by steamhammer

mcrave played#steamhammer recognized
PoolHatch,12Pool,2HatchMuta3322 Naked expand | 6 Unknown | 5 Heavy rush
PoolHatch,12Pool,2HatchSpeedling229 Naked expand | 9 Unknown | 3 Heavy rush | 1 Worker rush
PoolLair,9Pool,1HatchMuta9589 Unknown | 4 Turtle | 2 Naked expand

Worker rush? That is likely a bug. The other choices capture information about the game that is probably true and not particularly useful.