archive by month
Skip to content

AIIDE 2021 - McRave versus BananaBrain

McRave and BananaBrain both recorded all 157 of their mutual games. I chose to put McRave down the left side of the strategy cross, because its longer strategy names make the table hard to read otherwise. I also trimmed off the “PvZ_” and “Z_” prefixes from BananaBrain’s strategy names for compactness.

Blue is good for McRave, red is good for BananaBrain.

mcrave strategies versus bananabrain strategies

overall10/12gate1basespeedzeal2basespeedzeal4gate2archon5gategoon9/9gate9/9proxygatebisuneobisusairdtsairgoonsairreaverstove
overall28/157 18%8/54 15%1/3 33%1/5 20%1/1 100%1/1 100%1/1 100%2/8 25%1/5 20%1/4 25%1/3 33%2/12 17%1/1 100%7/59 12%
HatchPool,12Hatch,2HatchMuta16/86 19%3/28 11%1/1 100%1/3 33%1/1 100%1/1 100%1/1 100%0/1 0%-1/4 25%0/2 0%2/10 20%1/1 100%4/33 12%
HatchPool,12Hatch,2HatchSpeedling0/1 0%------0/1 0%------
HatchPool,9Pool,2HatchSpeedling2/2 100%------2/2 100%------
PoolHatch,9Pool,2HatchMuta3/15 20%0/2 0%------0/3 0%----3/10 30%
PoolHatch,9Pool,2HatchSpeedling0/3 0%------0/3 0%------
PoolHatch,9Pool,3HatchMuta4/19 21%4/13 31%-0/1 0%----0/1 0%----0/4 0%
PoolHatch,9Pool,6HatchHydra0/2 0%----------0/1 0%-0/1 0%
PoolHatch,Overpool,2HatchMuta0/4 0%0/2 0%0/1 0%--------0/1 0%--
PoolHatch,Overpool,2HatchSpeedling0/1 0%------0/1 0%------
PoolHatch,Overpool,3HatchMuta3/14 21%1/9 11%0/1 0%-----1/1 100%-1/1 100%--0/2 0%
PoolHatch,Overpool,6HatchHydra0/10 0%--0/1 0%---------0/9 0%

There we have the explanation for the 2 lonely HatchPool,9Pool,2HatchSpeedling games: The strategy was a successful reaction to proxy gates. I read it as meaning that the build is 9 hatch, 9 pool, and gas soon for the zergling speed upgrade.

BananaBrain split its effort between 10-12 gate and the Stove (a scout into dark templar build), very different builds. McRave answered both mostly with 12 hatch into 2 hatch muta. A hydralisk opening would have been a more natural way to counter both, but play what you’re good at.

mcrave as seen by bananabrain

mcrave played#bananabrain recognized
HatchPool,12Hatch,2HatchMuta8684 12hatch | 2 unknown
HatchPool,12Hatch,2HatchSpeedling11 unknown
HatchPool,9Pool,2HatchSpeedling22 12pool
PoolHatch,9Pool,2HatchMuta158 9pool | 7 overpool
PoolHatch,9Pool,2HatchSpeedling32 overpool | 1 9pool
PoolHatch,9Pool,3HatchMuta1913 9pool | 6 overpool
PoolHatch,9Pool,6HatchHydra21 overpool | 1 9pool
PoolHatch,Overpool,2HatchMuta44 overpool
PoolHatch,Overpool,2HatchSpeedling11 overpool
PoolHatch,Overpool,3HatchMuta1414 overpool
PoolHatch,Overpool,6HatchHydra1010 overpool

BananaBrain was accurate in recognizing 12 hatch and overpool, but had trouble with 9 pool. It did not try to narrow the build down any further than that.

bananabrain as seen by mcrave

bananabrain played#mcrave recognized
10/12gate5431 2Gate,10/12,Corsair | 8 2Gate,10/12,DT | 4 2Gate,10/12,ZealotRush | 3 2Gate,10/17,Corsair | 2 2Gate,Unknown,Corsair | 2 2Gate,9/9,DT | 2 2Gate,9/9,Corsair | 1 2Gate,10/17,4Gate | 1 2Gate,10/17,DT
1basespeedzeal32 1GateCore,2Zealot,DT | 1 1GateCore,2Zealot,Corsair
2basespeedzeal53 FFE,Forge,Speedlot | 1 FFE,Nexus,Speedlot | 1 FFE,Nexus,5GateGoon
4gate2archon11 FFE,Forge,5GateGoon
5gategoon11 FFE,Nexus,5GateGoon
9/9gate11 2Gate,9/9,Corsair
9/9proxygate87 2Gate,Proxy,ZealotRush | 1 2Gate,9/9,Unknown
bisu52 FFE,Forge,Unknown | 2 FFE,Forge,5GateGoon | 1 FFE,Nexus,Unknown
neobisu44 FFE,Forge,Speedlot
sairdt33 1GateCore,2Zealot,Corsair
sairgoon126 FFE,Forge,5GateGoon | 2 FFE,Nexus,5GateGoon | 2 FFE,Forge,Unknown | 1 FFE,Gateway,5GateGoon | 1 FFE,Gateway,Unknown
sairreaver11 FFE,Forge,Unknown
stove5927 1GateCore,2Zealot,Corsair | 10 1GateCore,Unknown,Corsair | 6 1GateCore,Unknown,DT | 6 1GateCore,2Zealot,DT | 3 2Gate,10/12,DT | 3 2Gate,10/12,ZealotRush | 2 2Gate,10/17,4Gate | 1 2Gate,10/17,DT | 1 2Gate,10/12,4Gate

In 1-base protoss plays, McRave tried to distinguish when the gates were made, and often got it right but had some trouble. It seems like something you can’t do perfectly, even if you combine direct scouting of the gates with inferences based on the enemy army. Recognizing the enemy build precisely doesn’t seem possible in general, though you can usually get close.

AIIDE 2021 - what McRave learned

I’m taking the bots in finishing order; McRave is next. Last year I analyzed McRave’s three-part strategy representation and learning algorithm. These apparently have not changed in outline, though details may have changed. The set of available strategies has been updated. For example, 6HatchHydra is new this year. It follows that the set of enabled strategy triples has also changed.

McRave is much stronger this year. It has become noted for dangerous mutalisk control.


#1 stardust

openinggameswinsfirstlast
HatchPool,12Hatch,2HatchMuta816%0156
PoolHatch,9Pool,2HatchMuta2214%13155
PoolHatch,9Pool,3HatchMuta110%4147
PoolHatch,9Pool,6HatchHydra90%9143
PoolHatch,Overpool,2HatchMuta90%6145
PoolHatch,Overpool,3HatchMuta138%11125
PoolHatch,Overpool,6HatchHydra120%1149
7 openings1576%
enemygameswins
1GateCore,2Zealot,4Gate1056%
2Gate,10/12,4Gate1010%
2Gate,10/17,4Gate405%
2Gate,9/9,4Gate10%
2Gate,Unknown,4Gate10%
5 openings1576%


9 pool into 2 hatch muta worked best, with 3 wins out of 22. That is not intuitive. The more natural 12 hatch into 2 hatch muta was tried more but was less successful. Did Stardust react inefficiently to the 9 pool? McRave appears to correctly understand that Stardust ends up with 4 gates despite taking different routes to get there. That’s kind of impressive.

Last year McRave scored 3 out of 150 against Stardust. This year it scored 8 out of 150 against a stronger Stardust—which seems to have updates specifically to defeat McRave, since McRave was the only bot to upset it in CoG 2021. Good progress!


#2 bananabrain

openinggameswinsfirstlast
HatchPool,12Hatch,2HatchMuta8619%0156
HatchPool,12Hatch,2HatchSpeedling10%2626
HatchPool,9Pool,2HatchSpeedling2100%30100
PoolHatch,9Pool,2HatchMuta1520%18144
PoolHatch,9Pool,2HatchSpeedling30%2429
PoolHatch,9Pool,3HatchMuta1921%4124
PoolHatch,9Pool,6HatchHydra20%12129
PoolHatch,Overpool,2HatchMuta40%996
PoolHatch,Overpool,2HatchSpeedling10%2525
PoolHatch,Overpool,3HatchMuta1421%16114
PoolHatch,Overpool,6HatchHydra100%1146
11 openings15718%
enemygameswins
1GateCore,2Zealot,Corsair3113%
1GateCore,2Zealot,DT812%
1GateCore,Unknown,Corsair1010%
1GateCore,Unknown,DT60%
2Gate,10/12,4Gate10%
2Gate,10/12,Corsair3116%
2Gate,10/12,DT1127%
2Gate,10/12,ZealotRush70%
2Gate,10/17,4Gate367%
2Gate,10/17,Corsair30%
2Gate,10/17,DT250%
2Gate,9/9,Corsair333%
2Gate,9/9,DT20%
2Gate,9/9,Unknown10%
2Gate,Proxy,ZealotRush729%
2Gate,Unknown,Corsair20%
FFE,Forge,5GateGoon922%
FFE,Forge,Speedlot729%
FFE,Forge,Unknown520%
FFE,Gateway,5GateGoon1100%
FFE,Gateway,Unknown10%
FFE,Nexus,5GateGoon425%
FFE,Nexus,Speedlot10%
FFE,Nexus,Unknown1100%
24 openings15718%


McRave’s wins over BananaBrain are dominated by games where BananaBrain timed out. In game 2754, BananaBrained timed out with 320 frames over 55ms, when McRave had 318 frames over 55ms—close call! McRave had more timeouts than any other bot, but only 3 losses to BananaBrain by timeout. BananaBrain’s timeouts seem to be concentrated on Dragon and McRave, and to a lesser extent on Steamhammer.

If HatchPool,9Pool,2HatchSpeedling was tried twice and won twice, why wasn’t it tried more often? The first try was on game 30 of 0-156. I imagine that it was a reactive build, not enabled as an initial choice but switched to under given circumstances. I didn’t read the source to verify that.

The enemy table shows a complex set of strategies by BananaBrain.


#3 dragon

openinggameswinsfirstlast
HatchPool,12Hatch,2HatchMuta6632%0156
HatchPool,12Hatch,2HatchSpeedling10%6161
PoolHatch,12Pool,2HatchMuta911%27150
PoolHatch,12Pool,3HatchMuta3741%1129
PoolHatch,Overpool,2HatchMuta2733%3127
PoolHatch,Overpool,2HatchSpeedling2100%2199
PoolHatch,Overpool,3HatchMuta1527%25148
7 openings15733%
enemygameswins
2Rax,Expand,Unknown1100%
2Rax,Main,1FactTanks10%
2Rax,Main,Unknown825%
2Rax,Proxy,Unknown10%
RaxCC,1RaxFE,1FactTanks333%
RaxCC,1RaxFE,5FactGoliath2512%
RaxCC,1RaxFE,Unknown1127%
RaxFact,Unknown,2PortWraith1100%
RaxFact,Unknown,5FactGoliath1323%
RaxFact,Unknown,Unknown250%
Unknown,Unknown,Unknown8939%
Unknown,Unknown,WorkerRush2100%
12 openings15733%


Over half of McRave’s losses to Dragon were by timeout. I think Dragon is an especially easy bot to time out against, because its strong macro and big battles with light units put heavy demands on the opponent.

The enemy table shows 89 games with Unknown,Unknown,Unknown. Apparently Dragon often denied scouting. Presumably the scouting overlord was afraid to approach due to marines, and any scouting drone was turned away. Also, I wonder about 2Rax,Proxy,Unknown. Did Dragon really proxy once, or was it a misrecognition? On Python, bases can be close by air. If McRave measures proxy distance by air distance, it might take a barracks in the enemy main for a proxy.


