I wrote a new script to analyze Steamhammer’s learning data. A couple points: 1. Steamhammer crashed in nearly half of its games in CIG 2018. It can’t save learning data after a crash, so against some opponents Steamhammer had few opportunities to experiment. The number of crashes varied strongly depending on the opponent. 2. Steamhammer was set to remember the previous 100 games, since I figure there’s no play advantage to remembering more. The tournament was 125 rounds long. So in the tables below, “100 games” means that Steamhammer played at least 100 games without crashing, and up to 25 games may have been dropped, the early games. Against some weak opponents, Steamhammer learned, within 25 games, how to win 100% of the remaining games, and those tables give a 100% win rate for remembered games. Steamhammer did not score 100% against any opponent overall; it always had some losses in early games.
I should be able to run the same analysis for Steamhammer forks which retain Steamhammer’s opponent model file format.
#1 Locutus
opening | games | wins |
2HatchHydraBust | 1 | 0% |
3HatchHydraExpo | 2 | 0% |
3HatchLingBust | 1 | 0% |
3HatchLingExpo | 1 | 0% |
4HatchBeforeGas | 1 | 0% |
OverpoolSpeed | 9 | 56% |
6 openings | 15 | 33% |
A mystery is solved. Why was Steamhammer’s crash rate higher than I expected? Because many opponents learned to make Steamhammer crash. A crash for the opponent is a win, and the bot doesn’t care how it wins, so if it can learn a plan that makes the opponent crash reliably, it will. The stronger opponents tend to be learning bots, so Steamhammer crashed more often on average against strong opponents. This also means that my glib conclusion that Steamhammer won 66% of non-crash games, so it seems to have kept up with general progress is not sound. The non-crash games were mostly against weak opponents.
Locutus was lucky that it could figure out how to break Steamhammer. As Bruce mentioned in a comment, this Locutus version had a bug when facing certain zergling timings, and Steamhammer quickly figured out how to exploit the bug. It’s possible that Steamhammer minus the crash would have upset Locutus.
#2 PurpleWave
opening | games | wins |
11Gas10PoolMuta | 1 | 0% |
3HatchHydra | 3 | 0% |
3HatchLurker | 1 | 0% |
4PoolSoft | 1 | 0% |
7Pool12Hatch | 1 | 0% |
7PoolSoft | 1 | 0% |
9Hatch8Pool | 1 | 0% |
9HatchExpo9Pool9Gas | 1 | 0% |
9PoolSpeed | 1 | 0% |
AntiFactory | 1 | 0% |
Over10Hatch | 6 | 0% |
Over10Hatch1Sunk | 7 | 0% |
Over10Hatch2Sunk | 18 | 0% |
Over10HatchBust | 1 | 0% |
Over10HatchSlowLings | 4 | 0% |
OverhatchMuta | 1 | 0% |
OverpoolHatch | 1 | 0% |
OverpoolTurtle | 3 | 0% |
ZvP_3HatchPoolHydra | 2 | 0% |
ZvP_4HatchPoolHydra | 1 | 0% |
ZvT_12PoolMuta | 1 | 0% |
ZvZ_Overpool11Gas | 1 | 0% |
22 openings | 58 | 0% |
PurpleWave shut out Steamhammer. It didn’t learn to make Steamhammer crash because every game was a win for it anyway. Steamhammer desperately tried alternatives all over the map, including crazy all-ins and openings intended for ZvT and ZvZ, and nothing worked.
#3 McRave
opening | games | wins |
11Gas10PoolLurker | 1 | 0% |
4HatchBeforeGas | 1 | 0% |
9HatchExpo9Pool9Gas | 1 | 0% |
9PoolSpeed | 5 | 100% |
ZvP_3HatchPoolHydra | 2 | 0% |
5 openings | 10 | 50% |
#4 tscmoo
opening | games | wins |
9PoolExpo | 1 | 0% |
9PoolHatch | 1 | 0% |
9PoolSunkHatch | 1 | 0% |
AntiFact_2Hatch | 1 | 0% |
Over10Hatch2Sunk | 1 | 0% |
OverhatchExpoLing | 13 | 15% |
OverpoolSpeed | 22 | 23% |
7 openings | 40 | 18% |
#5 ISAMind
opening | games | wins |
3HatchHydraExpo | 1 | 0% |
4HatchBeforeGas | 1 | 0% |
OverpoolSpeed | 4 | 100% |
ZvP_2HatchMuta | 7 | 0% |
ZvP_3HatchPoolHydra | 6 | 0% |
5 openings | 19 | 21% |
#6 Iron
opening | games | wins |
2HatchHydra | 1 | 0% |
3HatchLingExpo | 2 | 0% |
4PoolHard | 1 | 0% |
6PoolSpeed | 1 | 0% |
9Hatch8Pool | 1 | 0% |
9HatchMain9Pool9Gas | 1 | 0% |
9PoolSunkSpeed | 1 | 0% |
AntiFact_13Pool | 4 | 0% |
AntiFact_2Hatch | 83 | 12% |
AntiFactory | 1 | 0% |
Over10Hatch | 1 | 0% |
PurpleSwarmBuild | 1 | 0% |
ZvP_2HatchMuta | 1 | 0% |
ZvT_12PoolMuta | 1 | 0% |
14 openings | 100 | 10% |
Iron is not a learning bot, so it did not learn to crash Steamhammer. Still, these results show a weakness in Steamhammer: Its best opening against Iron is AntiFactory
, which it tried only once in these 100 games. Steamhammer did not explore enough. I tried to fix the weakness in Steamhammer 2.0.
#7 ZZZKBot
opening | games | wins |
11Gas10PoolMuta | 1 | 0% |
8Pool | 7 | 29% |
9HatchMain9Pool9Gas | 1 | 0% |
9PoolSpeed | 1 | 0% |
OverhatchMuta | 1 | 0% |
Overpool+1 | 1 | 0% |
OverpoolSpeed | 1 | 0% |
ZvZ_12HatchMain | 2 | 0% |
ZvZ_12Pool | 1 | 0% |
ZvZ_12PoolLing | 48 | 58% |
ZvZ_Overgas9Pool | 2 | 0% |
ZvZ_Overpool9Gas | 2 | 0% |
12 openings | 68 | 44% |
#8 Microwave
opening | games | wins |
9PoolSunkHatch | 5 | 80% |
9PoolSunkSpeed | 27 | 67% |
OverpoolSunk | 1 | 0% |
OverpoolTurtle | 3 | 33% |
ZvZ_12PoolLing | 1 | 0% |
5 openings | 37 | 62% |
This looks like successful learning. Too bad Steamhammer only successfully played 37 of the 125 games.
#9 LetaBot
opening | games | wins |
11Gas10PoolLurker | 1 | 0% |
2HatchLurkerAllIn | 4 | 0% |
3HatchHydraExpo | 1 | 0% |
3HatchLurker | 13 | 38% |
9HatchExpo9Pool9Gas | 45 | 36% |
OverpoolLurker | 13 | 31% |
ZvP_2HatchMuta | 1 | 0% |
ZvT_12PoolMuta | 1 | 0% |
ZvT_13Pool | 1 | 0% |
ZvT_3HatchMuta | 1 | 0% |
10 openings | 81 | 31% |
#10 MegaBot
opening | games | wins |
11Gas10PoolLurker | 1 | 0% |
3HatchHydra | 1 | 0% |
3HatchHydraExpo | 1 | 0% |
3HatchLingExpo | 21 | 43% |
Over10Hatch | 1 | 0% |
OverhatchExpoLing | 1 | 100% |
ZvP_3HatchPoolHydra | 2 | 0% |
7 openings | 28 | 36% |
#11 UAlbertaBot
opening | games | wins |
3HatchLingExpo | 1 | 0% |
5PoolHard2Player | 1 | 0% |
9PoolExpo | 1 | 0% |
9PoolSpeed | 1 | 0% |
9PoolSunkHatch | 46 | 33% |
9PoolSunkSpeed | 29 | 48% |
Over10Hatch1Sunk | 2 | 0% |
OverpoolSpeed | 1 | 0% |
ZvZ_Overpool9Gas | 1 | 0% |
9 openings | 83 | 35% |
#12 Tyr
opening | games | wins |
9PoolHatch | 5 | 100% |
ZvP_3HatchPoolHydra | 5 | 0% |
2 openings | 10 | 50% |
#13 Ecgberht
opening | games | wins |
11Gas10PoolLurker | 10 | 50% |
2HatchLurker | 23 | 61% |
2HatchLurkerAllIn | 44 | 75% |
Over10HatchBust | 3 | 33% |
OverpoolLurker | 8 | 75% |
OverpoolSpeed | 3 | 33% |
ZvT_13Pool | 1 | 0% |
7 openings | 92 | 65% |
#14 Aiur
opening | games | wins |
11Gas10PoolLurker | 1 | 100% |
5PoolHard2Player | 1 | 100% |
9PoolSunkHatch | 1 | 100% |
9PoolSunkSpeed | 2 | 100% |
Over10Hatch | 1 | 0% |
Over10Hatch1Sunk | 2 | 50% |
Over10Hatch2Hard | 1 | 100% |
Over10HatchSlowLings | 1 | 100% |
OverpoolSpeed | 2 | 100% |
OverpoolTurtle | 3 | 67% |
10 openings | 15 | 80% |
#15 TitanIron
opening | games | wins |
3HatchLingBust | 1 | 0% |
AntiFact_13Pool | 6 | 50% |
AntiFact_2Hatch | 1 | 0% |
AntiFactory | 74 | 42% |
Over10Hatch2Sunk | 1 | 0% |
OverhatchExpoMuta | 1 | 0% |
OverpoolLurker | 1 | 0% |
ZvZ_Overgas9Pool | 14 | 21% |
ZvZ_Overpool9Gas | 1 | 0% |
9 openings | 100 | 37% |
This selection of openings implies that TitanIron plays a factory-first build against zerg, like Iron, and is a non-learning bot, like Iron. Later I’ll look into the source and find out for sure.
#16 Ziabot
opening | games | wins |
11Gas10PoolMuta | 4 | 25% |
2.5HatchMuta | 1 | 0% |
3HatchHydraBust | 1 | 0% |
6PoolSpeed | 1 | 0% |
8Pool | 7 | 71% |
9Hatch8Pool | 1 | 0% |
9PoolHatch | 4 | 50% |
ZvP_2HatchTurtle | 1 | 0% |
ZvZ_12Pool | 1 | 0% |
ZvZ_12PoolMain | 16 | 25% |
ZvZ_Overpool11Gas | 10 | 50% |
ZvZ_Overpool9Gas | 53 | 74% |
12 openings | 100 | 56% |
Low win rates against Zia and some other opponents suggest to me that Steamhammer had other new weaknesses besides crashing. I think Steamhammer should score over 80% against Zia.
#18 Overkill
opening | games | wins |
11Gas10PoolMuta | 10 | 90% |
4PoolHard | 23 | 96% |
6PoolSpeed | 28 | 100% |
9Hatch8Pool | 1 | 0% |
OverhatchLing | 2 | 50% |
OverpoolSpeed | 13 | 92% |
ZvZ_12HatchExpo | 2 | 50% |
ZvZ_12PoolMain | 1 | 0% |
8 openings | 80 | 91% |
#19 TerranUAB
opening | games | wins |
2HatchLurker | 52 | 90% |
AntiFact_13Pool | 8 | 88% |
AntiFact_2Hatch | 9 | 78% |
AntiFactory | 31 | 90% |
4 openings | 100 | 89% |
#20 CUNYbot
opening | games | wins |
11Gas10PoolMuta | 9 | 78% |
OverhatchLing | 34 | 97% |
ZvZ_12PoolLing | 27 | 96% |
ZvZ_Overgas9Pool | 1 | 0% |
ZvZ_Overpool9Gas | 19 | 89% |
5 openings | 90 | 92% |
#21 OpprimoBot
opening | games | wins |
11Gas10PoolLurker | 3 | 67% |
2HatchLurker | 2 | 50% |
2HatchLurkerAllIn | 6 | 83% |
6PoolSpeed | 19 | 100% |
OverpoolLurker | 1 | 0% |
OverpoolSpeed | 5 | 80% |
ZvT_12PoolMuta | 20 | 95% |
ZvT_3HatchMuta | 20 | 100% |
ZvT_3HatchMutaExpo | 24 | 100% |
9 openings | 100 | 94% |
#22 Sling
opening | games | wins |
4PoolHard | 4 | 75% |
4PoolSoft | 6 | 100% |
5PoolHard2Player | 3 | 100% |
ZvZ_12HatchMain | 1 | 0% |
ZvZ_Overgas9Pool | 1 | 0% |
5 openings | 15 | 80% |
The selection of fast rush openings suggests that Sling played a macro strategy which was countered by fast rushes. But I don’t want to draw strong conclusions based on 15 non-crash games out of 125.
#23 SRbotOne
opening | games | wins |
11Gas10PoolLurker | 14 | 93% |
2HatchLurker | 10 | 90% |
2HatchLurkerAllIn | 10 | 90% |
3HatchLurker | 17 | 100% |
4PoolSoft | 17 | 100% |
5PoolHard | 7 | 100% |
9HatchExpo9Pool9Gas | 4 | 75% |
9PoolLurker | 3 | 100% |
OverpoolLurker | 5 | 100% |
9 openings | 87 | 95% |
The wide range of lurker openings means that SRbotOne by Johan Kayser fought with mostly barracks units. Well, we already knew that.
#24 Bonjwa
opening | games | wins |
9PoolExpo | 6 | 100% |
9PoolSunkHatch | 5 | 100% |
9PoolSunkSpeed | 5 | 100% |
AntiFact_2Hatch | 3 | 100% |
AntiFactory | 5 | 100% |
ZvT_2HatchMuta | 1 | 100% |
6 openings | 25 | 100% |
#25 Stormbreaker
opening | games | wins |
11Gas10PoolMuta | 1 | 100% |
4PoolHard | 1 | 100% |
9PoolSunkHatch | 8 | 100% |
9PoolSunkSpeed | 8 | 100% |
OverhatchLing | 1 | 100% |
OverhatchMuta | 7 | 100% |
OverpoolSpeed | 1 | 100% |
OverpoolSunk | 7 | 100% |
ZvZ_12HatchExpo | 2 | 100% |
ZvZ_12HatchMain | 3 | 100% |
ZvZ_12PoolLing | 1 | 100% |
ZvZ_12PoolMain | 3 | 100% |
12 openings | 43 | 100% |
#26 Korean
opening | games | wins |
4PoolHard | 1 | 100% |
4PoolSoft | 3 | 100% |
5PoolHard | 5 | 100% |
5PoolHard2Player | 3 | 100% |
5PoolSoft | 1 | 100% |
6PoolSpeed | 6 | 100% |
OverhatchLing | 9 | 100% |
OverhatchMuta | 12 | 100% |
ZvZ_12HatchExpo | 13 | 100% |
ZvZ_12HatchMain | 16 | 100% |
ZvZ_12PoolLing | 14 | 100% |
ZvZ_12PoolMain | 17 | 100% |
12 openings | 100 | 100% |
#27 Salsa
opening | games | wins |
4PoolHard | 2 | 100% |
4PoolSoft | 4 | 100% |
5PoolHard | 7 | 100% |
5PoolHard2Player | 1 | 100% |
5PoolSoft | 1 | 100% |
6PoolSpeed | 8 | 100% |
OverhatchLing | 11 | 100% |
OverhatchMuta | 8 | 100% |
ZvZ_12HatchExpo | 12 | 100% |
ZvZ_12HatchMain | 20 | 100% |
ZvZ_12PoolLing | 13 | 100% |
ZvZ_12PoolMain | 12 | 100% |
ZvZ_Overgas9Pool | 1 | 100% |
13 openings | 100 | 100% |
overall
| total | ZvT | ZvP | ZvZ | ZvR |
opening | games | wins | games | wins | games | wins | games | wins | games | wins |
11Gas10PoolLurker | 31 | 68% |
28 | 71% |
3 | 33% |
| |
11Gas10PoolMuta | 26 | 69% |
| 1 | 0% |
25 | 72% |
|
2.5HatchMuta | 1 | 0% |
| | 1 | 0% |
|
2HatchHydra | 1 | 0% |
1 | 0% |
| | |
2HatchHydraBust | 1 | 0% |
| 1 | 0% |
| |
2HatchLurker | 87 | 82% |
87 | 82% |
| | |
2HatchLurkerAllIn | 64 | 73% |
64 | 73% |
| | |
3HatchHydra | 4 | 0% |
| 4 | 0% |
| |
3HatchHydraBust | 1 | 0% |
| | 1 | 0% |
|
3HatchHydraExpo | 5 | 0% |
1 | 0% |
4 | 0% |
| |
3HatchLingBust | 2 | 0% |
1 | 0% |
1 | 0% |
| |
3HatchLingExpo | 25 | 36% |
2 | 0% |
22 | 41% |
| 1 | 0% |
3HatchLurker | 31 | 71% |
30 | 73% |
1 | 0% |
| |
4HatchBeforeGas | 3 | 0% |
| 3 | 0% |
| |
4PoolHard | 32 | 91% |
1 | 0% |
| 31 | 94% |
|
4PoolSoft | 31 | 97% |
17 | 100% |
1 | 0% |
13 | 100% |
|
5PoolHard | 19 | 100% |
7 | 100% |
| 12 | 100% |
|
5PoolHard2Player | 9 | 89% |
| 1 | 100% |
7 | 100% |
1 | 0% |
5PoolSoft | 2 | 100% |
| | 2 | 100% |
|
6PoolSpeed | 63 | 97% |
20 | 95% |
| 43 | 98% |
|
7Pool12Hatch | 1 | 0% |
| 1 | 0% |
| |
7PoolSoft | 1 | 0% |
| 1 | 0% |
| |
8Pool | 14 | 50% |
| | 14 | 50% |
|
9Hatch8Pool | 4 | 0% |
1 | 0% |
1 | 0% |
2 | 0% |
|
9HatchExpo9Pool9Gas | 51 | 37% |
49 | 39% |
2 | 0% |
| |
9HatchMain9Pool9Gas | 2 | 0% |
1 | 0% |
| 1 | 0% |
|
9PoolExpo | 8 | 75% |
6 | 100% |
| | 2 | 0% |
9PoolHatch | 10 | 70% |
| 5 | 100% |
4 | 50% |
1 | 0% |
9PoolLurker | 3 | 100% |
3 | 100% |
| | |
9PoolSpeed | 8 | 62% |
| 6 | 83% |
1 | 0% |
1 | 0% |
9PoolSunkHatch | 66 | 50% |
5 | 100% |
1 | 100% |
13 | 92% |
47 | 32% |
9PoolSunkSpeed | 72 | 65% |
6 | 83% |
2 | 100% |
35 | 74% |
29 | 48% |
AntiFact_13Pool | 18 | 56% |
18 | 56% |
| | |
AntiFact_2Hatch | 97 | 21% |
96 | 21% |
| | 1 | 0% |
AntiFactory | 112 | 57% |
111 | 58% |
1 | 0% |
| |
Over10Hatch | 9 | 0% |
1 | 0% |
8 | 0% |
| |
Over10Hatch1Sunk | 11 | 9% |
| 9 | 11% |
| 2 | 0% |
Over10Hatch2Hard | 1 | 100% |
| 1 | 100% |
| |
Over10Hatch2Sunk | 20 | 0% |
1 | 0% |
18 | 0% |
| 1 | 0% |
Over10HatchBust | 4 | 25% |
3 | 33% |
1 | 0% |
| |
Over10HatchSlowLings | 5 | 20% |
| 5 | 20% |
| |
OverhatchExpoLing | 14 | 21% |
| 1 | 100% |
| 13 | 15% |
OverhatchExpoMuta | 1 | 0% |
1 | 0% |
| | |
OverhatchLing | 57 | 96% |
| | 57 | 96% |
|
OverhatchMuta | 29 | 93% |
| 1 | 0% |
28 | 96% |
|
Overpool+1 | 1 | 0% |
| | 1 | 0% |
|
OverpoolHatch | 1 | 0% |
| 1 | 0% |
| |
OverpoolLurker | 28 | 54% |
28 | 54% |
| | |
OverpoolSpeed | 61 | 56% |
8 | 62% |
15 | 73% |
15 | 87% |
23 | 22% |
OverpoolSunk | 8 | 88% |
| | 8 | 88% |
|
OverpoolTurtle | 9 | 33% |
| 6 | 33% |
3 | 33% |
|
PurpleSwarmBuild | 1 | 0% |
1 | 0% |
| | |
ZvP_2HatchMuta | 9 | 0% |
2 | 0% |
7 | 0% |
| |
ZvP_2HatchTurtle | 1 | 0% |
| | 1 | 0% |
|
ZvP_3HatchPoolHydra | 17 | 0% |
| 17 | 0% |
| |
ZvP_4HatchPoolHydra | 1 | 0% |
| 1 | 0% |
| |
ZvT_12PoolMuta | 23 | 83% |
22 | 86% |
1 | 0% |
| |
ZvT_13Pool | 2 | 0% |
2 | 0% |
| | |
ZvT_2HatchMuta | 1 | 100% |
1 | 100% |
| | |
ZvT_3HatchMuta | 21 | 95% |
21 | 95% |
| | |
ZvT_3HatchMutaExpo | 24 | 100% |
24 | 100% |
| | |
ZvZ_12HatchExpo | 29 | 97% |
| | 29 | 97% |
|
ZvZ_12HatchMain | 42 | 93% |
| | 42 | 93% |
|
ZvZ_12Pool | 2 | 0% |
| | 2 | 0% |
|
ZvZ_12PoolLing | 104 | 79% |
| | 104 | 79% |
|
ZvZ_12PoolMain | 49 | 73% |
| | 49 | 73% |
|
ZvZ_Overgas9Pool | 19 | 21% |
14 | 21% |
| 5 | 20% |
|
ZvZ_Overpool11Gas | 11 | 45% |
| 1 | 0% |
10 | 50% |
|
ZvZ_Overpool9Gas | 76 | 74% |
1 | 0% |
| 74 | 76% |
1 | 0% |
total | 1596 | 64% | 685 | 62% | 155 | 26% | 633 | 82% | 123 | 29% |
openings played | 69 | 37 | 36 | 31 | 13 |
This summary table took me hours to get right, so I hope it's useful.
Steamhammer played 69 openings in 1596 non-crash games, which is around 2/3rds of the openings it knows. No single matchup had more than 37 different openings. There were far more games against terran and zerg than against protoss and random, partly due to the crashing pattern. Against the random opponents (Tscmoo and UAlbertaBot), it settled on mostly general-purpose openings, as you might expect. Its best matchup was ZvZ, with a Jaedong-like 82% win rate (and lately, Jaedong crashes half the time too, so they’re just alike).
Openings that were both popular and successful include 2HatchLurker
and 2HatchLurkerAllIn
versus terran, 6PoolSpeed
with a 97% win rate against mostly weak opponents, 9PoolSunkSpeed
used across all matchups, and ZvZ specialties OverhatchLing
, ZvZ_12PoolLing
, and ZvZ_Overpool9Gas
. None of the opening choices surprises me, though some of the win rates do.
Comments
Tully Elliston on :
MicroDK on :
Jay Scott on :
McRave on :
Jay Scott on :