#4 steamhammer

openinggameswinsfirstlast
PoolHatch,12Pool,2HatchMuta2133%3142
PoolHatch,12Pool,2HatchSpeedling1217%1136
PoolLair,9Pool,1HatchMuta12551%0157
3 openings15846%
enemygameswins
HatchPool,10Hatch,1HatchMuta2100%
HatchPool,10Hatch,2HatchSpeedling1681%
HatchPool,10Hatch,3HatchMuta10%
HatchPool,10Hatch,Unknown850%
HatchPool,9Pool,3HatchMuta10%
HatchPool,9Pool,Unknown667%
HatchPool,Unknown,Unknown1100%
PoolHatch,12Pool,3HatchMuta1100%
PoolHatch,12Pool,Unknown250%
PoolHatch,4Pool,LingRush888%
PoolHatch,9Pool,2HatchSpeedling1100%
PoolHatch,9Pool,Unknown838%
PoolHatch,Unknown,2HatchHydra1100%
PoolHatch,Unknown,3HatchMuta2100%
PoolHatch,Unknown,Unknown475%
PoolLair,9Pool,1HatchMuta2100%
PoolLair,Unknown,1HatchMuta425%
Unknown,Unknown,1HatchHydra1100%
Unknown,Unknown,1HatchLurker2100%
Unknown,Unknown,1HatchMuta5127%
Unknown,Unknown,3HatchMuta20%
Unknown,Unknown,Unknown3429%
22 openings15846%


McRave chose from the same fixed set of 3 strategies against all the zergs. Only the 1 hatch mutalisks were able to hold their own with Steamhammer.


#6 willyt

openinggameswinsfirstlast
HatchPool,12Hatch,2HatchMuta8933%0156
PoolHatch,12Pool,3HatchMuta5535%1155
PoolHatch,Overpool,2HatchMuta130%2151
3 openings15731%
enemygameswins
RaxCC,1RaxFE,1FactTanks200%
RaxCC,1RaxFE,5FactGoliath3826%
RaxCC,1RaxFE,Unknown3033%
RaxFact,Unknown,5FactGoliath20%
Unknown,Unknown,Unknown6742%
5 openings15731%


Hurrying the mutas too much did not help against WillyT. The enemy table shows that WillyT sometimes countered with goliaths. Does McRave later make a hydra switch to fight the goliaths? WillyT sometimes goes for goliaths with 2 tanks, and it’s sensible to fight back with hydralisks. I didn’t see a hydra switch in the games I watched.

I noticed that McRave doesn’t clear the terran scout from its main until mutas come out. WillyT gets to know the exact timing for its turrets with no need to spend a scan.


#7 microwave

openinggameswinsfirstlast
PoolHatch,12Pool,2HatchMuta4965%3156
PoolHatch,12Pool,2HatchSpeedling1533%1147
PoolLair,9Pool,1HatchMuta9362%0149
3 openings15761%
enemygameswins
HatchPool,10Hatch,+1Ling10%
HatchPool,10Hatch,1HatchMuta10%
HatchPool,10Hatch,2HatchHydra1100%
HatchPool,10Hatch,2HatchSpeedling4146%
HatchPool,10Hatch,3HatchMuta1182%
HatchPool,10Hatch,Unknown1867%
HatchPool,9Pool,+1Ling10%
HatchPool,9Pool,2HatchSpeedling2100%
HatchPool,9Pool,3HatchMuta250%
HatchPool,9Pool,Unknown2100%
HatchPool,Unknown,2HatchSpeedling250%
PoolHatch,12Pool,+1Ling1100%
PoolHatch,12Pool,1HatchHydra1100%
PoolHatch,12Pool,2HatchSpeedling1100%
PoolHatch,12Pool,3HatchHydra1100%
PoolHatch,12Pool,3HatchMuta922%
PoolHatch,12Pool,Unknown580%
PoolHatch,4Pool,LingRush1479%
PoolHatch,9Pool,+1Ling10%
PoolHatch,9Pool,1HatchMuta10%
PoolHatch,9Pool,2HatchSpeedling1100%
PoolHatch,9Pool,3HatchMuta367%
PoolHatch,9Pool,Unknown250%
PoolHatch,Unknown,2HatchHydra1100%
PoolHatch,Unknown,Unknown3100%
Unknown,9Pool,+1Ling250%
Unknown,9Pool,1HatchHydra1100%
Unknown,Unknown,+1Ling30%
Unknown,Unknown,1HatchLurker1100%
Unknown,Unknown,1HatchMuta1100%
Unknown,Unknown,3HatchHydra250%
Unknown,Unknown,3HatchMuta1060%
Unknown,Unknown,Unknown1173%
33 openings15761%



#8 daqin

openinggameswinsfirstlast
HatchPool,12Hatch,2HatchMuta12383%0156
PoolHatch,9Pool,2HatchMuta333%12138
PoolHatch,9Pool,3HatchMuta250%1120
PoolHatch,9Pool,6HatchHydra20%5898
PoolHatch,Overpool,2HatchMuta2378%83155
PoolHatch,Overpool,3HatchMuta30%37105
PoolHatch,Overpool,6HatchHydra10%11
7 openings15778%
enemygameswins
FFE,Forge,5GateGoon2796%
FFE,Forge,Speedlot8874%
FFE,Forge,Unknown2100%
FFE,Forge,ZealotArchon7100%
FFE,Gateway,5GateGoon250%
FFE,Gateway,Speedlot2374%
FFE,Nexus,5GateGoon2100%
FFE,Nexus,Speedlot633%
8 openings15778%


The mutalisks did in DaQin. DaQin’s slow start puts 12 hatch ahead of other choices; DaQin makes cannons before nexus regardless of what the opponent does. DaQin defends its natural entrance with cannons, but not its nexus, so the mutalisks have a free hand and DaQin finds itself short of probes.


#9 freshmeat

openinggameswinsfirstlast
PoolHatch,12Pool,2HatchMuta4065%3152
PoolHatch,12Pool,2HatchSpeedling1947%1135
PoolLair,9Pool,1HatchMuta9869%0156
3 openings15766%
enemygameswins
HatchPool,10Hatch,2HatchSpeedling2662%
HatchPool,10Hatch,3HatchMuta1338%
HatchPool,10Hatch,Unknown1060%
HatchPool,9Pool,2HatchSpeedling729%
HatchPool,9Pool,Unknown250%
HatchPool,Unknown,3HatchMuta1100%
HatchPool,Unknown,Unknown1100%
PoolHatch,4Pool,LingRush2479%
PoolHatch,9Pool,2HatchSpeedling450%
PoolHatch,9Pool,Unknown2100%
PoolHatch,Unknown,2HatchSpeedling475%
PoolHatch,Unknown,3HatchMuta1100%
PoolLair,Unknown,Unknown1100%
Unknown,9Pool,Unknown4100%
Unknown,Unknown,+1Ling2100%
Unknown,Unknown,1HatchHydra2100%
Unknown,Unknown,1HatchMuta2100%
Unknown,Unknown,3HatchMuta1164%
Unknown,Unknown,3HatchSpeedling10%
Unknown,Unknown,Unknown3967%
20 openings15766%



#10 ualbertabot

openinggameswinsfirstlast
PoolHatch,12Pool,2HatchMuta10%9898
PoolHatch,Overpool,2HatchMuta8542%0156
PoolHatch,Overpool,2HatchSpeedling7131%4154
3 openings15737%
enemygameswins
1GateCore,0Zealot,4Gate2100%
1GateCore,0Zealot,DT1100%
2Gate,10/12,ZealotRush1090%
2Gate,9/9,Unknown20%
2Gate,9/9,ZealotRush3642%
2Rax,Main,MarineRush250%
2Rax,Main,Unknown633%
PoolHatch,4Pool,LingRush5240%
RaxCC,8Rax,Unknown100%
RaxFact,Unknown,2Fact1100%
RaxFact,Unknown,Unknown10%
Unknown,Unknown,Unknown1164%
12 openings15737%


McRave met UAlbertaBot with the same strategies as last year (except for one stray PoolHatch,12Pool,2HatchMuta this year). The same strategies by name, that is. The actual play was different and performed far worse against UAlbertaBot’s pressure builds. I looked at some games. When McRave respected its enemy and defended itself, it generally won. Sometimes it seemed to arrogantly conclude “Pff, you’re not worth spending a sunken on” and got overrun. As far as I could tell from watching games, it wasn’t a scouting miss—though it’s easy to overlook things in watching games. It had the feel of a bug.

AIIDE 2021 - what Steamhammer learned

The submitted Steamhammer was mistakenly configured to retain 100 game records per opponent. I had thought it was set for 200, and didn’t double-check. So of the 157 games against each opponent, of which 150 counted in the tournament, I have records for only the final 100. That’s 93 tournament games plus the 7 extra at the end.

My prepared data was successful. For all opponents which I prepared for, the prepared openings were among the highest scoring (including the zero score versus Stardust). It’s notable that Steamhammer’s gas steal was not successful against any opponent, perhaps another sign of an elite tournament. It was either infeasible or abandoned as a failure against every opponent except DaQin, and did no good then.

Steamhammer’s game records are rich with data. To show a little bit more of it, I added a new feature in the opening table. There are new “wins” and “losses” columns showing the median time that winning and losing games with that opening lasted. The median is a better measure than the mean, because we can expect the distribution of game times to be right-tailed: Games are limited to between zero minutes and one hour, but we expect a hump nearer to zero and a long tail of slower games. That inflates the mean and makes it misleading. For the tournament, I turned off surrendering, so Steamhammer played its losses out to the end.


#1 stardust

openinggameswinswinslossesfirstlast
10Hatch10%-8:484848
10HatchHydra10%-8:414545
11HatchTurtleHydra30%-10:331456
11HatchTurtleMuta30%-10:401067
11Pool10%-8:487474
12Gas11PoolMuta10%-6:536060
12Hatch_4HatchLing10%-14:082525
2HatchLurkerAllIn10%-9:126565
2x10Hatch10%-8:309595
2x10HatchBurrow10%-9:215555
3HatchHydraExpo40%-8:032386
3HatchLateHydras10%-7:4399
3HatchLing10%-7:545151
3HatchLingBurrow10%-8:317171
3HatchLingExpo20%-8:43637
4HatchBeforeLair10%-7:394747
4PoolSoft10%-8:266868
6Pool20%-9:127592
6PoolHide10%-8:351717
6PoolSpeed60%-8:27385
7DroneGas10%-7:518080
7Pool10Hatch10%-8:168383
7Pool12Hatch10%-8:365050
7Pool6GasLurker B10%-9:384444
7PoolHard10%-14:074141
7PoolHarder10%-8:237676
7PoolMid10%-8:038989
7PoolSoft10%-13:094242
8Hatch7PoolBurrow10%-9:476464
8Hatch7PoolBurrowB10%-8:2355
8Scout10%-8:148787
9HatchExpo9Pool9Gas20%-8:291694
9Pool8Hatch10%-8:179898
9Pool9Hatch10%-10:297070
9PoolBurrow10%-9:348484
9PoolBurrowB10%-8:0744
9PoolHatchSpeed7Drone20%-7:583173
9PoolHatchSpeed7DroneB20%-8:01024
9PoolHatchSpeedAllInB10%-8:412222
9PoolLair10%-7:369999
9PoolLurker10%-9:412727
9PoolSpeed20%-9:03826
9PoolSpire10%-9:033232
9PoolSunkSpeed10%-7:417979
AntiFact_13Pool10%-8:175454
AntiFact_2Hatch30%-7:396993
AntiFactoryHydra10%-7:086363
AntiZeal_12Hatch30%-10:203377
HiveRush10%-6:503030
Over10Hatch20%-10:071534
Over10Hatch1Sunk10%-8:359696
Over10Hatch2Sunk30%-10:33188
Over10Hatch2SunkHard10%-9:154646
Over10HatchBust20%-8:211849
Over10HatchSlowLings20%-8:236178
OverhatchExpoLing10%-8:301313
OverhatchLing10%-10:255858
Overpool14Hatch10%-7:3977
Overpool2HatchLurker20%-9:064382
OverpoolLurker10%-8:487272
OverpoolTurtle 010%-8:3222
Overpool_3HatchLing10%-10:292020
PurpleSwarmBuild10%-8:086666
ZvP_2HatchMuta20%-7:553897
ZvP_Overpool3Hatch10%-8:162929
ZvT_13Pool20%-9:185791
ZvT_7Pool10%-8:308181
ZvZ_12Pool10%-7:015353
ZvZ_Overpool11Gas10%-7:503535
ZvZ_Overpool9Gas10%-7:471919
70 openings1000% - 8:30
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Heavy rush100100%0%4040%0%40%58%
Naked expand--22%0%0%0%
Unknown--5858%0%0%0%
timing#medianearlylate
my combat unit1002:541:474:11
my gas993:171:347:33
enemy scout1001:571:187:53
enemy combat unit1002:412:214:37
enemy gas1004:203:376:37
enemy air unit99:428:3011:09
enemy cloaked unit89:439:1411:09
game duration1008:306:5018:12
gas steal#medianearlylatewinsenemy gas
gas steal decision102:121:582:210%4:22
gas steal success62:152:032:310%4:32
none or failed94---0%4:17
gas steal killed62:472:422:58


Steamhammer lost every game, but there is still valuable info here. If you’re losing all games, the game duration is a plausible proxy for how much trouble you caused the opponent. Especially so if you tried a rush opening and ended up in a long game—either the rush did some damage, or the opponent overreacted and was slowed down. Here, a couple of 7 pool builds were among the longest games. Steamhammer probably should have repeated them.

Notice the 4 pool and the hive rush. Steamhammer tried the whole range. Steamhammer recognized Stardust’s build in 2 games as nexus without cannons, a reaction that Stardust did not have last year. Otherwise, results are similar to last year’s.


#2 bananabrain

openinggameswinswinslossesfirstlast
11Gas10PoolMuta10%-6:043333
11Gas10PoolMutaB10%-6:215656
11HatchTurtleLurker1553%15:329:437198
11Pool10%-14:481010
12-11HatchStem10%-16:347878
2x10HatchSlow70%-8:30495
3HatchHydra10%-12:204242
3HatchLingBurrow10%-14:001919
4PoolSoft10%-7:557474
6Scout10%-8:486666
9Hatch8Pool10%-6:126969
9PoolBurrow812%16:2912:534382
9PoolHatchSpeed7DroneB10%-10:2611
9PoolHatchSpeedAllIn520%9:496:515868
9PoolHatchSpeedSpire80%-7:21399
9PoolHatchSpeedSpire210%-7:021515
9PoolSpeed10%-11:011414
9PoolSpeedAllIn10%-13:021616
9PoolSunkHatch10%-11:502828
AntiFact_Overpool11Hatch10%-13:189393
AntiZeal_12Hatch10%-7:482626
Over10Hatch1Sunk10%-15:104747
Over10Hatch2Sunk10%-14:382727
Over10Hatch2SunkHard10%-16:033636
Over10HatchHydra10%-10:353838
Overgas+110%-13:188585
OverhatchExpoLing1118%7:3414:512483
OverpoolLurker10%-6:156161
OverpoolTurtle617%15:0115:591796
ZvP_3HatchPoolHydra157%18:188:27270
ZvT_3HatchMuta10%-15:2700
ZvZ_12HatchMain10%-15:2366
ZvZ_12Pool10%-6:393131
33 openings10014% 15:24 10:42
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Fast rush22%0%1111%0%0%50%
Heavy rush9797%14%6363%13%63%22%
Safe expand11%0%33%67%0%0%
Turtle--11%0%0%0%
Unknown--2222%18%0%0%
timing#medianearlylate
my combat unit1003:031:474:38
my gas932:571:337:14
enemy scout1002:101:155:03
enemy combat unit1002:402:185:47
enemy gas946:053:169:12
enemy air unit916:073:1711:33
enemy cloaked unit579:266:0614:59
game duration10011:456:0421:43
gas steal#medianearlylatewinsenemy gas
gas steal decision102:301:513:3310%5:42
gas steal success32:101:552:110%4:22
none or failed97---14%6:07
gas steal killed32:502:482:51


In the 150 tournament games, Steamhammer scored 25 wins versus BananaBrain. Of those, 15 were due to BananaBrain suffering a frame timeout. Ouch. The game scores say that BananaBrain was ahead in 11 of the 15 games when it timed out. So the win percentages and times need to be interpreted carefully. The wins overall were longer games than the losses, possibly because BananaBrain was more likely to time out in a longer game with a larger game state to model and more units to control.

11HatchTurtleLurker scored over 50% in 15 games! Is it particularly good at prompting BananaBrain to time out? If I’d known about it ahead of time, I could have added it to my preparation and perhaps scored higher.

The build 2x10HatchSlow is shown as tried 7 times with no wins. I know from watching games that the opening scored wins earlier in the tournament, before the final 100 games; that is why it was tried so often later on. The build is very similar to Broken Horn’s 10 hatch-9 hatch-pool, but (I think) slightly more efficient. Apparently BananaBrain learned to avoid lines that lose to the mass of slow zerglings.

Successfully stealing its gas caused BananaBrain to take its gas sooner. I haven’t seen that before. In any case, it was only 3 games; Steamhammer found the gas steal unprofitable.


#3 dragon

openinggameswinswinslossesfirstlast
2HatchLurkerAllIn10%-30:514141
3HatchHydra10%-10:163333
5HatchPool2471%13:2328:23694
7-7HydraLingRush10%-16:574545
9PoolFastLurker933%9:1627:47192
9PoolHatchSpeed425%3:3116:321758
9PoolSunkSpeed20%-26:541438
AntiFact_13Pool1765%18:0516:345096
AntiZeal_12Hatch10%-38:541212
ZvP_4HatchPoolHydra862%5:5715:586599
ZvT_3HatchMutaExpo3278%15:5024:55098
11 openings10062% 15:36 25:13
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Factory4141%56%1717%47%24%41%
Naked expand--44%50%0%0%
Safe expand2323%74%1515%80%9%48%
Turtle--11%0%0%0%
Unknown--3131%68%0%0%
Worker rush3636%61%3232%59%75%8%
timing#medianearlylate
my combat unit983:122:137:53
my gas803:491:3412:10
enemy scout982:110:5312:07
enemy combat unit822:482:218:38
enemy gas816:042:4410:40
enemy air unit749:394:3117:18
enemy cloaked unit6210:515:5019:39
game duration10016:283:3160:00
gas steal#medianearlylatewinsenemy gas
gas steal decision172:091:562:5853%6:31
gas steal success92:162:072:3044%7:04
none or failed91---64%6:03
gas steal killed94:053:085:05


The most successful openings were 5HatchPool (5 hatcheries before pool, a supremely greedy build to exploit bots that never attack early) and ZvT_3HatchMutaExpo, the two openings I selected as preparation. For bots carried over from the previous year, good preparation is easier.

Dragon has a chaotic play style. Steamhammer’s wildest game of the tournament may be Steamhammer-Dragon on Longinus (replay file). Dragon played a V strategy: Vultures, valkyries, and vessels.


#5 mcrave

openinggameswinswinslossesfirstlast
11Gas10PoolMuta10%-10:078989
12Gas11PoolLurker10%-9:054040
2HatchHydra10%-6:324545
2HatchMutaPure10%-4:026161
4PoolHard30%-8:521443
9Pool8GasLurker10%-11:258888
9PoolHatchSpeedAllIn1662%6:0310:25096
9PoolLair10%-4:586868
Over10Hatch11Pool1844%10:457:54281
OverhatchLateGas10%-16:085353
ZvZ_12HatchExpo10%-8:182323
ZvZ_12HatchMain1030%11:058:26790
ZvZ_OverpoolTurtle4578%9:2711:10499
13 openings10056% 9:19 9:46
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Heavy rush2323%48%55%60%4%74%
Turtle7777%58%1111%0%8%87%
Unknown--8484%63%0%0%
timing#medianearlylate
my combat unit992:261:493:19
my gas942:091:435:02
enemy scout992:570:415:25
enemy combat unit1002:321:494:26
enemy gas983:472:526:12
enemy air unit945:054:017:07
enemy cloaked unit0---
game duration1009:274:0224:09
gas steal#medianearlylatewinsenemy gas
gas steal decision72:131:582:5557%2:58
gas steal success0-----
none or failed100---56%3:47
gas steal killed0---


Again two of my prepared builds, 9PoolHatchSpeedAllIn and ZvZ_OverpoolTurtle, were the top choices. Both are tough for most zerg bots to handle. My other prepared build, ZvZ_Overgas9Pool, does not appear in these 100 games. Apparently it flopped and was abandoned early. Rushy builds ended up winning faster than they lost, and more macro builds were the reverse, as you might expect. The timing table shows that McRave went spire nearly every game (overlords do not count as “air units” there), and not slowly. That’s normal for ZvZ, of course, but it shows that McRave did not favor builds to overrun the opponent with zerglings.


#6 willyt

openinggameswinswinslossesfirstlast
12Hatch_4HatchLing10%-14:087373
2.5HatchMutaExpo450%19:4214:047694
9HatchExpo9Pool9Gas10%-17:395656
9PoolHatchSpeedAllIn1338%4:538:51097
9PoolHatchSpeedSpire210%-9:337070
9PoolLair10%-16:433030
9PoolLurker1580%12:1520:15398
9PoolSpeed1346%6:2612:49190
9PoolSpeedAllIn1267%5:509:321299
ZvT_13Pool2564%19:3520:09481
ZvT_2HatchMuta10%-22:102929
ZvT_3HatchMuta1354%17:3518:492278
12 openings10056% 13:56 14:57
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Factory11%100%11%100%0%0%
Fast rush88%38%33%67%0%75%
Heavy rush55%80%22%0%0%60%
Naked expand4747%57%1616%100%17%64%
Safe expand3939%54%1313%46%10%67%
Unknown--6565%48%0%0%
timing#medianearlylate
my combat unit1002:182:135:58
my gas1002:141:456:22
enemy scout1002:141:427:17
enemy combat unit1002:582:066:14
enemy gas855:163:167:59
enemy air unit4414:598:3923:14
enemy cloaked unit3115:227:1920:23
game duration10014:304:4160:00
gas steal#medianearlylatewinsenemy gas
gas steal decision102:061:563:0910%5:34
gas steal success82:142:063:150%5:42
none or failed92---61%5:15
gas steal killed83:593:034:20


WillyT has become much stronger over the past year. It is better at handling Steamhammer’s lurker builds—except for the especially early 9 pool lurker build, which apparently catches it unready. Steamhammer’s improvements in lurker play were important to keep up with progress. I think Steamhammer’s diverse mix of openings was essential to counter WillyT, which has its own diverse mix and will figure out how to counter anything that is too predictable.

Steamhammer’s closest game of the tournament was Steamhammer-WillyT on Empire of the Sun (replay file). Steamhammer decisively stopped WillyT from taking the nearby north island base, but allowed it to hold the distant south island despite scouting it the instant it started. Notice WillyT’s interesting but somewhat uncoordinated dropship play throughout the game.


#7 microwave

openinggameswinswinslossesfirstlast
5HatchPool10%-5:231818
8Hatch7Pool580%10:159:322059
973HydraBust540%13:285:165491
9HatchMain9Pool9Gas10%-4:325656
9PoolHatchBurrow10%-5:264646
9PoolHatchSpeedAllIn2080%6:4812:00099
9PoolHatchSpeedSpire2483%11:056:06493
9PoolSpeedSpire10%-11:098181
ZvZ_12HatchMain2085%11:2017:506596
ZvZ_12PoolMain1173%9:355:06897
ZvZ_Overpool9Gas1164%13:2717:08242
11 openings10074% 11:14 8:31
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Fast rush1717%71%1414%93%6%59%
Heavy rush4949%71%2525%76%27%31%
Naked expand2626%81%1616%62%12%35%
Turtle88%75%99%89%12%25%
Unknown--3636%67%0%0%
timing#medianearlylate
my combat unit982:252:133:15
my gas972:311:477:09
enemy scout982:301:224:43
enemy combat unit1002:321:053:31
enemy gas664:352:2517:32
enemy air unit527:513:4317:33
enemy cloaked unit0---
game duration10010:574:2725:22
gas steal#medianearlylatewinsenemy gas
gas steal decision82:111:532:4175%4:33
gas steal success22:292:142:43100%4:34
none or failed98---73%4:35
gas steal killed22:402:212:58


Microwave had too many weaknesses. Of the 4 openings with 80% plus win rates, 3 were from preparation and one was Steamhammer’s discovery during the tournament. It’s interesting that the 12 hatch build ZvZ_12HatchMain was faster to win than to lose. I think that means it won with zerglings from its extra larvas.

The plan table shows that Microwave followed its own broad range of plans. In the timing table, see the wide and matching variation in Microwave’s gas timing and air unit timing. Did Microwave never get zergling speed in long games?


#8 daqin

openinggameswinswinslossesfirstlast
11Gas10PoolMuta10%-11:292424
2HatchLingAllInSpire812%9:3712:165292
2HatchLurkerPure10%-15:314545
2x10HatchSlow10%-9:525555
3HatchHydra20%-17:147293
3HatchHydraBust520%18:0712:092291
3HatchHydraExpo10%-11:0466
3HatchLing1233%7:0611:29373
3HatchLingExpo1217%34:0211:353697
4HatchBeforeGas20%-12:31221
4HatchBeforeLair20%-11:476799
5HatchBeforeGas10%-11:116868
5PoolHard2Player10%-9:4144
9HatchExpo9Pool9Gas1030%8:1212:257595
9Pool9Hatch10%-12:243232
AntiZeal_12Hatch10%-11:404141
Over10Hatch11Pool10%-14:043131
Over10Hatch2Sunk10%-15:217070
Over10PoolHydra10%-9:437474
OverhatchExpoLing3040%6:3410:26098
OverhatchLateGas10%-12:309696
OverhatchMuta10%-14:162929
ZvP_3BaseSpire+Den20%-14:06525
ZvP_3HatchPoolHydra20%-13:175078
24 openings10023% 7:02 11:40
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Heavy rush44%50%1010%0%25%0%
Naked expand33%0%1111%100%0%0%
Safe expand5858%24%4141%10%40%3%
Turtle3535%20%3434%24%40%6%
Unknown--44%0%0%0%
timing#medianearlylate
my combat unit1003:071:533:54
my gas1002:471:476:26
enemy scout1001:311:109:29
enemy combat unit1004:334:066:41
enemy gas945:285:066:52
enemy air unit1216:509:1020:14
enemy cloaked unit2412:396:3517:59
game duration10011:185:4260:00
gas steal#medianearlylatewinsenemy gas
gas steal decision302:081:552:3623%5:35
gas steal success242:172:062:2525%5:36
none or failed76---22%5:23
gas steal killed242:472:353:06


After this upset, I think I’ll take DaQin as a test opponent and finally figure out the skills to defeat it. DaQin is a Locutus fork, so beating it probably means doing better against other protoss bots.

The timing table shows that DaQin was remarkably late with air units. That includes both corsairs and observers—DaQin was late with both of them. In fact, I don’t remember whether it makes corsairs at all. Mutalisks might be a good choice to win.


#9 freshmeat

openinggameswinswinslossesfirstlast
11Gas10PoolMuta1267%7:065:50294
8PoolHard633%8:209:091445
9Hatch8Pool10%-6:489292
9PoolHatchSpeedAllInB3784%5:565:55599
9PoolSunkHatch862%5:069:46474
9PoolSunkSpeed825%8:017:04052
Overpool14Hatch10%-6:198686
OverpoolSunk1771%9:189:45397
ZvT_13Pool333%7:335:439093
ZvZ_12PoolMain743%7:075:351187
10 openings10064% 6:21 6:53
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Fast rush1313%38%1414%71%31%31%
Heavy rush5757%65%3030%67%25%32%
Naked expand--22%100%0%0%
Turtle3030%73%2525%52%10%20%
Unknown--2828%64%0%0%
Worker rush--11%100%0%0%
timing#medianearlylate
my combat unit1002:172:093:27
my gas982:531:467:53
enemy scout792:311:267:29
enemy combat unit1002:341:055:17
enemy gas394:012:559:29
enemy air unit294:434:015:51
enemy cloaked unit0---
game duration1006:304:1716:24
gas steal#medianearlylatewinsenemy gas
gas steal decision112:151:552:5745%3:31
gas steal success62:182:013:0133%-
none or failed94---66%4:01
gas steal killed63:042:314:06


When I was preparing opponent-specific data, Steamhammer had an overwhelming score against FreshMeat on BASIL. This result is good but not overwhelming; FreshMeat improved a lot in a short time. I had recognized that FreshMeat had made great strides, but there was not enough recent data to show what was working in the most recent games. So I made no preparation at all. These tables show an example of how Steamhammer figures out an opponent from scratch. I think it did OK.


#10 ualbertabot

openinggameswinswinslossesfirstlast
Over10HatchSlowLings10%-8:169999
OverhatchExpoMuta1759%5:216:262195
OverpoolTurtle8294%6:1711:51098
3 openings10087% 6:00 8:16
planpredictedrecognizedaccuracy
countgameswinscountgameswinsgood?
Factory1010%100%1313%100%10%0%
Fast rush3333%82%2727%85%36%18%
Heavy rush4949%90%3131%81%31%20%
Naked expand88%75%1212%100%0%12%
Unknown--1717%82%0%0%
timing#medianearlylate
my combat unit1002:262:153:13
my gas992:582:396:33
enemy scout882:081:219:58
enemy combat unit892:331:474:30
enemy gas823:442:3714:24
enemy air unit1414:2011:5015:59
enemy cloaked unit1014:212:3716:46
game duration1006:314:3521:33
gas steal#medianearlylatewinsenemy gas
gas steal decision82:321:482:5488%7:00
gas steal success42:292:102:4475%13:15
none or failed96---88%3:37
gas steal killed43:022:513:06


Comparing this year to last year, Steamhammer actually did a little worse against UAlbertaBot. The skills I improved over the last year didn’t include skills to defeat UAlbertaBot’s pressure builds, or to adapt better to its random race.


overall

totalZvTZvPZvZZvR
openinggameswinsgameswinsgameswinsgameswinsgameswins
10Hatch10% 10%
10HatchHydra10% 10%
11Gas10PoolMuta1553% 20% 1362%
11Gas10PoolMutaB10% 10%
11HatchTurtleHydra30% 30%
11HatchTurtleLurker1553% 1553%
11HatchTurtleMuta30% 30%
11Pool20% 20%
12-11HatchStem10% 10%
12Gas11PoolLurker10% 10%
12Gas11PoolMuta10% 10%
12Hatch_4HatchLing20% 10% 10%
2.5HatchMutaExpo450% 450%
2HatchHydra10% 10%
2HatchLingAllInSpire812% 812%
2HatchLurkerAllIn20% 10% 10%
2HatchLurkerPure10% 10%
2HatchMutaPure10% 10%
2x10Hatch10% 10%
2x10HatchBurrow10% 10%
2x10HatchSlow80% 80%
3HatchHydra40% 10% 30%
3HatchHydraBust520% 520%
3HatchHydraExpo50% 50%
3HatchLateHydras10% 10%
3HatchLing1331% 1331%
3HatchLingBurrow20% 20%
3HatchLingExpo1414% 1414%
4HatchBeforeGas20% 20%
4HatchBeforeLair30% 30%
4PoolHard30% 30%
4PoolSoft20% 20%
5HatchBeforeGas10% 10%
5HatchPool2568% 2471% 10%
5PoolHard2Player10% 10%
6Pool20% 20%
6PoolHide10% 10%
6PoolSpeed60% 60%
6Scout10% 10%
7-7HydraLingRush10% 10%
7DroneGas10% 10%
7Pool10Hatch10% 10%
7Pool12Hatch10% 10%
7Pool6GasLurker B10% 10%
7PoolHard10% 10%
7PoolHarder10% 10%
7PoolMid10% 10%
7PoolSoft10% 10%
8Hatch7Pool580% 580%
8Hatch7PoolBurrow10% 10%
8Hatch7PoolBurrowB10% 10%
8PoolHard633% 633%
8Scout10% 10%
973HydraBust540% 540%
9Hatch8Pool20% 10% 10%
9HatchExpo9Pool9Gas1323% 10% 1225%
9HatchMain9Pool9Gas10% 10%
9Pool8GasLurker10% 10%
9Pool8Hatch10% 10%
9Pool9Hatch20% 20%
9PoolBurrow911% 911%
9PoolBurrowB10% 10%
9PoolFastLurker933% 933%
9PoolHatchBurrow10% 10%
9PoolHatchSpeed425% 425%
9PoolHatchSpeed7Drone20% 20%
9PoolHatchSpeed7DroneB30% 30%
9PoolHatchSpeedAllIn5459% 1338% 520% 3672%
9PoolHatchSpeedAllInB3882% 10% 3784%
9PoolHatchSpeedSpire3262% 80% 2483%
9PoolHatchSpeedSpire220% 10% 10%
9PoolLair30% 10% 10% 10%
9PoolLurker1675% 1580% 10%
9PoolSpeed1638% 1346% 30%
9PoolSpeedAllIn1362% 1267% 10%
9PoolSpeedSpire10% 10%
9PoolSpire10% 10%
9PoolSunkHatch956% 10% 862%
9PoolSunkSpeed1118% 20% 10% 825%
AntiFact_13Pool1861% 1765% 10%
AntiFact_2Hatch30% 30%
AntiFact_Overpool11Hatch10% 10%
AntiFactoryHydra10% 10%
AntiZeal_12Hatch60% 10% 50%
HiveRush10% 10%
Over10Hatch20% 20%
Over10Hatch11Pool1942% 10% 1844%
Over10Hatch1Sunk20% 20%
Over10Hatch2Sunk50% 50%
Over10Hatch2SunkHard20% 20%
Over10HatchBust20% 20%
Over10HatchHydra10% 10%
Over10HatchSlowLings30% 20% 10%
Over10PoolHydra10% 10%
Overgas+110% 10%
OverhatchExpoLing4233% 4233%
OverhatchExpoMuta1759% 1759%
OverhatchLateGas20% 10% 10%
OverhatchLing10% 10%
OverhatchMuta10% 10%
Overpool14Hatch20% 10% 10%
Overpool2HatchLurker20% 20%
OverpoolLurker20% 20%
OverpoolSunk1771% 1771%
OverpoolTurtle8889% 617% 8294%
OverpoolTurtle 010% 10%
Overpool_3HatchLing10% 10%
PurpleSwarmBuild10% 10%
ZvP_2HatchMuta20% 20%
ZvP_3BaseSpire+Den20% 20%
ZvP_3HatchPoolHydra176% 176%
ZvP_4HatchPoolHydra862% 862%
ZvP_Overpool3Hatch10% 10%
ZvT_13Pool3057% 2564% 20% 333%
ZvT_2HatchMuta10% 10%
ZvT_3HatchMuta1450% 1354% 10%
ZvT_3HatchMutaExpo3278% 3278%
ZvT_7Pool10% 10%
ZvZ_12HatchExpo10% 10%
ZvZ_12HatchMain3165% 10% 3067%
ZvZ_12Pool20% 20%
ZvZ_12PoolMain1861% 1861%
ZvZ_Overpool11Gas10% 10%
ZvZ_Overpool9Gas1258% 10% 1164%
ZvZ_OverpoolTurtle4578% 4578%
total90048%20059%30012%30065%10087%
openings played12523101303

AIIDE 2021 - BananaBrain versus Dragon

BananaBrain and Dragon both recorded their own opening builds for all 157 games played, so I can align their learning files and see how their strategies matched up against each other. BananaBrain also recorded its representation of what the opponent played, so I can compare its idea of Dragon’s build with Dragon’s own idea. I first did this last year. Dragon is carried over from last year unchanged, while BananaBrain is much stronger now.

The win rates and coloring are from the point of view of BananaBrain. Blue is good for BananaBrain and red is good for Dragon.

bananabrain strategies versus dragon strategies

overall1rax fe2rax bio2rax mechbiodirty worker rushmass vulturesiege expand
overall117/157 75%8/8 100%19/30 63%8/8 100%12/13 92%8/8 100%27/36 75%35/54 65%
PvT_10/12gate34/48 71%1/1 100%9/17 53%1/1 100%2/2 100%2/2 100%3/5 60%16/20 80%
PvT_1gatedtexpo0/1 0%-0/1 0%-----
PvT_28nexus3/6 50%-1/2 50%---1/1 100%1/3 33%
PvT_2gaterngexpo2/4 50%-0/1 0%---1/1 100%1/2 50%
PvT_32nexus0/1 0%------0/1 0%
PvT_9/9gate78/96 81%7/7 100%9/9 100%7/7 100%10/11 91%6/6 100%22/29 76%17/27 63%
PvT_9/9proxygate0/1 0%------0/1 0%

dragon as seen by bananabrain

dragon played#bananabrain recognized
1rax fe87 T_unknown | 1 T_fastexpand
2rax bio3030 T_unknown
2rax mech88 T_unknown
bio1313 T_unknown
dirty worker rush88 T_unknown
mass vulture3621 T_1fac | 14 T_unknown | 1 T_2fac
siege expand5438 T_1fac | 16 T_unknown

Last year this table showed that BananaBrain was weak at recognizing Dragon’s builds, with a lot of unknowns. There are more recognized builds this year, but BananaBrain plays differently so I’m not sure whether BananaBrain has improved at recognition. What is clear is that everything is blue. Recognizing some builds does not seem to have helped BananaBrain; it did well no matter what.

AIIDE 2021 - what Dragon learned

Dragon records for each game only its own build and win/loss, so the information is sparse. It has a total of 7 builds. Dragon is a carryover bot, and I analyzed its game records from AIIDE 2020 last year. Dragon considers that “the opening” is a very brief phase of the game: It quickly adapts to what it sees of the opponent’s play, and the opening build fades out of view. Last year I found that, against many opponents, the choice of opening build made little difference; the game was decided later.


#1 stardust

openinggameswinsfirstlast
1rax fe240%5156
2rax bio356%1153
2rax mech180%2146
bio205%3144
dirty worker rush190%0133
mass vulture200%4152
siege expand210%6150
7 openings1572%


It’s interesting that the only openings to make a dent were “2rax bio” and “bio”. Was Stardust surprised by marines? If Stardust made zealots to get units faster, that may have backfired.


#2 bananabrain

openinggameswinsfirstlast
1rax fe80%682
2rax bio3037%1156
2rax mech80%7109
bio138%8140
dirty worker rush80%5148
mass vulture3625%2151
siege expand5435%0145
7 openings15725%


Again, the marines were a relatively successful choice against protoss. It’s a surprise. #8 DaQin below is different. Yesterday we saw that BananaBrain liked zealot openings against Dragon, and it’s true that marines with good micro can hold their own against zealots. Maybe BananaBrain liked zealots because they upset Dragon’s tech builds, and Dragon found that marines answered best, so that the two settled into this equilibrium with neither bot able to 100% counter the other. It’s a nice story, at least.


#4 steamhammer

openinggameswinsfirstlast
1rax fe5345%8124
2rax bio714%0153
2rax mech1225%4121
bio1729%6135
dirty worker rush4740%2156
mass vulture1527%10117
siege expand60%5122
7 openings15736%


Switching between opposite builds like fast expand (“1rax fe”) and worker rush (“dirty worker rush”) is not a bad plan for defeating Steamhammer. I don’t think Dragon did it on purpose, though. Most openings scored about equal.


#5 mcrave

openinggameswinsfirstlast
1rax fe2080%34153
2rax bio4065%0109
2rax mech1765%2390
bio2462%64100
dirty worker rush20%2098
mass vulture633%63137
siege expand4672%11154
7 openings15566%


Again, most were about equal, with only a couple of exceptions. “1rax fe” was also best against last year’s McRave, even though it played rather differently.


#6 willyt

openinggameswinsfirstlast
2rax bio10%5353
mass vulture15498%0154
2 openings15597%


Last year Dragon chose “2rax mech” as its build to trample on WillyT (winning fewer, 94%, even though this year’s WillyT is substantially stronger). I think it found something that worked and felt no need to experiment any further.


#7 microwave

openinggameswinsfirstlast
1rax fe2467%1120
2rax bio2861%31152
2rax mech6674%0149
bio2662%46147
dirty worker rush20%8124
mass vulture540%12156
siege expand633%43153
7 openings15765%



#8 daqin

openinggameswinsfirstlast
1rax fe9856%8156
2rax bio617%14104
2rax mech1136%1105
bio1331%7136
dirty worker rush50%5153
mass vulture2050%9103
siege expand40%0132
7 openings15747%


Best was the fast expansion. (“1rax fe” is faster than “siege expand”.) That makes sense against DaQin’s style of play.


#9 freshmeat

openinggameswinsfirstlast
1rax fe1225%4128
2rax bio1233%18143
2rax mech2536%0141
bio1030%9139
dirty worker rush3435%7155
mass vulture4953%10156
siege expand1527%15142
7 openings15739%


Mostly about equal again. At some point I’ll look at the games and see how FreshMeat upset Dragon.


#10 ualbertabot

openinggameswinsfirstlast
1rax fe4092%116155
2rax bio667%5473
2rax mech250%114115
bio1377%3649
dirty worker rush1776%5074
mass vulture7684%0113
siege expand250%85110
7 openings15683%

AIIDE 2021 - what BananaBrain learned

Here’s my summary of BananaBrain’s learning files. BananaBrain records both its own strategy and the recognized enemy strategy for every game.

#1 stardust

openinggameswinsfirstlast
PvP_10/12gate50%9121
PvP_12nexus50%10119
PvP_2gatedt50%3120
PvP_2gatedtexpo1619%0125
PvP_2gatereaver50%1118
PvP_3gaterobo50%13123
PvP_3gatespeedzeal50%5116
PvP_4gategoon2425%12126
PvP_9/9gate50%6122
PvP_9/9proxygate3829%8156
PvP_nzcore1315%4149
PvP_zcore50%7117
PvP_zcorez911%11144
PvP_zzcore1724%2127
14 openings15717%
enemygameswins
P_1gatecore650%
P_2gate2619%
P_2gatefast1331%
P_4gategoon10714%
P_cannonturtle10%
P_unknown40%
6 openings15717%


The most successful: Double proxy gates. Stardust plays the same every game, except for reactions to its opponent, so it’s interesting that BananaBrain diagnosed so many different openings. I suspect that they were all, or nearly all, 4 gate goon, and BananaBrain was not always able to scout long enough to see it. I think the variety is what you get when BananaBrain sees only part of the build.


#3 dragon

openinggameswinsfirstlast
PvT_10/12gate4871%0156
PvT_1gatedtexpo10%1616
PvT_28nexus650%13119
PvT_2gaterngexpo450%1091
PvT_32nexus10%8989
PvT_9/9gate9681%2118
PvT_9/9proxygate10%9292
7 openings15775%
enemygameswins
T_1fac5966%
T_2fac1100%
T_fastexpand1100%
T_unknown9679%
4 openings15775%


The best builds were zealot builds. BananaBrain seems to be especially successful with early zealot pressure.


#4 steamhammer

openinggameswinsfirstlast
PvZ_10/12gate367%57
PvZ_1basespeedzeal2186%37157
PvZ_2basespeedzeal978%21149
PvZ_4gate2archon10%3131
PvZ_5gategoon250%2930
PvZ_9/9gate9288%61156
PvZ_9/9proxygate10%5757
PvZ_bisu580%3236
PvZ_neobisu1283%819
PvZ_sairdt367%146148
PvZ_sairgoon10%2020
PvZ_sairreaver367%5860
PvZ_stove580%04
13 openings15883%
enemygameswins
Z_10hatch3284%
Z_12hatch5775%
Z_12hatchmain1100%
Z_12pool2100%
Z_4/5pool1100%
Z_9pool2396%
Z_9poolspeed888%
Z_overpool1984%
Z_unknown1580%
9 openings15883%


Again, zealot builds. Steamhammer tried a wide variety of counters, of which 12 hatch worked best. BananaBrain records only the earliest steps of zerg openings, so what BananaBrain calls Z_12hatch could have a range of followups.


#5 mcrave

openinggameswinsfirstlast
PvZ_10/12gate5485%17119
PvZ_1basespeedzeal367%5860
PvZ_2basespeedzeal580%15
PvZ_4gate2archon10%6161
PvZ_5gategoon10%6666
PvZ_9/9gate10%66
PvZ_9/9proxygate875%24100
PvZ_bisu580%5357
PvZ_neobisu475%6265
PvZ_sairdt367%1416
PvZ_sairgoon1283%7105
PvZ_sairreaver10%00
PvZ_stove5988%31156
13 openings15782%
enemygameswins
Z_12hatch8481%
Z_12pool20%
Z_9pool2378%
Z_overpool4589%
Z_unknown3100%
5 openings15782%


Most things worked against McRave, but especially tech openings. The earliest steps of McRave’s openings are stereotyped, so BananaBrain recognized few choices.


#6 willyt

openinggameswinsfirstlast
PvT_10/12gate4493%750
PvT_12nexus683%05
PvT_2gatedt10%66
PvT_32nexus2488%5174
PvT_9/9proxygate7799%80156
PvT_dtdrop250%7879
PvT_stove367%7577
7 openings15793%
enemygameswins
T_1fac12100%
T_2rax5595%
T_fastexpand5288%
T_unknown3895%
4 openings15793%


The proxy gates won 76 times out of 77. Ouch.


#7 microwave

openinggameswinsfirstlast
PvZ_10/12gate8697%31156
PvZ_1basespeedzeal10%2323
PvZ_2basespeedzeal250%1920
PvZ_4gate2archon250%2425
PvZ_5gategoon3083%3979
PvZ_9/9gate1580%982
PvZ_9/9proxygate250%6364
PvZ_bisu250%78
PvZ_neobisu250%2122
PvZ_sairdt580%04
PvZ_sairgoon580%2630
PvZ_sairreaver250%56
PvZ_stove367%1618
13 openings15787%
enemygameswins
Z_10hatch8100%
Z_12hatch3197%
Z_12pool1385%
Z_4/5pool13100%
Z_9pool5879%
Z_9poolspeed6100%
Z_overpool2075%
Z_unknown888%
8 openings15787%


Zealots were best again, though dragoons were good too. I wonder why the economic 10/12 gates were more successful than the fast 9/9 gates? It suggests that Microwave may overdefend, fearing fast zealots, and not have a strong enough economy to hold off efficient zealots instead. Or the followup after the zealots; BananaBrain likes to expand quickly.


#8 daqin

openinggameswinsfirstlast
PvP_2gatedt1080%037
PvP_2gatedtexpo10%66
PvP_2gatereaver14292%7156
PvP_9/9gate367%3133
PvP_zcore10%2626
5 openings15790%
enemygameswins
P_1gatecore6988%
P_4gategoon6891%
P_ffe1100%
P_unknown1989%
4 openings15790%


DaQin was apparently not ready for reavers. Otherwise it did not badly against a powerful opponent.


#9 freshmeat

openinggameswinsfirstlast
PvZ_4gate2archon888%2633
PvZ_9/9gate122100%35156
PvZ_neobisu1486%013
PvZ_sairgoon10%3434
PvZ_stove1283%1425
5 openings15796%
enemygameswins
Z_12hatch2785%
Z_12hatchmain2291%
Z_12pool1100%
Z_4/5pool27100%
Z_9pool11100%
Z_overpool3100%
Z_unknown66100%
7 openings15796%



#10 ualbertabot

openinggameswinsfirstlast
PvU_10/12gate475%03
PvU_9/9gate10%44
PvU_9/9proxygate580%1014
PvU_nzcore580%59
PvU_zcore14297%15156
5 openings15795%
enemygameswins
P_1gatecore19100%
P_2gate1100%
P_2gatefast2584%
P_4gategoon3100%
P_unknown6100%
T_1fac1100%
T_2fac22100%
T_2rax1694%
T_unknown11100%
Z_12hatch26100%
Z_4/5pool2387%
Z_overpool3100%
Z_unknown1100%
13 openings15795%

AIIDE 2021 - Stardust table in minutes and seconds

It occurred to me a little late that many people would find the Stardust data table easier to understand if the frame times were converted to minutes and seconds. So here’s that version. See the previous post from today.

firstDarkTemplarCompleted pylonInOurMain firstMutaliskCompleted
opponent games n min median max n min median max n min median max
bananabrain 155 20 5:15 5:29 16:11 0 - - - 0 - - -
dragon 156 0 - - - 0 - - - 0 - - -
steamhammer 158 0 - - - 0 - - - 17 4:59 5:43 7:11
mcrave 157 0 - - - 0 - - - 124 6:17 7:35 11:12
willyt 157 0 - - - 0 - - - 0 - - -
microwave 157 0 - - - 0 - - - 17 5:07 5:55 7:54
daqin 156 126 5:13 5:29 12:36 2 1:53 1:54 1:55 0 - - -
freshmeat 157 0 - - - 0 - - - 1 11:40 11:40 11:40
ualbertabot 157 17 4:19 4:29 4:36 0 - - - 0 - - -

AIIDE 2021 - Stardust’s learning

I investigated how Stardust’s learning works, and what it learned. It’s unusual, so it was worth a close look.

In its learning file of game records for each opponent, Stardust records values for 3 keys for each game, firstDarkTemplarCompleted, pylonInOurMain, and firstMutaliskCompleted. If the event occurs in the game, the value is the frame time of the event; otherwise the value is 2147483647 (INT_MAX, the largest int value, in this C++ implementation). It also records whether the game was a win or a loss. It records the hash of the map, too, but that doesn’t seem to be used again.

summarizing the data

The class Opponent is responsible for providing the learned information to the rest of the bot. It summarizes the game records via two routines.

  int minValueInPreviousGames(const std::string &key, int defaultNoData, int maxCount = INT_MAX, int minCount = 0);

If there are at least minCount games, then look through the game records, most recent first, for up to maxCount games. Look up the key for each game and return its minimum value, or the default value if there are none. This amounts to finding the earliest frame at which the event happened, or the default if it did not happen in the specified number of games.

   double winLossRatio(double defaultValue, int maxCount = INT_MAX);

Look through the game records, most recent first, for up to maxCount games and return the winning ratio, or the default value if there are no games yet.

using the summarized data

Each of the 3 keys is used in exactly one place in the code. Here is where firstDarkTemplarCompleted is looked up in the PvP strategy code:

    if (Opponent::winLossRatio(0.0, 200) < 0.99)
    {
        expectedCompletionFrame = Opponent::minValueInPreviousGames("firstDarkTemplarCompleted", 7300, 15, 10);
    }

This means “If we’re rolling you absolutely flat (at least 99% wins in the last 200 games), then it doesn’t matter. Otherwise there’s some risk. In the most recent 15 games, find the earliest frame that the first enemy dark templar was (estimated to be) completed, or return frame 7300 if none.” The default frame 7300 is not the earliest a DT can emerge; they can be on the map over a thousand frames earlier. So it is not a worst-case assumption. Further code overrides the frame number if there is scouting information related to dark templar production. It attempts to build a defensive photon cannon just in time for the enemy DT’s arrival, and sometimes to get an observer.

The key pylonInOurMain is part of cannon rush defense. Stardust again checks the win ratio and again looks back 15 games with a minimum game count of 10, this time with a default of 0 if there are not enough games. It starts scouting its base 500 frames (about 21 seconds) ahead of the earliest seen enemy pylon appearing in its base, which may be never. The idea is that Stardust doesn’t waste time scouting its own base if it hasn’t seen you proxy a pylon in the last 15 games, and delays the scout if the pylon is proxied late.

The key firstMutaliskCompleted is used very similarly, to decide whether and when to defend each nexus with cannons. The goal is to get cannons in time in case mutalisks arrive without being scouted. There are simple rules to decide how many cannons at each nexus:

    // Main and natural are special cases, we only get cannons there to defend against air threats
    if (base == Map::getMyMain() || base == Map::getMyNatural())
    {
        if (enemyAirUnits > 6) return 4;
        if (enemyAirThreat) return 3;
        if (enemyDropThreat && BWAPI::Broodwar->getFrameCount() > 8000) return 1;
        return 0;
    }

    // At expansions we get cannons if the enemy is not contained or has an air threat
    if (!Strategist::isEnemyContained() || enemyAirUnits > 0) return 2;
    if (enemyAirThreat || enemyDropThreat) return 1;
    return 0;

If the firstMutaliskCompleted check says that it’s time, it sets enemyAirThreat to true and makes 3 cannons each at main and natural, and at least 1 at each other base.

the data itself

Here’s my summary of the data in Stardust’s files. The files include prepared data. I left the prepared data out; this covers only what was recorded during the tournament. The tournament was run for 157 rounds, although the official results are given after round 150. The table here is data for all 157 rounds. I don’t have a way to tell which unrecorded games were from rounds 1-150 and which were from 151-157... though I think I could guess.

n is the number of games for which a value (other than 2147483647) was recorded for the key. The values are frame numbers.

firstDarkTemplarCompleted pylonInOurMain firstMutaliskCompleted
opponent games n min median max n min median max n min median max
bananabrain 155 20 7579 7897.5 23319 0 - - - 0 - - -
dragon 156 0 - - - 0 - - - 0 - - -
steamhammer 158 0 - - - 0 - - - 17 7188 8241 10355
mcrave 157 0 - - - 0 - - - 124 9070 10939 16146
willyt 157 0 - - - 0 - - - 0 - - -
microwave 157 0 - - - 0 - - - 17 7371 8534 11397
daqin 156 126 7533 7912.5 18154 2 2721 2743.5 2766 0 - - -
freshmeat 157 0 - - - 0 - - - 1 16801 16801 16801
ualbertabot 157 17 6230 6477 6627 0 - - - 0 - - -

As you might expect after deep contemplation of the nature of reality, only protoss makes dark templar or proxy pylons, and only zerg makes mutalisks. Nothing interesting was recorded for the terran opponents.

Notice that UAlbertaBot sometimes makes dark templar much earlier than the no-data 7300 frame default time; the others do not. DaQin is recorded as twice placing a proxy pylon in Stardust’s main. I didn’t think it ever did that. I guess it’s a holdover from the Locutus proxy pylon play, to trick opponents into overreacting? DaQin made DTs in most games, and McRave went mutalisks in most games. FreshMeat is recorded as having made a mutalisk (or more than one) in exactly one game, which seems unusual.

AIIDE 2021 - the learning curves

Before I dig into what each bot learned, I thought I’d look at the win percentage over time graph. Every bot wrote data, and it is likely that every bot attempted to learn and improve over time. Only some succeeded in improving their results, though.

Every bot shows a startup transient on the graph. The early swings up and down are controlled by some combination of luck and learning; luck because there are few games so statistical variation is high, and learning if and when the learning algorithms make fast adjustments (I think they usually do). To disentangle luck from learning, I think I want both statistical tests and a look into the algorithms to see what the learning rates could be. It would be too much for one post. In this post, I’m looking at the curves after 20 or 30 rounds, when the swings have mostly leveled off. I’m answering the question: Is the bot able to keep learning throughout a long tournament, outlearning its competition in the long run?

Four bots more or less held even. There are wobbles or slight trends, but not large ones. It’s what you expect if most bots are about equally good at lifetime learning. The learning systems are more or less saturated, and when one discovers an exploit, its counterpart figures out soon enough how to neuter the exploit, or so I imagine it. The learning competition is near an equilibrium.

graph of level-ish lines

Stardust doesn’t learn much, and apparently doesn’t have to. Steamhammer and McRave have messy early curves, perhaps reflecting complicated learning systems. FreshMeat has a beautiful clean early curve, unlike any other bot’s, suggesting that it knows what it is doing and straightforwardly does it. All 3 of the lower bots show low humps followed by slight regressions. I provisionally interpret that as the bot’s learning system saturating, then its opponents adjusting to that over time.

Four bots were able to improve. BananaBrain was in a class by itself, improving far more than any other bot. WillyT, Microwave, and UAlbertaBot had slight upward trends. None of them looks as impressive as AIUR did in 2015.

graph of rising lines

What gives BananaBrain a steeper curve? Is it good at learning in the long term, or bad at learning in the short term? (See that down-hook at the beginning.) I’ll look into it later on.

Dragon and DaQin fell behind. If somebody’s going up, somebody else must be going down. It may not be a coincidence that both are carryover bots from last year. Dragon’s learning files have a simple structure, the strategy name and win/loss. DaQin plays few strategies and has few ways to escape from exploits that other bots may find.

graph of falling lines

Next: Looking at Stardust’s learning.

AIIDE 2021 - what bots wrote data?

I looked in each bot’s final write directory to see what files it wrote, if any, and in its AI directory to see if it had prepared data for any opponents. Be sure to note: A bot does not necessarily use the data it writes. Preparation for specific opponents is not necessarily in the form of data in the AI directory, it might be in code.

#botinfo
1StardustUnlike last year, this year Stardust wrote data. It’s in JSON format, and records the map by hash, win or loss, and the timings of up to 3 game events, named firstDarkTemplarCompleted, firstMutaliskCompleted, and pylonInOurMain. The times look like frame numbers, and the great majority are 2147483647 (-1 printed as unsigned), which must mean “didn’t happen”. There is prepared data for 7 opponents (including PurpleWave which did not compete), so I assume that Stardust uses the data. I’ll find out for sure when I look at the source.
2BananaBrainThe learning files look unchanged from last year and the year before: One file for each opponent in the form of brief records of results. Each record consists of date+time, map, BananaBrain’s strategy (“PvZ_9/9proxygate”), the opponent’s recognized strategy (“Z_9pool”), a floating point number which we were told last year is the game duration in minutes, and the game result. Pre-learned data for DaQin and Dragon, the two stronger carryover bots. Last year there was pre-learned data for more opponents; maybe prep for opponents that might change turned out risky.
3DragonSimple game records, one per line, with strategy and game result, like "siege expand" won.
4SteamhammerSteamhammer’s learning file format is documented here.
5McRaveThe files look to have the same information as last year, but the format is slightly different. Two files for each opponent, named like ZvU UAlbertaBot.txt and ZvU UAlbertaBot Info.txt. The first file is short and counts wins and losses overall and for each of McRave’s strategies. The info file has detailed game records with aspects of the opponent’s strategy (2Gate,Main,ZealotRush), McRave’s strategy at 3 levels of abstraction (PoolHatch,Overpool,2HatchMuta), timings, and unit counts. No prepared files.
6WillyTThe files seem to have been corrected since last year. There is one file per opponent, one line per game, with lines that look like 20211005,Z,03,0. The items look like date, opponent race, a number 01 02 or 03, and win/loss. No prepared files.
7MicrowaveResult and history files for each opponent. They look identical to last year’s, except that Microwave now lists a much larger number of strategies for itself. The result files count wins and losses for each Microwave strategy. The history files have a one-line record of data about each game. Also pre-learned history files for all opponents, each with over 100 game records.
8DaQinCarried over from last year. Learning files straight from its parent Locutus (very similar to the old format Steamhammer files). No prepared files (and they’d be out of date if they existed).
9FreshMeat Three files for each opponent, except 6 files for UAlbertaBot, presumably because it plays random. The contents of the files are opaque: Two are bare lists of numbers, one is a list of incomprehensible 14-character strings. I’ll have to read the code. No prepared files.
10UAlbertaBotCarried over from past years. For each opponent, a file listing strategies with win and loss counts for each.

The only real surprise is Stardust’s minimalist and rather weird-seeming data. FreshMeat is new, of course, so anything it did would be unsurprising! It’s notable that every single participant wrote learning data, but that’s not a surprise either because this was an elite tournament. Except for Stardust, all the elite bots have used learning for years.

In unrelated news, I expected that CoG would post replays and learning files shortly after the AIIDE submission deadline. But no, they haven’t done it yet.

Steamhammer’s opening data

As promised, more on the opening timing data. Here’s the data I decided to collect. I hope I chose the most important data, because I expect that it will take a long time to collect a full set and I’d rather not have to redo it from scratch. I will have to update it over time as Steamhammer evolves, though.

I plan to play local games to systematically collect complete data, but that can’t be the only approach. Steamhammer needs real world experience with games against all kinds of opponents, so it can see the ways that its openings break down under stress. I think that will be key for playing well. That’s why I uploaded this data collection version of Steamhammer. I’ll see how it goes, but I may later upload a version that (heedless of its rank) chooses little-played openings to fill out the dataset.

By the way, this sounds like a lot of data when I describe it here. But it’s only a few lines of numbers. It’s not much.

• Opening timings: For each game, info about opening events, on Steamhammer’s side only. Ten numbers giving key info about the results of the build as of the time the opening line ends, plus the frame of completion of each tech building, each upgrade, and each tech researched. The completion times are recorded until 1500 frames after the end of the build, to give opening stuff time to finish and to see some events from the start of the middle game.

number of the first frame out of book
the number of workers alivehow strong is the economy?
mineral cost of all combat units producedhow strong is the army?
gas cost of all combat units produced
unspent mineralsdid the opening build use resources efficiently?
unspent gas
count of barracks, or gateways, or hatcheries/lairs/hiveswhat is the production capacity?
count of factories, or robo facilities, or 0 for zerg
count of starports, or stargates, or 0 for zerg
the number of bases, including incomplete bases

The 10 numbers outline the strategic state of the game at the end of the book line, and the completion times say what our tech is and when we got it. The idea is to save info about how the opening actually went, rather than how the book said it was supposed to go. Events will vary depending on the map, our reactions to the enemy strategy, the effects of fighting, random bobbles, and who knows what. My plan is to collect all the records for each opening (across all opponents), and reduce them to summaries for each matchup that show how the opening typically goes and the range of variation. The summaries can be stored in a static file read at initialization time. Add in win rates for each build and matchup, and Steamhammer will have a sound basis to choose openings against unfamiliar opponents. Choosing based on data will surely be better than choosing based on numbers I made up and typed into the config file.

Also keep data about enemy play, so that Steamhammer can choose openings based on data about the current opponent. This info is specific to the opponent, so it doesn’t need to be summarized into a separate file but lives on in the game records.

• Record the frame that each enemy unit type was first spotted, for the entire game. This summarizes a fair amount of the scouting info. It doesn’t tell how many production facilities of each type the enemy has when, but Steamhammer can’t scout that properly anyway. Info about proxies and contains is already kept in another field of the game records.

• Record the first two “significant” battles of the game. I modified the combat sim to save a count of the number of enemy units of each type for the largest battle that it has been asked to resolve so far. The first significant battle is one with at least 8 supply of enemy units. Since BWAPI doubles the supply, that means 4 marines, 2 zealots, or 8 zerglings, or the equivalent. Static defense takes 0 supply and is not counted, which may be a mistake. The second significant battle is one with at least 20 supply of enemy units. When we first notice a significant battle, we don’t record it right away, but wait 3 seconds to see if more enemy units appear. (3 seconds may be too low. Maybe 5 to 10 would be better.) Since the combat sim remembers the biggest battle, no information can be lost.

For each of the 2 battles, we keep the frame the battle started (saved by the combat simulator; it’s the actual frame, not 3 seconds delayed), and the distance of the center of the battle from our starting base in tiles, and the same distance from the enemy base (or -1 if the enemy base is not located). And we keep the count of unit types. Since these are very early battles, usually there are only 1 or 2 enemy unit types present. If the enemy is overrun without putting up much fight, then only one battle or no battle may be recorded.

The unit type timings tell is when we have to be ready for each enemy capability to come online, if the enemy repeats the same strategy. And the battles tell us something about how the enemy behaves, including whether the first fights were near our base or the enemy’s. To choose openings against a familiar opponent, we can check the timings of enemy play from the game records against the timings of our openings from the summary file for the matchup. If we can’t predict the enemy’s strategy, then we can check the range of play and hopefully find safe options. If we can predict, maybe we can find a direct counter.

Info about enemy timings is useful for reactions throughout the game, not only for choosing the opening. “XIMP’s carriers should be arriving around frame x, start the ranged attack upgrade in time to answer that.” And it can be used to automatically develop new opening lines to counter specific enemy builds. That feature is probably far in the future, but I’m looking forward to it.

In overview, the idea is to compare a model of our actual play against a model of the enemy’s actual play to figure out what is likely to work. That means understanding the game, at least for a limited value of “understanding”. It should be way more effective than trying stuff at random until you hit a winner.

lazy learning

Today’s post is AI background info. To use a neural network, or a decision tree, or most machine learning methods, you train it first and query it afterward. The system includes a model, represented as a data structure with code to interpret its meaning, and the learning algorithm adjusts the model to fit the training data. Training may be slow, but the model is usually designed so that answering queries is fast.

Some bots, including Steamhammer, do their opening learning differently, without persistent model data: They store only the training data, records of what happened in past games. When querying the system—deciding what opening to play based on experience—they look through the game records to find any relevant information and decide on the fly, not keeping any other permanent representation. That is called lazy learning, as opposed to eager learning, because it computes its model lazily on demand rather than eagerly up front. It’s a special case of lazy evaluation. There is also the closely related instance-based learning, which often means the same thing.

As an aside, this is analogous to the difference between an interpreter and a compiler. Partial evaluation of a lazy learning algorithm produces an equivalent eager learning algorithm, in exactly the same way that the appropriate Futamura projection converts an interpreter into a compiler. Not that that’s important, I just think it’s fun.

The prototypical lazy learning algorithm is k-nearest neighbors: Represent your training data as points in some space, each associated with a value. To query for some point in the space, you find the k closest points whose values you know and fit some function to them (say, take their average, which amounts to fitting a constant function). Choose k > 1 to average out any noise in individual values. I like to think of it in more general terms: Find whatever instances you can that are similar to your query, and generalize or synthesize the information in the instances into an answer to your query. That is a description of case-based reasoning. You can see k-nearest neighbors as a lightweight example and case-based reasoning as a heavyweight example of the same underlying idea.

Lazy learning does not mean that the learning system does not have a model, it only means that it does not have an explicit model that it stores as a data structure. There is still code to answer queries, and the code embodies an implicit model of how to turn training data into answers.

Lazy learning has advantages and disadvantages. Learning is trivial, since it amounts to storing records of your experience, so it is easy to keep up to date. With a deep learning model it is not very useful to update online in regular games, because training needs so much data. On the other hand, if your learning data is large, then with lazy learning you may not be able to use all of it to answer any given query. You’ll need a way to pick out the relevant records. It’s still effective if the relevant records are few enough, but by restricting the data you use you might be dropping useful information.

Lazy learning methods are natural for opponent modeling. I wouldn’t count them out for strategic uses, though. I can imagine a case base of strategic situations with reactions and evaluations of how the reactions worked out. That could produce a bot which keeps up with the meta by learning it from experience.

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.

AIIDE 2020 - various versus DaQin

I added parsing for DaQin’s files, which was little effort. I decided to dump all of DaQin’s analysis into a single post, because the tables aren’t that rich in information. Now I’m able to move on to other topics. I put the opponents on the left, so that in all cases, blue is good for the opponent and red is good for DaQin.

bananabrain strategies versus daqin strategies

overall2GateDT3GateDT4GateGoon
overall99/150 66%9/14 64%53/89 60%37/47 79%
PvP_10/12gate7/10 70%-2/5 40%5/5 100%
PvP_12nexus4/7 57%1/1 100%2/4 50%1/2 50%
PvP_2gatedt14/16 88%1/1 100%7/9 78%6/6 100%
PvP_2gatedtexpo10/14 71%1/2 50%5/7 71%4/5 80%
PvP_2gatereaver13/16 81%1/1 100%5/7 71%7/8 88%
PvP_3gaterobo8/13 62%2/2 100%5/7 71%1/4 25%
PvP_3gatespeedzeal2/7 29%0/1 0%1/5 20%1/1 100%
PvP_4gategoon4/8 50%1/1 100%2/6 33%1/1 100%
PvP_9/9gate15/16 94%-11/11 100%4/5 80%
PvP_9/9proxygate6/10 60%1/1 100%2/6 33%3/3 100%
PvP_nzcore7/11 64%1/1 100%4/8 50%2/2 100%
PvP_zcore3/7 43%0/2 0%3/5 60%-
PvP_zcorez2/7 29%-2/4 50%0/3 0%
PvP_zzcore4/8 50%0/1 0%2/5 40%2/2 100%

Reading DaQin’s openings out of its configuration file, I see that 2GateDT makes 2 dark templar out of the promised 2 gateways, adds 3 cannons in front of its natural, then expands. As a PvP build, that strikes me as illogical (you might want one cannon if the enemy also has dark templar). 3GateDT makes one gate, gets dragoons and dragoon range, adds a second gate and a citadel, and then the predefined build order ends—the rest is left to the strategy manager. That seems sensible as far as it goes, but does the strategy manager regularly add a third gate and make DTs as promised, or is the name of the opening a lie? See below for BananaBrain’s opinion on the question. In any case, 3GateDT is the opening that gave BananaBrain the most trouble.

bananabrain as seen by daqin

bananabrain played#daqin recognized
PvP_10/12gate1010 Fast rush
PvP_12nexus75 Fast rush | 1 Safe expand | 1 Naked expand
PvP_2gatedt1616 Fast rush
PvP_2gatedtexpo1413 DarkTemplar rush | 1 Unknown
PvP_2gatereaver1616 DarkTemplar rush
PvP_3gaterobo1313 DarkTemplar rush
PvP_3gatespeedzeal76 Fast rush | 1 Unknown
PvP_4gategoon85 DarkTemplar rush | 1 Naked expand | 1 Unknown | 1 Fast rush
PvP_9/9gate1616 Fast rush
PvP_9/9proxygate109 Fast rush | 1 Proxy
PvP_nzcore118 DarkTemplar rush | 1 Not fast rush | 1 Naked expand | 1 Unknown
PvP_zcore77 DarkTemplar rush
PvP_zcorez75 DarkTemplar rush | 2 Not fast rush
PvP_zzcore85 DarkTemplar rush | 2 Proxy | 1 Not fast rush

DaQin recognizes 9-9 gate as Fast rush, but also the economy-first 10-12 gate and even the fast expand 12 nexus. What BananaBrain calls a reaver build, DaQin sees as a dark templar rush. Strategy recognition has some odd results.

daqin as seen by bananabrain

daqin played#bananabrain recognized
2GateDT1412 P_1gatecore | 2 P_unknown
3GateDT8945 P_1gatecore | 32 P_4gategoon | 11 P_unknown | 1 P_ffe
4GateGoon4736 P_4gategoon | 9 P_1gatecore | 2 P_unknown

This suggests that DaQin’s 3GateDT was often not a dark templar build at all.

mcrave strategies versus daqin strategies

overallForgeExpand5GateGoonForgeExpandSpeedlots
overall97/150 65%3/3 100%94/147 64%
PoolHatch,Overpool,2HatchMuta97/150 65%3/3 100%94/147 64%

Not a lot of strategic variety here.

mcrave as seen by daqin

mcrave played#daqin recognized
PoolHatch,Overpool,2HatchMuta150117 Not fast rush | 28 Heavy rush | 5 Unknown

daqin as seen by mcrave

daqin played#mcrave recognized
ForgeExpand5GateGoon33 FFE,Forge,5GateGoon
ForgeExpandSpeedlots147121 FFE,Forge,Speedlot | 21 FFE,Nexus,Speedlot | 2 FFE,Forge,5GateGoon | 2 FFE,Forge,ZealotArchon | 1 FFE,Gateway,Speedlot

microwave strategies versus daqin strategies

overall4GateGoonForgeExpand5GateGoonForgeExpandSpeedlots
overall125/150 83%3/11 27%3/3 100%119/136 88%
1HatchMuta_Sparkle56/62 90%0/1 0%-56/61 92%
3HatchLingBust11/17 65%2/4 50%1/1 100%8/12 67%
3HatchMuta53/59 90%0/2 0%2/2 100%51/55 93%
3HatchMutaExpo5/9 56%1/4 25%-4/5 80%
3HatchPoolHydraExpo0/1 0%--0/1 0%
9Pool0/1 0%--0/1 0%
OverpoolLurker0/1 0%--0/1 0%

Why did DaQin play its most successful opening by far, 4GateGoon, less often than any other? It is not that it discovered the opening late; it played it first in game 10 of 150, and won that game. It immediately played it again and lost, but soon played it a third time and won again. It surely wasn’t confused by too many choices. Either there was a bug, or some built-in bias in DaQin’s decisions led it astray.

microwave as seen by daqin

microwave played#daqin recognized
1HatchMuta_Sparkle6234 Not fast rush | 19 Heavy rush | 7 Unknown | 2 Proxy
3HatchLingBust1712 Not fast rush | 4 Heavy rush | 1 Proxy
3HatchMuta5948 Not fast rush | 7 Heavy rush | 4 Proxy
3HatchMutaExpo98 Not fast rush | 1 Proxy
3HatchPoolHydraExpo11 Not fast rush
9Pool11 Fast rush
OverpoolLurker11 Unknown

daqin as seen by microwave

daqin played#microwave recognized
4GateGoon118 Unknown | 2 HeavyRush | 1 Proxy
ForgeExpand5GateGoon31 SafeExpand | 1 Turtle | 1 NakedExpand
ForgeExpandSpeedlots13668 Turtle | 22 HeavyRush | 20 SafeExpand | 16 NakedExpand | 10 Unknown

steamhammer strategies versus daqin strategies

overallForgeExpand5GateGoonForgeExpandSpeedlots
overall33/150 22%29/136 21%4/14 29%
10HatchLing0/1 0%0/1 0%-
11Gas10PoolLurker0/1 0%0/1 0%-
12-12Hatch0/1 0%0/1 0%-
12Hatch_4HatchLing0/2 0%0/2 0%-
2.5HatchMuta0/1 0%0/1 0%-
2HatchHydraBust0/2 0%0/1 0%0/1 0%
3HatchHydra0/2 0%0/2 0%-
3HatchHydraBust0/3 0%0/2 0%0/1 0%
3HatchHydraExpo0/1 0%0/1 0%-
3HatchLateHydras+10/1 0%0/1 0%-
3HatchLing26/59 44%24/52 46%2/7 29%
3HatchLingBust20/2 0%0/2 0%-
4HatchBeforeGas5/25 20%3/23 13%2/2 100%
4HatchBeforeLair0/1 0%0/1 0%-
5HatchBeforeGas0/2 0%-0/2 0%
5HatchPool0/1 0%0/1 0%-
5PoolHard2Player0/1 0%0/1 0%-
5Scout0/1 0%0/1 0%-
973HydraBust0/4 0%0/3 0%0/1 0%
9Pool8GasLurker0/1 0%0/1 0%-
9PoolHatchSpeed0/1 0%0/1 0%-
9PoolHatchSpeedSpire20/1 0%0/1 0%-
9PoolHatchSpire0/1 0%0/1 0%-
9PoolSpireSlowlings0/1 0%0/1 0%-
9PoolSunkHatch0/1 0%0/1 0%-
AntiFact_2Hatch0/1 0%0/1 0%-
AntiFact_Overpool9Gas0/1 0%0/1 0%-
AntiFactory20/1 0%0/1 0%-
Over10Hatch1Sunk0/1 0%0/1 0%-
OverhatchExpoMuta0/3 0%0/3 0%-
OverpoolSpeed0/1 0%0/1 0%-
OverpoolTurtle 00/2 0%0/2 0%-
Proxy8HatchNatural0/1 0%0/1 0%-
Sparkle 3HatchMuta1/6 17%1/6 17%-
ZvP_2HatchMuta0/1 0%0/1 0%-
ZvP_3BaseSpire+Den0/1 0%0/1 0%-
ZvP_3HatchPoolHydra1/7 14%1/7 14%-
ZvT_2HatchMuta0/1 0%0/1 0%-
ZvT_3HatchMuta0/1 0%0/1 0%-
ZvT_7Pool0/1 0%0/1 0%-
ZvZ_12PoolLing0/1 0%0/1 0%-
ZvZ_12PoolLingB0/2 0%0/2 0%-
ZvZ_Overpool11Gas0/1 0%0/1 0%-

steamhammer as seen by daqin

steamhammer played#daqin recognized
10HatchLing11 Unknown
11Gas10PoolLurker11 Heavy rush
12-12Hatch11 Not fast rush
12Hatch_4HatchLing22 Heavy rush
2.5HatchMuta11 Not fast rush
2HatchHydraBust21 Hydra bust | 1 Not fast rush
3HatchHydra22 Not fast rush
3HatchHydraBust32 Not fast rush | 1 Heavy rush
3HatchHydraExpo11 Not fast rush
3HatchLateHydras+111 Not fast rush
3HatchLing5940 Not fast rush | 16 Heavy rush | 3 Unknown
3HatchLingBust221 Not fast rush | 1 Unknown
4HatchBeforeGas2524 Not fast rush | 1 Unknown
4HatchBeforeLair11 Not fast rush
5HatchBeforeGas22 Not fast rush
5HatchPool11 Not fast rush
5PoolHard2Player11 Fast rush
5Scout11 Not fast rush
973HydraBust44 Not fast rush
9Pool8GasLurker11 Heavy rush
9PoolHatchSpeed11 Heavy rush
9PoolHatchSpeedSpire211 Fast rush
9PoolHatchSpire11 Heavy rush
9PoolSpireSlowlings11 Heavy rush
9PoolSunkHatch11 Fast rush
AntiFact_2Hatch11 Not fast rush
AntiFact_Overpool9Gas11 Not fast rush
AntiFactory211 Heavy rush
Over10Hatch1Sunk11 Heavy rush
OverhatchExpoMuta33 Not fast rush
OverpoolSpeed11 Heavy rush
OverpoolTurtle 022 Heavy rush
Proxy8HatchNatural11 Heavy rush
Sparkle 3HatchMuta66 Not fast rush
ZvP_2HatchMuta11 Not fast rush
ZvP_3BaseSpire+Den11 Heavy rush
ZvP_3HatchPoolHydra74 Not fast rush | 1 Heavy rush | 1 Hydra bust | 1 Unknown
ZvT_2HatchMuta11 Not fast rush
ZvT_3HatchMuta11 Not fast rush
ZvT_7Pool11 Fast rush
ZvZ_12PoolLing11 Not fast rush
ZvZ_12PoolLingB22 Not fast rush
ZvZ_Overpool11Gas11 Heavy rush

daqin as seen by steamhammer

daqin played#steamhammer recognized
ForgeExpand5GateGoon13679 Turtle | 41 Safe expand | 10 Heavy rush | 5 Naked expand | 1 Unknown
ForgeExpandSpeedlots147 Safe expand | 6 Turtle | 1 Unknown

ecgberht strategies versus daqin strategies

overall12NexusCarriers3GateDT
overall1/150 1%1/2 50%0/148 0%
14CC0/32 0%-0/32 0%
FullMech0/29 0%0/1 0%0/28 0%
JoyORush0/28 0%-0/28 0%
MechGreedyFE0/28 0%-0/28 0%
ProxyEightRax1/33 3%1/1 100%0/32 0%

ecgberht as seen by daqin

ecgberht played#daqin recognized
14CC3228 Safe expand | 2 Naked expand | 2 Unknown
FullMech2927 Factory | 2 Not fast rush
JoyORush2827 Factory | 1 Unknown
MechGreedyFE2812 Unknown | 9 Safe expand | 7 Not fast rush
ProxyEightRax3327 Fast rush | 5 Not fast rush | 1 Proxy

daqin as seen by ecgberht

daqin played#ecgberht recognized
12NexusCarriers22 Unknown
3GateDT148148 Unknown

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.