Steamhammer 2.4 source released
The source for Steamhammer 2.4 is available at Steamhammer’s web page.
The source for Steamhammer 2.4 is available at Steamhammer’s web page.
Steamhammer 2.4 is uploaded. Since I never got around to releasing the source of the previous version, I’ll release source shortly.
This version has 2 points of focus: First, fixing critical bugs that are responsible for many of the losses against weaker opponents, and second, coping with the deadly Styx opening. I wrote 18 new openings, 10 of which are connected to the Styx opening.
• Added the Config::Strategy::HumanOpponent flag for games against humans. It’s false by default, since almost all games are versus bots.
• Cancelling mutalisks just before making them is fixed. It happened intermittently in some openings. A spire takes 1800 frames to build, and Steamhammer is configured to conclude that production is jammed if there are 1440 frames without production. In some cases, the opening build might pause production for longer than the limit while saving up for mutalisks; a jam clears the queue and drops out of the opening, so the mutalisks were never made. I fixed it with a special case test, since only this one case was failing.
• Gas deadlock is an emergency that happens when Steamhammer needs gas for the next item, and has the extractors for it, but finds itself unable to collect the gas for some reason (for example, the base is under attack so the drones ran away). It clears the queue to try again. The condition for recognizing gas deadlock was too loose, and sometimes declared deadlock falsely. I tightened it up.
• Tracking of geysers and refinery buildings seemed to be wrong in some cases. I was not able to pin down any bad behavior it caused, but the code looked confused and I’ll be surprised if nothing is corrected.
• Combat sim is more fixed. In the previous version I fixed bugs in setting up the combat sim, related to short-circuit judgments when facing cloaked units. There was still a bug, and I traced it to... checking whether a unit’s air weapon was unequal to BWAPI::UnitTypes::None rather than BWAPI::WeaponTypes::None. Thank you C++ for your “helpful” type checking. This fix will make mutalisks more aggressive, as they should be, in certain situations.
• Restored the setting of 2 workers per mineral patch for terran and protoss. It had been accidentally set to the zerg value of 1.6.
• Against certain stronger enemy units, send more defenders. If an archon is in your base wreaking havoc, 2 marines will not stop it.
• The natural expansion cannot be one of the map’s starting bases. This fixes a problem that came up on the map Baekmagoji.
• StrategyBossZerg::enemySeemsToBeDead() works more nearly as intended. There was a minor bug. The enemy is considered to be dead and ready to be buried when all these conditions are met: 1. The enemy starting base has been found (so it can’t happen immediately when the game starts). 2. The enemy has no known surviving bases. 3. The known enemy ground army is not strong enough to threaten to win. 4. The enemy has no known anti-air units or anti-air static defense. When the enemy looks dead, Steamhammer techs to mutas and switches to a unit mix of drone + mutalisk. The mutalisks can efficiently hunt down any hidden or floating buildings.
• The micro system drops positional orders for which the position is “close enough” to the previous order. If code orders a move to (x, y) and then on a later frame a move to (x, y+1), the second order is dropped. The tolerance is a few pixels for short-range moves, larger for long moves. This reduces command spamming and smooths unit flow. In the long run, I ideally want to reduce Steamhammer’s APM to human levels.
• Targeting priority for enemy buildings is factored out and more nearly standardized across unit controllers. Streamhammer should destroy enemy bases a little more purposefully, with fewer cases of zerglings tearing down the spire while mutalisks tackle the spawning pool.
• Enemy observers are a higher priority target for ranged units and scourge, depending on the situation.
• When in book, if we have no zerglings, do not change a planned zergling into a drone. Steamhammer likes to skip zerglings when it foresees no danger. A similar change was already made for the case when it was out of the opening.
• Queen bug: The queen believed it could infest an unfinished command center. “It has few enough HP, let me fly across the map and take it.” When the building SCV was killed, the queen might sit over the unfinished command center forever. “This infestation sure is taking a long time. Oh well, stick with it!”
• Queen bug: When using broodling, the previous version was intended to be willing to make 2 queens, not the usual 1. After testing the feature, I introduced a typo that prevented it from working. Fixed.
• Prevent production freezes related to queen upgrades. Rare but painful.
• Allow air upgrades in any order, using 1 or 2 spires. Formerly, air carapace had to be first (or else production freezes were possible) and Steamhammer could upgrade in only 1 spire. This any-order-is-OK improvement was made earlier for ground upgrades.
• ZvZ_Overgas8Pool fills a small gap in the repertoire. A very small gap.
• 973HydraBust is a precise modern build versus protoss forge expand. The name is because you are supposed to end up with 9 drones in your main, 7 in your natural, and 3 at a third base. Steamhammer does not have the skills to distribute the drones efficiently as intended, but it does get the right total count.
• 2HatchMutaForever covers a weakness in the zerg strategy boss: There are times when growing the mutalisk flock is best, but the strategy boss doesn’t understand the value of stacking air units and prefers to switch into a different unit mix. The opening doesn’t really make mutalisks indefinitely, only for a long time. It also gets air upgrades.
• 2HatchFakeHydra and 2HatchFakeMuta are deceptive openings that make both hydralisk den and spire. The fake hydra opening makes a hydralisk den when the enemy scout should see it, chases the scout away, and adds the spire later. The enemy may predict hydra play or lurkers. The fake muta opening is similar but in reverse.
• 5HatchPool makes 5 hatcheries before spawning pool, an extremely greedy opening for use against opponents that move out late. (See my mention of Locutus in what Steamhammer learned. I’ve seen 6 hatch before pool work against a bot.) ZvP_5HatchPoolHydra is a specialized version that follows up with mass hydralisks. 5HatchPoolLing gets an evolution chamber before the spawning pool, so that when the first zerglings hatch, melee attack +1 is already half finished. The flood of lings is late but massive.
• The powerful Styx build. The openings 9PoolHatchSpeed7Drone, 9PoolHatchSpeed7DroneB, 9PoolHatchSpeed, 9PoolHatchSpeedAllIn, 9PoolHatchSpeedAllInB are variations on the Styx build of 9 pool, 3 pairs of zerglings, hatchery, extractor (leaving yourself with 7 drones), zergling speed, and deluge the enemy with zerglings (7 drones are enough). That exact build is 9PoolHatchSpeed7DroneB. The versions without a B have the extractor before the second hatchery, which gets faster zergling speed and a slightly slower hatchery. The versions without 7Drone use the extractor trick to end up with an 8th drone without losing time. The 8th drone does not make the zergling attack stronger, because 7 drones are enough to keep the 2 hatcheries completely busy producing, but it does establish leeway to lose a drone to accidents, make an emergency sunken, or transition into another plan. The plain version 9PoolHatchSpeed makes fewer zerglings and leaves the followup to the strategy boss, which is not too helpful because the strategy boss doesn’t understand the idea.
• Anti-Styx openings. If you know your opponent’s exact build order, you can always choose your own build to gain an advantage. (Don’t be predictable!) If the opponent is too greedy, you can clobber them with a rush or a bust before they’re ready. The Styx opening is not greedy; 9 pool is what you play to be safe against cheese. When the opponent is not greedy, you gain an advantage by being greedier, to a calculated extent. AntiStyx_9Pool is the simplest try. It uses the extractor trick for the 8th drone, and turns the drone into a sunken. The zergling wars are about equal, but the sunken at home is safer and allows more freedom of action because there is less need to hang back in defense. At Steamhammer’s level of play, the advantage is slight. However, this anti-Styx build is valuable as a general-purpose anti-cheese build; I configured it for that too. AntiStyx_3Hatch and AntiStyx_Muta are more successful at defending against the Styx opening. They open with overpool rather than 9 pool, gaining a lead in drones. Both make 1 sunken and use the safety it provides to scrape out more drones. The 3 hatch followup adds a third hatchery to eventually win the zergling wars, while the muta followup techs instead. The safe path is narrow; I’m curious to see how well the openings perform in practice.
Turtle openings can also cross the river Styx. Some turtles swim well, and they do not have the same weakness as Achilles. See wins over StyxZ by ZurZurZur, by Simplicity, and by Microwave with its turtle build.
• 9PoolHatchSpeedSpire and 9PoolHatchSpeedLurker are my try to pre-empt bot authors who may add a recognizer for the dangerous Styx opening so they can counter it. These builds start out with the Styx opening stem but transition into tech.
• I made tweaks to AntiZeal_12Hatch and 12HatchTurtle. They should be a trifle stronger.
Steamhammer 2.4 is almost ready. I’ll upload it tomorrow. It has accumulated enough critical bug fixes and changes; it is time to put it on the road and see how it drives.
New are 4 variants of the “Styx” opening (popularized, not invented, by StyxZ—as Ogden Nash said, “Don’t be a discoverer, be a promoter.”). A later post will analyze and compare the variants. And I wrote 3 counter-Styx openings designed to defend and come out ahead.
In 2016, when Steamhammer was brand new, it squeaked into the SSCAIT final playoffs through a tiebreaker match. In 2017 and 2018, it was clear to me ahead of time that Steamhammer would make it into the finals. This year, my life and schedule have been disrupted and I made less progress. Some of the work I put in, like queen skills, was more about having fun than about playing better, because I need some fun. The bottom line is, Steamhammer is failing to keep up with advances. Its rank is sliding.
I think that Steamhammer is still likely to make it into the SSCAIT round of 16, but it may be a close call. There’s a real risk that it may fall short. The fixes in version 2.4 may claw back a rank or two, but not enough to eliminate the risk. It’s possible that I can change Steamhammer’s prospects before then by implementing a killer skill (I have one in mind), but that’s risky in itself, and my past attempts to code killer skills before a deadline have fallen short. But we’ll see.
I watched the SCHNAIL video and I’m pleased. Today I added a HumanOpponent flag to Steamhammer’s configuration file, to make the bot more fun for humans to play against. If you set it to true, the flag has 2 effects:
1. It tells the opponent model that the opponent is unpredictable, which the opponent model takes to mean “I’d better be unpredictable too so I can’t be exploited.” It chooses openings more randomly. This is just turning on a standard Steamhammer behavior that already existed.
2. When losing, Steamhammer ggs out much earlier. Steamhammer in the past assumed that its opponent is a bot and may mess up the win, so it surrenders barely one step before it is provably unable to win. (Even so, I’ve seen a couple games over the years when it might have won if it hadn’t given up—when it had no drones and no combat units and no money, but had units in production that could outfight the opponent which was also near death. It’s extremely rare.) Versus a human, that gg timing is way way too late, unacceptably late. When HumanOpponent is turned on, Steamhammer follows a two-part rule: A. The enemy is much stronger than me—my supply is less than half the enemy’s known supply. B. I have been hurt—my supply has fallen below half of its high water mark. The B part ensures that Steamhammer doesn’t give up without a fight merely because it has been grossly outmacroed.
I’m curious to find out how well the gg rule works in real human games. In test games, I thought the gg still came later than a strong human would prefer. But perhaps it is a good fit for human players who deem Steamhammer an interesting opponent. Also, the enemy’s known supply is generally less than the enemy’s true supply, and Steamhammer is weak at scouting so often it is much less. But I will need to improve scouting as part of my strategy adaptation project, and gg timing may improve when I do.
About SCHNAIL: Obviously we can’t expect SCHNAIL users to edit Steamhammer’s config file and set the HumanOpponent flag. The file won’t be exposed to them at all; they don’t need to know it exists. I asked Sonko if there will be a way for a bot to tell that it is running under SCHNAIL. Whatever the final arrangement ends up being, I will help Steamhammer fit into it so the bot does sensible things in human games.
I was testing a macro build on the map Baekmagoji, a 2 player map where macro builds are fitting because each main base has 2 geysers and 18 mineral patches—double the usual. (I routinely test on all kinds of maps.) Early in the game, Steamhammer suddenly panicked and canceled a hatchery to get its spawning pool immediately. What was going on?
The bug, or I should say bugs, turned out to be this: Because the enemy main was so rich in resources, Steamhammer decided “well, it’s a bit far away, but still it’s the best choice for my natural base.” When the scout found enemy buildings (“hey, that’s in my natural”), Steamhammer concluded that it was getting proxied. Panic! That was easy to fix; the chosen natural is not allowed to be a starting base. But wait, why was the first expansion hatchery already started somewhere else, so that it could be canceled? Because the choice of the natural base and the actual first expansion taken are not quite coordinated correctly; in some cases they can be different for no good reason. Ack!
Baekmagoji is a difficult map for bots. Another issue is that some of the mineral patches in the main are not reachable until other patches are mined out. It’s a clever design, but Steamhammer doesn’t understand it and tries to assign drones to minerals that they can’t reach. Well, that’s not important to fix yet. I can’t think of another competitive map that would trigger this bug (though more than a few Blizzard maps do). Also notice the neutral sunken colonies spreading creep, and the blocking temples and blocking minerals. Lots of tricks lying in wait.
New bot Crona is, as it says in its description, BananaBrain playing zerg. It was uploaded today and has started out well. The name “Crona” is after an anime villain.
Sp far, I have only seen Crona play with zerglings and mutalisks, no other units. Here are the names of Crona’s openings, extracted from the binary. “Main Muta/Hydra/Ling” looks like an unrelated string that sneaked into the list, but maybe it’s an opening too.
ZvZ_2hatchling
ZvZ_5pool
ZvT_2hatchling
ZvT_4pool
ZvT_2hatchmuta_12pool
ZvT_2hatchmuta_12hatch
ZvP_2hatchling
ZvP_5pool
ZvP_4pool
ZvP_2hatchmuta
Main Muta/Hydra/Ling
ZvU_2hatchling
The build ZvZ_2hatchling is the “Styx build” of 9 pool, 3 pairs of zerglings, second hatchery, extractor, research zergling speed and produce zerglings for a long, long time. (Note 1: One of the rules of naming is that the origin of a thing cannot be the name; you have to pick something later. Note 2: I’ve tested both variants, and I’m pretty sure that the PurpleSwarm variant with extractor before the second hatchery is better.) Likely the other 2hatchling openings are too.
When playing 4 pool, and presumably other builds, Crona sticks with 1 hatchery and 3 drones for a while, then transitions to 2 hatcheries and 7 drones, then later to 3 hatcheries. I assume the sequence continues. My impression is that the expansions are on a timer: I’ve done this long enough, time for another hatchery. It’s a simple way to slowly increase pressure on the opponent.
Crona’s zerg play is good—see its results—but still looks a little rough to me. It doesn’t scout with its overlord. It has a glitch where, at a certain point in the opening, all the drones move away from the minerals for a second before returning. Crona seems a little confused about drone transfers in general. These things should not be hard to fix, though.
I see terran openings in the binary too. Can anybody guess what the terran BananaBrain will be called?
Adias is a new terran bot, and starting off strongly. The first thing I noticed about it is that its name is SAIDA spelled backward. Does that mean it is like SAIDA, or the opposite of SAIDA? The second thing I noticed, after unpacking the binary from SSCAIT, is a machine learning folder with files caffe2.dll, torch.dll, and a couple of learned models with the .pt suffix. It is the signature of a project using PyTorch for deep learning. It’s not TorchCraft, so not directly related to CherryPi. It also does not seem to be based on SAIDA_RL; strings I checked from SAIDA_RL do not appear in adias.
The third thing I noticed, peering into the .exe, is that it looks to be derived from SAIDA. It’s clear that the two share a lot of code, at least. That’s surprising; based on SAIDA and using RL but not based on SAIDA_RL? Close similarities to SAIDA are visible in the game play. For example, adias shares SAIDA’s way of grouping supply depots and tech buildings together, and SAIDA’s predilection for walls composed of barracks plus engineering bay. Both habits appear in the game adias-Tomas Cere on Benzene. There are a lot more similarities; the building placement and opening build orders look identical to me, and adias shares the skill to set up tank lines where the opponent will be compelled to engage at a disadvantage.
The combination of traits reminds me of something else: Stormbreaker, the bot which was disqualified from AIIDE 2019 for being SAIDA with cosmetic changes and a neural network whose result was not used. Is adias only Stormbreaker under a different name?
Well, I don’t know, but I’m guessing not. Though SAIDA and adias look more similar than not, I went back and watched old SAIDA games and I think I see differences too. The difference most salient to me is that adias likes to send an SCV to scout around inside and near its base early in the game, seeming to check for proxies. The only other bot I’ve seen with that style of anti-proxy scouting is tscmoo. Did tscmoo have a hand in adias?
I expect we’ll learn more as we get to see more games. Krasi0 was eventually updated to defeat SAIDA. Will Krasi0 quickly learn to beat adias too, or will Krasi0 have to be updated again to keep up?
Here’s data from Microwave’s history files, using the same script as for BananaBrain with a little customization. Unlike Microwave’s learning files, which deliberately omit data and include information from pre-learning, the history files tell what Microwave actually did during the games. Microwave didn’t record information about the opponent’s strategy, so that table is left out. That made it look a little sparse, so I added columns giving the first and last games when the opening was tried, where the first game in the history file is game 0. We can see things like when a winning opening was found, and whether it kept winning. If there are fewer than 100 games recorded for an opponent because Microwave crashed, then the game numbers generally do not align with the tournament round numbers.
Against difficult opponents, Microwave experimented widely. Against some opponents that Microwave pre-trained against, it played whatever came out of pre-training. So I don’t have much to say about opponents in the top half of the post. But toward the bottom I’ve made some comments. Especially see the note to AITP.
| opening | games | wins | first | last |
|---|---|---|---|---|
| 10Hatch9Pool9gas | 8 | 12% | 1 | 52 |
| 2HatchHydra | 7 | 0% | 0 | 53 |
| 2HatchLurker | 7 | 29% | 83 | 89 |
| 2HatchLurkerAllIn | 2 | 0% | 63 | 90 |
| 2HatchMuta | 12 | 25% | 3 | 56 |
| 3HatchHydraBust | 3 | 0% | 10 | 57 |
| 3HatchLingBust | 3 | 0% | 38 | 91 |
| 3HatchPoolHydra | 5 | 0% | 16 | 92 |
| 4HatchBeforeGas | 4 | 0% | 27 | 93 |
| 4PoolHard | 3 | 0% | 15 | 58 |
| 4PoolSoft | 4 | 0% | 21 | 59 |
| 5Pool | 2 | 0% | 36 | 60 |
| 5PoolSpeed | 3 | 0% | 41 | 94 |
| 6Pool | 3 | 0% | 42 | 95 |
| 6PoolSpeed | 3 | 0% | 43 | 96 |
| 7Pool | 2 | 0% | 37 | 61 |
| 8Pool | 3 | 0% | 44 | 97 |
| 9Pool | 9 | 22% | 45 | 78 |
| 9PoolLurker | 2 | 0% | 46 | 79 |
| 9PoolSpeed | 3 | 0% | 11 | 62 |
| 9PoolSpeedLing | 2 | 0% | 47 | 80 |
| ZvP_10Hatch9Pool | 4 | 0% | 17 | 81 |
| ZvZ_Overpool11Gas | 4 | 0% | 18 | 82 |
| 23 openings | 98 | 8% |
| opening | games | wins | first | last |
|---|---|---|---|---|
| 10Hatch9Pool9gas | 11 | 9% | 20 | 93 |
| 2HatchHydra | 6 | 0% | 14 | 87 |
| 2HatchMuta | 5 | 0% | 35 | 94 |
| 3HatchHydraBust | 9 | 0% | 3 | 95 |
| 3HatchLingBust | 14 | 7% | 0 | 74 |
| 4PoolHard | 1 | 0% | 80 | 80 |
| 4PoolSoft | 7 | 14% | 30 | 75 |
| 5Pool | 8 | 12% | 15 | 90 |
| 5PoolSpeed | 1 | 0% | 81 | 81 |
| 6Pool | 1 | 0% | 82 | 82 |
| 6PoolSpeed | 1 | 0% | 83 | 83 |
| 7Pool | 8 | 0% | 17 | 76 |
| 8Pool | 4 | 0% | 42 | 91 |
| 9Pool | 1 | 0% | 84 | 84 |
| 9PoolSpeed | 3 | 0% | 52 | 92 |
| 9PoolSpeedLing | 14 | 21% | 4 | 77 |
| ZvP_10Hatch9Pool | 1 | 0% | 85 | 85 |
| ZvZ_Overpool11Gas | 1 | 0% | 86 | 86 |
| 18 openings | 96 | 7% |
| opening | games | wins | first | last |
|---|---|---|---|---|
| 10Hatch9Pool9gas | 1 | 0% | 54 | 54 |
| 2HatchHydra | 1 | 0% | 51 | 51 |
| 2HatchMuta | 1 | 0% | 52 | 52 |
| 3HatchLingBust | 37 | 49% | 0 | 92 |
| 4PoolHard | 3 | 0% | 29 | 63 |
| 4PoolSoft | 4 | 0% | 28 | 67 |
| 5Pool | 11 | 45% | 22 | 76 |
| 5PoolSpeed | 7 | 29% | 19 | 78 |
| 6Pool | 1 | 0% | 62 | 62 |
| 6PoolSpeed | 5 | 20% | 20 | 68 |
| 7Pool | 1 | 0% | 55 | 55 |
| 8Pool | 3 | 0% | 24 | 69 |
| 9Pool | 7 | 43% | 56 | 70 |
| 9PoolSpeed | 1 | 0% | 53 | 53 |
| 9PoolSpeedLing | 3 | 0% | 25 | 71 |
| ZvZ_Overgas9Pool | 4 | 0% | 26 | 77 |
| ZvZ_Overpool11Gas | 3 | 0% | 35 | 79 |
| 17 openings | 93 | 31% |
| opening | games | wins | first | last |
|---|---|---|---|---|
| 10Hatch9Pool9gas | 11 | 18% | 2 | 77 |
| 2HatchHydra | 4 | 0% | 18 | 78 |
| 2HatchLurker | 4 | 0% | 23 | 79 |
| 2HatchMuta | 13 | 23% | 17 | 89 |
| 3HatchHydraBust | 3 | 0% | 20 | 51 |
| 3HatchLingBust | 31 | 39% | 16 | 76 |
| 3HatchPoolHydra | 3 | 0% | 25 | 52 |
| 4PoolSoft | 3 | 0% | 6 | 53 |
| 5Pool | 3 | 0% | 7 | 54 |
| 7Pool | 3 | 0% | 11 | 55 |
| 9Pool | 3 | 0% | 1 | 56 |
| 9PoolSpeed | 3 | 0% | 10 | 57 |
| 9PoolSpeedLing | 3 | 0% | 0 | 58 |
| ZvP_10Hatch9Pool | 3 | 0% | 5 | 59 |
| 14 openings | 90 | 19% |
| opening | games | wins | first | last |
|---|---|---|---|---|
| 9PoolSpeed | 100 | 75% | 0 | 99 |
| 1 openings | 100 | 75% |
| opening | games | wins | first | last |
|---|---|---|---|---|
| 9PoolHatch | 1 | 0% | 0 | 0 |
| ZvZ_Overgas11Pool | 70 | 80% | 1 | 70 |
| 2 openings | 71 | 79% |
Why are only 71 games recorded? According to the official results, Microwave crashed in 56 games throughout the tournament, and 29 of those crashes happened against ZZZKBot. Microwave recorded every game in which it did not crash. It’s a debugging opportunity. :-/
| opening | games | wins | first | last |
|---|---|---|---|---|
| 10Hatch9Pool9gas | 2 | 0% | 53 | 82 |
| 2HatchHydra | 1 | 0% | 83 | 83 |
| 2HatchLurkerAllIn | 2 | 0% | 63 | 88 |
| 2HatchMuta | 11 | 9% | 0 | 72 |
| 3HatchHydraBust | 15 | 33% | 5 | 77 |
| 3HatchHydraExpo | 1 | 0% | 84 | 84 |
| 3HatchPoolHydra | 1 | 0% | 85 | 85 |
| 4HatchBeforeGas | 4 | 0% | 18 | 89 |
| 4PoolHard | 6 | 0% | 13 | 78 |
| 4PoolSoft | 7 | 14% | 11 | 71 |
| 5Pool | 1 | 0% | 86 | 86 |
| 5PoolSpeed | 6 | 0% | 14 | 79 |
| 6Pool | 2 | 0% | 54 | 87 |
| 6PoolSpeed | 5 | 20% | 35 | 92 |
| 7Pool | 10 | 30% | 19 | 68 |
| 8Pool | 7 | 14% | 17 | 80 |
| 9Pool | 8 | 12% | 1 | 95 |
| 9PoolSpeedLing | 4 | 0% | 21 | 96 |
| OverpoolTurtle | 4 | 0% | 22 | 81 |
| 19 openings | 97 | 13% |
| opening | games | wins | first | last |
|---|---|---|---|---|
| 10Hatch9Pool9gas | 2 | 0% | 42 | 47 |
| 2HatchLurker | 1 | 0% | 48 | 48 |
| 2HatchMuta | 2 | 0% | 45 | 46 |
| 4PoolSoft | 38 | 63% | 1 | 38 |
| 5Pool | 2 | 50% | 0 | 39 |
| 7Pool | 51 | 76% | 49 | 99 |
| 9Pool | 2 | 50% | 40 | 41 |
| 9PoolSpeedLing | 2 | 0% | 43 | 44 |
| 8 openings | 100 | 65% |
As soon as Microwave found that 7 pool worked, it played 7 pool exclusively.
| opening | games | wins | first | last |
|---|---|---|---|---|
| 2HatchMuta | 40 | 62% | 0 | 79 |
| 3HatchHydraBust | 13 | 92% | 86 | 98 |
| 4PoolHard | 1 | 0% | 80 | 80 |
| 4PoolSoft | 40 | 62% | 1 | 40 |
| 9Pool | 1 | 0% | 85 | 85 |
| ZvZ_Overgas11Pool | 4 | 50% | 81 | 84 |
| 6 openings | 99 | 65% |
Microwave was late to discover the success of the hydra bust opening. That’s why it was played so little. The example shows the importance of finding good ideas as early as possible. I am adding smarts to Steamhammer to make it better at finding the good tries fast.
It’s interesting that 2HatchMuta and 4PoolSoft have the same numbers, but were given up on at different times.
| opening | games | wins | first | last |
|---|---|---|---|---|
| 4PoolSoft | 100 | 82% | 0 | 99 |
| 1 openings | 100 | 82% |
The choice against UAlbertaBot was determined by pre-training. From scratch, I expect Microwave would have tried a wider variety.
| opening | games | wins | first | last |
|---|---|---|---|---|
| 9PoolSpeedLing | 100 | 93% | 0 | 99 |
| 1 openings | 100 | 93% |
If the first try wins, keep it up. What if Microwave had an opening that would have won more than 93%? The theory is that, above some winning rate, the risk of losing by trying alternatives is higher than the risk of losing by sticking with a known good opening. But what winning rate is high enough to stick with? It depends on how much you respect your opponents. If you expect to win nearly every game, like Locutus, maybe you should switch to an alternative as soon as you lose a single game. If you expect to finish near the bottom, maybe you should stick with a strategy that wins 50%.
But more: How much do you respect each opponent? Maybe bots should have a “contempt factor” like chess programs may use to decide whether to aim for a draw: Accept a low winning rate strategy against Locutus, but demand 95% wins against the unknown who you’ve decided is a weak newbie. I would rather call it a respect factor! In a UCB algorithm, a level of respect is implicitly encoded in the exploration rate constant. Does any bot already have a respect factor for specific opponents?
| opening | games | wins | first | last |
|---|---|---|---|---|
| 5Pool | 100 | 99% | 0 | 99 |
| 1 openings | 100 | 99% |
Apparently the initial choice against an unknown is random.
I wrote a script to analyze BananaBrain’s game history files, which record its experience with each opponent. For now, I had the script summarize the strategies played and the enemy strategies recognized. The history files also record the map and a value that represents the game duration. History files are rich with information, and there are many ways to summarize it. It would be interesting to see how strategy usage and win rate vary by map, among other possibilities.
The same script should work with minor changes to summarize Microwave’s history files.
BananaBrain had prepared history files for the opponents #1 Locutus, #2 PurpleWave, #5 Steamhammer, #6 ZZZKBot, #7 Microwave, and #8 Iron. Data from the prepared history files was not copied into the write directory. That is different from how Steamhammer and Locutus keep their game records, and it has the nice effect that the tables show exactly what happened in the tournament, from BananaBrain’s point of view.
For each opponent, the left table is BananaBrain’s choice. The right table is BananaBrain’s idea of what the opponent did. All the win rates are from BananaBrain’s point of view, so that, for example, when Locutus played P_1gatecore, BananaBrain won 5% of the time. Of course, the opponent’s view of its own strategy is likely to be more fine-grained than BananaBrain’s. To take the extreme case, Steamhammer played 30 different openings against BananaBrain, and BananaBrain recognized them in 8 categories.
| opening | games | wins |
|---|---|---|
| PvP_10/12gate | 6 | 17% |
| PvP_12nexus | 11 | 36% |
| PvP_2gatedt | 10 | 0% |
| PvP_2gatedtexpo | 9 | 0% |
| PvP_3gaterobo | 5 | 0% |
| PvP_3gatespeedzeal | 8 | 25% |
| PvP_4gategoon | 6 | 0% |
| PvP_9/9gate | 12 | 8% |
| PvP_9/9proxygate | 9 | 0% |
| PvP_nzcore | 8 | 12% |
| PvP_zcore | 4 | 0% |
| PvP_zcorez | 6 | 0% |
| PvP_zzcore | 6 | 17% |
| 13 openings | 100 | 10% |
| enemy | games | wins |
|---|---|---|
| P_1gatecore | 20 | 5% |
| P_cannonrush | 29 | 7% |
| P_fastexpand | 1 | 0% |
| P_ffe | 19 | 21% |
| P_unknown | 31 | 10% |
| 5 openings | 100 | 10% |
As you might expect against Locutus, the best choice was a fast expansion.
Is the single game of enemy P_fastexpand a misrecognition? I suspect that Locutus played otherwise, and BananaBrain didn’t see everything and wasn’t able to draw the right conclusion. Or maybe it’s a bug somewhere. PurpleWave and McRave also show a single P_fastexpand game.
| opening | games | wins |
|---|---|---|
| PvP_10/12gate | 23 | 70% |
| PvP_12nexus | 2 | 0% |
| PvP_2gatedt | 6 | 17% |
| PvP_2gatedtexpo | 3 | 33% |
| PvP_3gaterobo | 2 | 0% |
| PvP_3gatespeedzeal | 1 | 0% |
| PvP_4gategoon | 8 | 38% |
| PvP_9/9gate | 26 | 88% |
| PvP_9/9proxygate | 13 | 62% |
| PvP_nzcore | 3 | 0% |
| PvP_zcore | 4 | 25% |
| PvP_zcorez | 5 | 40% |
| PvP_zzcore | 4 | 25% |
| 13 openings | 100 | 56% |
| enemy | games | wins |
|---|---|---|
| P_1gatecore | 54 | 56% |
| P_2gate | 25 | 60% |
| P_2gatefast | 6 | 33% |
| P_fastexpand | 1 | 0% |
| P_ffe | 2 | 50% |
| P_unknown | 12 | 67% |
| 6 openings | 100 | 56% |
Against PurpleWave, different zealot rushes worked best. Maybe it is because zealot rushes depend for their success more on execution than on the enemy’s strategic reaction. PurpleWave is particularly good at reacting to the enemy strategy, and BananaBrain is good at execution.
| opening | games | wins |
|---|---|---|
| PvP_10/12gate | 8 | 62% |
| PvP_12nexus | 6 | 33% |
| PvP_2gatedt | 6 | 17% |
| PvP_2gatedtexpo | 12 | 83% |
| PvP_3gaterobo | 7 | 14% |
| PvP_3gatespeedzeal | 6 | 33% |
| PvP_4gategoon | 5 | 0% |
| PvP_9/9gate | 14 | 93% |
| PvP_9/9proxygate | 9 | 67% |
| PvP_nzcore | 7 | 43% |
| PvP_zcore | 6 | 33% |
| PvP_zcorez | 7 | 43% |
| PvP_zzcore | 7 | 43% |
| 13 openings | 100 | 51% |
| enemy | games | wins |
|---|---|---|
| P_1gatecore | 82 | 50% |
| P_unknown | 18 | 56% |
| 2 openings | 100 | 51% |
BananaBrain made quite a variety of tries, and was most successful with... zealot rush and dark templars, which are kind of different. BananaBrain’s varied opening choice is a strength.
| opening | games | wins |
|---|---|---|
| PvZ_10/12gate | 15 | 100% |
| PvZ_1basespeedzeal | 8 | 88% |
| PvZ_2basespeedzeal | 11 | 82% |
| PvZ_4gate2archon | 7 | 57% |
| PvZ_5gategoon | 7 | 86% |
| PvZ_9/9gate | 12 | 92% |
| PvZ_9/9proxygate | 15 | 100% |
| PvZ_bisu | 4 | 75% |
| PvZ_neobisu | 2 | 50% |
| PvZ_sairdt | 7 | 100% |
| PvZ_sairgoon | 2 | 0% |
| PvZ_stove | 10 | 70% |
| 12 openings | 100 | 85% |
| enemy | games | wins |
|---|---|---|
| Z_10hatch | 38 | 76% |
| Z_12hatch | 31 | 84% |
| Z_12pool | 11 | 91% |
| Z_4/5pool | 3 | 100% |
| Z_9pool | 1 | 100% |
| Z_9poolspeed | 4 | 100% |
| Z_overpool | 2 | 100% |
| Z_unknown | 10 | 100% |
| 8 openings | 100 | 85% |
2 gate zealot openings work well against Steamhammer—but only when played by PurpleWave or BananaBrain. Steamhammer can usually defend versus a lesser protoss.
| opening | games | wins |
|---|---|---|
| PvZ_10/12gate | 17 | 100% |
| PvZ_1basespeedzeal | 11 | 91% |
| PvZ_2basespeedzeal | 4 | 25% |
| PvZ_4gate2archon | 4 | 50% |
| PvZ_5gategoon | 6 | 67% |
| PvZ_9/9gate | 15 | 100% |
| PvZ_9/9proxygate | 3 | 67% |
| PvZ_bisu | 5 | 60% |
| PvZ_neobisu | 4 | 25% |
| PvZ_sairdt | 12 | 100% |
| PvZ_sairgoon | 6 | 50% |
| PvZ_stove | 13 | 100% |
| 12 openings | 100 | 83% |
| enemy | games | wins |
|---|---|---|
| Z_4/5pool | 33 | 85% |
| Z_9pool | 17 | 100% |
| Z_9poolspeed | 2 | 100% |
| Z_overpool | 23 | 65% |
| Z_unknown | 25 | 84% |
| 5 openings | 100 | 83% |
I like that BananaBrain varies its opening choice even when several openings win 100%. (Steamhammer does too; if more than one opening has scored 100% so far, Steamhammer chooses randomly among them.) Playing a strong opening gives the opponent one problem to solve (“how do I survive this?”). Unpredictably playing one of several strong openings sets the opponent two problems (“what is this fiend doing, and then how do I live through it?”) which must both be solved, more than twice as difficult.
| opening | games | wins |
|---|---|---|
| PvZ_10/12gate | 20 | 90% |
| PvZ_1basespeedzeal | 11 | 73% |
| PvZ_2basespeedzeal | 3 | 33% |
| PvZ_4gate2archon | 6 | 50% |
| PvZ_5gategoon | 8 | 75% |
| PvZ_9/9gate | 17 | 88% |
| PvZ_9/9proxygate | 8 | 75% |
| PvZ_bisu | 10 | 60% |
| PvZ_neobisu | 3 | 33% |
| PvZ_sairdt | 4 | 50% |
| PvZ_sairgoon | 2 | 0% |
| PvZ_stove | 8 | 62% |
| 12 openings | 100 | 71% |
| enemy | games | wins |
|---|---|---|
| Z_10hatch | 8 | 88% |
| Z_12hatch | 38 | 55% |
| Z_12pool | 2 | 100% |
| Z_4/5pool | 28 | 71% |
| Z_9pool | 9 | 67% |
| Z_9poolspeed | 7 | 100% |
| Z_overpool | 3 | 100% |
| Z_unknown | 5 | 100% |
| 8 openings | 100 | 71% |
| opening | games | wins |
|---|---|---|
| PvT_10/12gate | 6 | 67% |
| PvT_10/15gate | 3 | 0% |
| PvT_12nexus | 4 | 25% |
| PvT_1gatedtexpo | 25 | 84% |
| PvT_2gatedt | 10 | 60% |
| PvT_9/9gate | 10 | 60% |
| PvT_9/9proxygate | 4 | 75% |
| PvT_bulldog | 1 | 0% |
| PvT_dtdrop | 14 | 64% |
| PvT_nzcore | 5 | 40% |
| PvT_proxydt | 2 | 0% |
| PvT_stove | 4 | 25% |
| PvT_zcore | 5 | 40% |
| PvT_zzcore | 7 | 43% |
| 14 openings | 100 | 58% |
| enemy | games | wins |
|---|---|---|
| T_1fac | 30 | 63% |
| T_2fac | 1 | 0% |
| T_fastexpand | 29 | 48% |
| T_unknown | 40 | 62% |
| 4 openings | 100 | 58% |
Bulldog! That involves protoss dropping zealots, typically on cliff tanks, with a simultaneous attack by ground. When successful, a bulldog can abruptly break a terran defense that is sound against any purely ground attack. I don’t think I’ve seen BananaBrain play that; I should watch more games versus terran. Can anybody point out an example?
| opening | games | wins |
|---|---|---|
| PvT_10/12gate | 10 | 90% |
| PvT_10/15gate | 7 | 43% |
| PvT_12nexus | 5 | 20% |
| PvT_1gatedtexpo | 11 | 100% |
| PvT_2gatedt | 7 | 57% |
| PvT_9/9gate | 6 | 33% |
| PvT_9/9proxygate | 6 | 17% |
| PvT_bulldog | 5 | 0% |
| PvT_dtdrop | 9 | 89% |
| PvT_nzcore | 6 | 17% |
| PvT_proxydt | 7 | 71% |
| PvT_stove | 8 | 75% |
| PvT_zcore | 6 | 33% |
| PvT_zzcore | 7 | 57% |
| 14 openings | 100 | 57% |
| enemy | games | wins |
|---|---|---|
| T_1fac | 37 | 57% |
| T_fastexpand | 20 | 65% |
| T_unknown | 43 | 53% |
| 3 openings | 100 | 57% |
The Stove worked against XiaoYi? Again, XiaoYi shows weakness against tricks. The Stove involves making scouts to harass while teching to dark templar. It should not be hard for a good terran to defend against; notice that Iron dealt with it well enough.
| opening | games | wins |
|---|---|---|
| PvP_10/12gate | 7 | 71% |
| PvP_12nexus | 6 | 50% |
| PvP_2gatedt | 6 | 67% |
| PvP_2gatedtexpo | 8 | 50% |
| PvP_3gaterobo | 9 | 78% |
| PvP_3gatespeedzeal | 8 | 62% |
| PvP_4gategoon | 7 | 57% |
| PvP_9/9gate | 8 | 75% |
| PvP_9/9proxygate | 6 | 33% |
| PvP_nzcore | 10 | 90% |
| PvP_zcore | 7 | 57% |
| PvP_zcorez | 10 | 90% |
| PvP_zzcore | 8 | 88% |
| 13 openings | 100 | 69% |
| enemy | games | wins |
|---|---|---|
| P_1gatecore | 34 | 74% |
| P_2gate | 26 | 65% |
| P_2gatefast | 29 | 69% |
| P_fastexpand | 1 | 0% |
| P_proxygate | 4 | 100% |
| P_unknown | 6 | 50% |
| 6 openings | 100 | 69% |
It looks like most openings performed similarly against McRave, and BananaBrain struggled to identify what worked. I imagine a fierce learning battle, both trying to keep one step ahead.
| opening | games | wins |
|---|---|---|
| PvU_10/12gate | 17 | 94% |
| PvU_9/9gate | 17 | 100% |
| PvU_9/9proxygate | 13 | 85% |
| PvU_flex | 12 | 67% |
| PvU_nzcore | 11 | 64% |
| PvU_zcore | 16 | 88% |
| PvU_zzcore | 13 | 77% |
| 7 openings | 99 | 84% |
| enemy | games | wins |
|---|---|---|
| P_1gatecore | 8 | 100% |
| P_2gate | 6 | 83% |
| P_2gatefast | 21 | 71% |
| P_unknown | 3 | 33% |
| T_1fac | 5 | 100% |
| T_2fac | 7 | 100% |
| T_2rax | 10 | 90% |
| T_fastexpand | 3 | 100% |
| T_unknown | 5 | 100% |
| Z_10hatch | 2 | 100% |
| Z_12hatch | 8 | 100% |
| Z_4/5pool | 17 | 71% |
| Z_unknown | 4 | 75% |
| 13 openings | 99 | 84% |
| opening | games | wins |
|---|---|---|
| PvT_10/12gate | 7 | 100% |
| PvT_10/15gate | 8 | 100% |
| PvT_12nexus | 6 | 100% |
| PvT_1gatedtexpo | 8 | 100% |
| PvT_2gatedt | 7 | 100% |
| PvT_9/9gate | 6 | 100% |
| PvT_9/9proxygate | 7 | 100% |
| PvT_bulldog | 9 | 100% |
| PvT_dtdrop | 7 | 100% |
| PvT_nzcore | 7 | 100% |
| PvT_proxydt | 7 | 100% |
| PvT_stove | 9 | 100% |
| PvT_zcore | 6 | 100% |
| PvT_zzcore | 6 | 100% |
| 14 openings | 100 | 100% |
| enemy | games | wins |
|---|---|---|
| T_1fac | 4 | 100% |
| T_2fac | 12 | 100% |
| T_fastexpand | 24 | 100% |
| T_unknown | 60 | 100% |
| 4 openings | 100 | 100% |
| opening | games | wins |
|---|---|---|
| PvT_10/12gate | 7 | 100% |
| PvT_10/15gate | 7 | 100% |
| PvT_12nexus | 7 | 100% |
| PvT_1gatedtexpo | 7 | 100% |
| PvT_2gatedt | 7 | 100% |
| PvT_9/9gate | 6 | 100% |
| PvT_9/9proxygate | 7 | 100% |
| PvT_bulldog | 8 | 100% |
| PvT_dtdrop | 7 | 100% |
| PvT_nzcore | 6 | 100% |
| PvT_proxydt | 8 | 100% |
| PvT_stove | 8 | 100% |
| PvT_zcore | 7 | 100% |
| PvT_zzcore | 8 | 100% |
| 14 openings | 100 | 100% |
| enemy | games | wins |
|---|---|---|
| T_unknown | 100 | 100% |
| 1 openings | 100 | 100% |
BananaBrain apparently does not have a bunker rush recognizer.
Locutus’s game records are in almost the same format as Steamhammer’s and can be summarized by the same script. I expect it will also work for DaQin and AITP.
Where Steamhammer was set to keep 100 game records per opponent, Locutus was set to keep 200. Since there were 100 rounds in the tournament, game counts over 100 mean that pre-learned data is included in the table alongside the tournament data. If Locutus was not trained on a near-final version of the opponent, then the two could be significantly different.
| opening | games | wins |
|---|---|---|
| 4GateGoon | 28 | 54% |
| 4GateGoonWithObs | 16 | 62% |
| FakeDTRush | 10 | 20% |
| ForgeExpand | 19 | 63% |
| ZealotDrop | 127 | 73% |
| 5 openings | 200 | 66% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Dark templar | 20 | 10% | 50% | 30 | 15% | 37% | 45% | 0% |
| Fast rush | 3 | 2% | 100% | 5 | 2% | 80% | 0% | 0% |
| Heavy rush | 6 | 3% | 17% | 12 | 6% | 67% | 0% | 0% |
| Not fast rush | 171 | 86% | 69% | 153 | 76% | 71% | 81% | 0% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 92 | 1:44 | 0:44 | 2:01 |
| gas steal success | 15 | - | - | - |
| enemy scout | 186 | 2:27 | 1:09 | 16:11 |
| enemy combat units | 198 | 3:29 | 2:19 | 7:26 |
| enemy air units | 55 | 6:50 | 4:50 | 20:31 |
| enemy cloaked units | 93 | 11:07 | 5:13 | 19:54 |
After seeing a few Locutus-PurpleWave games I got the impression that PurpleWave reacted adequately to Locutus’s trick strategy of cannoning the ramp and then dropping zealots. So I was surprised that Locutus considered it the best choice. But the overall win rate is high compared to the tournament results, so I suspect it is influenced by pre-learned data from games against a weaker version of PurpleWave.
| opening | games | wins |
|---|---|---|
| 4GateGoon | 12 | 83% |
| ForgeExpand | 37 | 84% |
| ZealotDrop | 151 | 95% |
| 3 openings | 200 | 92% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Dark templar | 5 | 2% | 80% | 28 | 14% | 100% | 40% | 0% |
| Fast rush | 6 | 3% | 100% | 12 | 6% | 83% | 0% | 0% |
| Heavy rush | 1 | 0% | 100% | 19 | 10% | 89% | 0% | 0% |
| Not fast rush | 188 | 94% | 92% | 141 | 70% | 91% | 70% | 0% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 59 | 1:45 | 0:46 | 1:52 |
| gas steal success | 6 | - | - | - |
| enemy scout | 196 | 1:57 | 0:46 | 10:09 |
| enemy combat units | 200 | 3:30 | 2:18 | 7:25 |
| enemy air units | 20 | 15:41 | 13:05 | 17:35 |
| enemy cloaked units | 31 | 6:13 | 5:46 | 16:11 |
| opening | games | wins |
|---|---|---|
| 4GateGoon | 11 | 64% |
| FakeDTRush | 1 | 0% |
| ForgeExpand | 1 | 0% |
| ZealotDrop | 87 | 87% |
| 4 openings | 100 | 83% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Dark templar | 9 | 9% | 89% | 21 | 21% | 76% | 11% | 0% |
| Fast rush | 2 | 2% | 100% | 3 | 3% | 67% | 0% | 0% |
| Not fast rush | 88 | 88% | 82% | 76 | 76% | 86% | 74% | 0% |
| Unknown | 1 | 1% | 100% | - | - | 0% | 0% | |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 26 | 1:45 | 0:45 | 1:49 |
| gas steal success | 4 | - | - | - |
| enemy scout | 97 | 3:02 | 2:15 | 18:05 |
| enemy combat units | 100 | 3:31 | 2:19 | 5:22 |
| enemy air units | 2 | 17:47 | 16:23 | 19:10 |
| enemy cloaked units | 91 | 7:18 | 6:02 | 9:17 |
| opening | games | wins |
|---|---|---|
| 4GateGoon | 7 | 100% |
| 9-9GateDefensive | 5 | 100% |
| CannonFirst4GateGoon | 11 | 100% |
| ForgeExpand4Gate2Archon | 11 | 73% |
| ForgeExpand5GateGoon | 155 | 95% |
| ForgeExpandSpeedlots | 1 | 100% |
| PlasmaCorsairsCarriers | 9 | 100% |
| ProxyHeavyZealotRush2 | 1 | 0% |
| 8 openings | 200 | 94% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Fast rush | 14 | 7% | 100% | 26 | 13% | 96% | 57% | 0% |
| Heavy rush | 26 | 13% | 81% | 59 | 30% | 92% | 38% | 0% |
| Hydra bust | 4 | 2% | 100% | 23 | 12% | 87% | 50% | 0% |
| Not fast rush | 156 | 78% | 96% | 92 | 46% | 98% | 53% | 0% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 0 | - | - | - |
| gas steal success | 0 | - | - | - |
| enemy scout | 188 | 2:21 | 0:51 | 18:45 |
| enemy combat units | 199 | 3:10 | 2:02 | 7:11 |
| enemy air units | 12 | 5:40 | 5:01 | 6:14 |
| enemy cloaked units | 7 | 10:02 | 5:15 | 19:39 |
The numbers in the “recognized” columns of the plan table show how widely Steamhammer cast its net for a solution to Locutus.
Locutus never tried to steal the gas of a zerg. Objectively, that makes sense. In the context of bot play, I’m not so sure; many bots of all races mess up their builds in the face of a gas steal.
| opening | games | wins |
|---|---|---|
| 9-9GateDefensive | 4 | 100% |
| CannonAtChokeFirst4GateGoon | 13 | 54% |
| CannonFirst4GateGoon | 178 | 99% |
| PlasmaCorsairsCarriers | 1 | 100% |
| PlasmaProxy2Gate | 4 | 100% |
| 5 openings | 200 | 96% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Fast rush | 115 | 57% | 97% | 107 | 54% | 94% | 73% | 0% |
| Heavy rush | 78 | 39% | 96% | 66 | 33% | 100% | 54% | 0% |
| Hydra bust | 1 | 0% | 100% | 2 | 1% | 100% | 100% | 0% |
| Not fast rush | 6 | 3% | 100% | 25 | 12% | 96% | 17% | 0% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 0 | - | - | - |
| gas steal success | 0 | - | - | - |
| enemy scout | 200 | 2:25 | 0:51 | 5:58 |
| enemy combat units | 196 | 2:28 | 2:03 | 7:59 |
| enemy air units | 52 | 7:53 | 5:26 | 13:43 |
| enemy cloaked units | 0 | - | - | - |
| opening | games | wins |
|---|---|---|
| 9-9GateDefensive | 2 | 100% |
| ForgeExpand4Gate2Archon | 3 | 67% |
| ForgeExpand5GateGoon | 146 | 99% |
| ForgeExpandSpeedlots | 44 | 80% |
| PlasmaCorsairsCarriers | 2 | 100% |
| PlasmaProxy2Gate | 3 | 100% |
| 6 openings | 200 | 94% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Fast rush | 50 | 25% | 82% | 41 | 20% | 98% | 32% | 0% |
| Heavy rush | 34 | 17% | 100% | 50 | 25% | 90% | 47% | 0% |
| Hydra bust | - | - | 17 | 8% | 100% | 0% | 0% | |
| Not fast rush | 115 | 57% | 98% | 91 | 46% | 95% | 57% | 0% |
| Proxy | 1 | 0% | 100% | 1 | 0% | 100% | 0% | 0% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 0 | - | - | - |
| gas steal success | 0 | - | - | - |
| enemy scout | 195 | 2:30 | 1:07 | 21:14 |
| enemy combat units | 198 | 3:03 | 1:47 | 7:59 |
| enemy air units | 69 | 11:19 | 5:49 | 24:25 |
| enemy cloaked units | 32 | 6:37 | 5:21 | 13:49 |
| opening | games | wins |
|---|---|---|
| CautiousDTDrop | 200 | 98% |
| 1 openings | 200 | 98% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Not fast rush | 13 | 6% | 100% | 61 | 30% | 100% | 46% | 0% |
| Wall-in | 187 | 94% | 98% | 139 | 70% | 97% | 71% | 0% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 35 | 0:46 | 0:45 | 0:48 |
| gas steal success | 11 | - | - | - |
| enemy scout | 190 | 2:45 | 1:42 | 10:46 |
| enemy combat units | 200 | 4:07 | 2:34 | 6:39 |
| enemy air units | 117 | 8:18 | 6:55 | 13:39 |
| enemy cloaked units | 117 | 8:18 | 6:55 | 13:39 |
Locutus declared an enemy-specific strategy against Iron. I’m not sure why it also had pre-learned data.
| opening | games | wins |
|---|---|---|
| 10-15GateGoon | 1 | 0% |
| 10Gate25NexusFE | 2 | 50% |
| DTDrop | 1 | 0% |
| ForgeExpand | 1 | 0% |
| Proxy2ZealotsIntoGoons | 30 | 93% |
| ProxyDTRush | 165 | 95% |
| 6 openings | 200 | 93% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Not fast rush | 200 | 100% | 93% | 200 | 100% | 93% | 100% | 0% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 68 | 1:17 | 1:12 | 1:50 |
| gas steal success | 12 | - | - | - |
| enemy scout | 194 | 3:01 | 2:11 | 15:29 |
| enemy combat units | 200 | 4:20 | 2:29 | 6:57 |
| enemy air units | 13 | 12:59 | 7:54 | 15:10 |
| enemy cloaked units | 4 | 8:00 | 7:54 | 8:18 |
Proxy DT rush. That tends to confirm my picture of XiaoYi as vulnerable to tricks.
| opening | games | wins |
|---|---|---|
| 4GateGoon | 5 | 80% |
| 4GateGoonWithObs | 3 | 100% |
| FakeDTRush | 1 | 0% |
| ForgeExpand | 2 | 50% |
| ZealotDrop | 189 | 94% |
| 5 openings | 200 | 93% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Dark templar | 3 | 2% | 100% | 16 | 8% | 94% | 67% | 0% |
| Fast rush | 3 | 2% | 100% | 18 | 9% | 100% | 0% | 0% |
| Heavy rush | 2 | 1% | 50% | 5 | 2% | 100% | 0% | 0% |
| Not fast rush | 192 | 96% | 93% | 161 | 80% | 92% | 82% | 0% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 99 | 1:46 | 0:45 | 1:57 |
| gas steal success | 2 | - | - | - |
| enemy scout | 193 | 2:09 | 1:21 | 14:38 |
| enemy combat units | 200 | 3:35 | 2:21 | 7:26 |
| enemy air units | 24 | 11:44 | 7:19 | 20:31 |
| enemy cloaked units | 60 | 11:03 | 5:15 | 14:25 |
| opening | games | wins |
|---|---|---|
| CannonFirst4GateGoon | 188 | 99% |
| PlasmaProxy2Gate | 10 | 100% |
| Proxy9-9Gate | 2 | 0% |
| 3 openings | 200 | 98% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Dark templar | 1 | 0% | 100% | 11 | 6% | 100% | 0% | 0% |
| Fast rush | 23 | 12% | 100% | 29 | 14% | 93% | 22% | 0% |
| Heavy rush | 48 | 24% | 96% | 63 | 32% | 100% | 29% | 0% |
| Not fast rush | 128 | 64% | 99% | 97 | 48% | 99% | 51% | 0% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 95 | 2:00 | 1:57 | 2:03 |
| gas steal success | 0 | - | - | - |
| enemy scout | 127 | 2:11 | 1:18 | 5:45 |
| enemy combat units | 135 | 3:22 | 2:01 | 6:54 |
| enemy air units | 7 | 6:45 | 6:41 | 6:53 |
| enemy cloaked units | 11 | 4:34 | 4:30 | 5:13 |
Locutus configured an enemy-specific strategy against UAlbertaBot. Openings other than CannonFirst4GateGoon are from pre-learned data, which was ignored in making the opening decision.
| opening | games | wins |
|---|---|---|
| DTDrop | 66 | 100% |
| ForgeExpand | 33 | 97% |
| Turtle | 1 | 100% |
| 3 openings | 100 | 99% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Fast rush | 2 | 2% | 100% | 7 | 7% | 100% | 0% | 0% |
| Heavy rush | 1 | 1% | 100% | 1 | 1% | 100% | 0% | 0% |
| Not fast rush | 77 | 77% | 99% | 62 | 62% | 100% | 62% | 0% |
| Unknown | 1 | 1% | 100% | - | - | 0% | 0% | |
| Wall-in | 19 | 19% | 100% | 30 | 30% | 97% | 42% | 0% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 43 | 0:46 | 0:45 | 1:27 |
| gas steal success | 15 | - | - | - |
| enemy scout | 26 | 3:19 | 2:41 | 6:02 |
| enemy combat units | 100 | 3:48 | 2:01 | 7:49 |
| enemy air units | 0 | - | - | - |
| enemy cloaked units | 0 | - | - | - |
| opening | games | wins |
|---|---|---|
| 10Gate25NexusFE | 21 | 95% |
| CannonFirst4GateGoon | 88 | 100% |
| ForgeExpand | 79 | 100% |
| PlasmaProxy2Gate | 10 | 100% |
| Proxy9-9Gate | 2 | 0% |
| 5 openings | 200 | 98% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Fast rush | 17 | 8% | 100% | 20 | 10% | 90% | 24% | 0% |
| Heavy rush | 36 | 18% | 94% | 35 | 18% | 100% | 31% | 0% |
| Not fast rush | 147 | 74% | 99% | 144 | 72% | 99% | 83% | 1% |
| Unknown | - | - | 1 | 0% | 100% | 0% | 0% | |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 87 | 1:29 | 0:45 | 2:03 |
| gas steal success | 16 | - | - | - |
| enemy scout | 104 | 2:07 | 1:27 | 3:18 |
| enemy combat units | 113 | 2:26 | 2:01 | 8:14 |
| enemy air units | 0 | - | - | - |
| enemy cloaked units | 0 | - | - | - |
| total | PvT | PvP | PvZ | PvR | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| opening | games | wins | games | wins | games | wins | games | wins | games | wins |
| 10-15GateGoon | 1 | 0% | 1 | 0% | ||||||
| 10Gate25NexusFE | 23 | 91% | 23 | 91% | ||||||
| 4GateGoon | 63 | 68% | 56 | 64% | 7 | 100% | ||||
| 4GateGoonWithObs | 19 | 68% | 19 | 68% | ||||||
| 9-9GateDefensive | 11 | 100% | 11 | 100% | ||||||
| CannonAtChokeFirst4GateGoon | 13 | 54% | 13 | 54% | ||||||
| CannonFirst4GateGoon | 465 | 100% | 189 | 99% | 276 | 100% | ||||
| CautiousDTDrop | 200 | 98% | 200 | 98% | ||||||
| DTDrop | 67 | 99% | 67 | 99% | ||||||
| FakeDTRush | 12 | 17% | 12 | 17% | ||||||
| ForgeExpand | 172 | 90% | 113 | 98% | 59 | 75% | ||||
| ForgeExpand4Gate2Archon | 14 | 71% | 14 | 71% | ||||||
| ForgeExpand5GateGoon | 301 | 97% | 301 | 97% | ||||||
| ForgeExpandSpeedlots | 45 | 80% | 45 | 80% | ||||||
| PlasmaCorsairsCarriers | 12 | 100% | 12 | 100% | ||||||
| PlasmaProxy2Gate | 27 | 100% | 7 | 100% | 20 | 100% | ||||
| Proxy2ZealotsIntoGoons | 30 | 93% | 30 | 93% | ||||||
| Proxy9-9Gate | 4 | 0% | 4 | 0% | ||||||
| ProxyDTRush | 165 | 95% | 165 | 95% | ||||||
| ProxyHeavyZealotRush2 | 1 | 0% | 1 | 0% | ||||||
| Turtle | 1 | 100% | 1 | 100% | ||||||
| ZealotDrop | 554 | 88% | 554 | 88% | ||||||
| total | 2200 | 92% | 600 | 97% | 700 | 84% | 600 | 95% | 300 | 98% |
| openings played | 22 | 8 | 5 | 10 | 3 | |||||
Today is Steamhammer. With a mid-rank finish and the widest range of builds, plus informative game records, Steamhammer may give us the best insight into how other bots played.
The tournament was 100 rounds, and Steamhammer was configured to remember the previous 100 game records, because in play there is no reason to remember more (earlier records are increasingly discounted). Steamhammer also had pre-learned game records for many opponents, so when the game record count reached 100, new records added caused old pre-learned records to drop away. Not all 100 tournament games happened for each opponent, but the pre-learned games filled in the small gaps so that Steamhammer ended up with exactly 100 game records per opponent in every case.
The “opening” table counts Steamhammer’s opening choices. The “plan” table shows the plan that Steamhammer first predicted that the opponent would play, then recognized that the opponent was playing. Both prediction and recognition can be wrong. The timing table is new this year, an attempt to get a little more information out of Steamhammer’s rich game records. For some events, it gives the count of games in which the event occurred, and the median time, earliest time, and latest time it occurred in those games when it did. The times are given under the assumption that 1 second of game time is exactly 24 frames, a simplification.
• gas steal attempt - When Steamhammer sent out the drone to steal gas (if it did).
• gas steal success - Whether the gas steal attempt succeeded in taking the opponent’s gas. Steamhammer doesn’t record the time it happens, so this is only a success count.
• enemy scout - When the enemy scout first reached Streamhammer’s base.
• enemy combat units - When the first enemy combat unit was seen.
• enemy air units - When the enemy is first known to have tech for flying units (except overlords).
• enemy cloaked units - When the enemy is first known to have tech for cloaked units.
| opening | games | wins |
|---|---|---|
| 11Gas10PoolMuta | 1 | 0% |
| 12Hatch12Pool | 1 | 0% |
| 2.5HatchMuta | 2 | 0% |
| 2HatchHydra | 1 | 0% |
| 2HatchHydraBust | 4 | 0% |
| 2HatchLingAllInSpire | 1 | 0% |
| 3HatchHydraBust | 5 | 0% |
| 3HatchHydraExpo | 1 | 0% |
| 3HatchLateHydras+1 | 5 | 0% |
| 3HatchLingBust2 | 3 | 0% |
| 4HatchBeforeGas | 1 | 0% |
| 4HatchBeforeLair | 5 | 0% |
| 5HatchBeforeGas | 2 | 0% |
| 5PoolHard2Player | 2 | 0% |
| 5Scout | 1 | 0% |
| 7PoolSoft | 1 | 0% |
| 8-8HydraRush | 1 | 0% |
| 8Hatch7Pool | 1 | 0% |
| 8Pool | 1 | 0% |
| 9Pool | 2 | 0% |
| 9PoolHatch | 2 | 0% |
| 9PoolSpeedAllIn | 1 | 0% |
| AntiFact_Overpool9Gas | 1 | 0% |
| DefilerRush | 2 | 0% |
| Over10Hatch2Sunk | 1 | 0% |
| Over10HatchSlowLings | 1 | 0% |
| Over10PoolMuta | 1 | 0% |
| OverhatchExpoLing | 2 | 0% |
| OverhatchExpoMuta | 2 | 0% |
| Overpool2HatchLurker | 1 | 0% |
| OverpoolHatch | 1 | 0% |
| OverpoolHydra | 12 | 0% |
| OverpoolSpeed | 4 | 0% |
| OverpoolSunk | 1 | 0% |
| Overpool_4HatchLing | 2 | 0% |
| PurpleSwarmBuild | 1 | 0% |
| Sparkle 1HatchMuta | 1 | 0% |
| Sparkle 2HatchMuta | 1 | 0% |
| ZvP_3BaseSpire+Den | 1 | 0% |
| ZvP_3HatchPoolHydra | 2 | 0% |
| ZvP_4HatchPoolHydra | 14 | 21% |
| ZvT_12PoolMuta | 2 | 0% |
| ZvZ_12PoolLing | 1 | 0% |
| ZvZ_12PoolLingB | 1 | 0% |
| ZvZ_Overpool9Gas | 1 | 0% |
| 45 openings | 100 | 3% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Heavy rush | - | - | 4 | 4% | 0% | 0% | 0% | |
| Safe expand | 56 | 56% | 2% | 44 | 44% | 5% | 43% | 5% |
| Turtle | 44 | 44% | 5% | 45 | 45% | 2% | 43% | 9% |
| Unknown | - | - | 7 | 7% | 0% | 0% | 0% | |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 43 | 1:29 | 0:00 | 2:34 |
| gas steal success | 23 | - | - | - |
| enemy scout | 100 | 1:35 | 1:11 | 6:51 |
| enemy combat units | 100 | 5:23 | 4:10 | 7:58 |
| enemy air units | 7 | 12:05 | 7:39 | 21:34 |
| enemy cloaked units | 8 | 11:24 | 4:39 | 21:34 |
It looks like Locutus opened forge-expand every game. It worked. Steamhammer desperately tried everything, including ZvZ builds and island builds, and finally squeezed 3 wins with a risky extreme macro opening, 4 hatcheries before spawning pool, which was able to win one game in five. I should add 5 and 6 hatch before pool and see if they help.
Locutus rarely made corsairs or dark templar. I wonder what its criteria are? Maybe it won before it got that far. The scout was usually quite early, and the first combat unit was seen late, as expected for a cannon-first opener.
I played over the 3 wins. They were in rounds 65, 70, and 73; after that, I expect that Locutus found a way to win. In 2 games, Steamhammer pulled ahead in early economy with its greedy opening, then struggled to defend and fell into a losing position. But Locutus got most of its units stuck in its base, and Steamhammer was able to turn it around and win after a hard fight with critical defiler support. In the third win, Locutus chose a zealot-archon unit mix that Steamhammer knows how to cope with, and zerg powered through.
| opening | games | wins |
|---|---|---|
| 10Pool9Gas | 1 | 0% |
| 11HatchTurtleHydra | 50 | 44% |
| 11HatchTurtleLurker | 1 | 0% |
| 11HatchTurtleMuta | 15 | 20% |
| 12Hatch_4HatchLing | 1 | 0% |
| 2HatchLingAllInSpire | 1 | 0% |
| 3HatchHydraExpo | 1 | 0% |
| 3HatchLing | 1 | 0% |
| 3HatchLingExpo | 1 | 0% |
| 4HatchBeforeLair | 1 | 0% |
| 5PoolSoft | 1 | 0% |
| 7Pool12Hatch | 1 | 0% |
| 9PoolBurrow | 1 | 0% |
| AntiZeal_12Hatch | 1 | 0% |
| HiveRush | 1 | 0% |
| Over10Hatch | 2 | 0% |
| Over10Hatch1Sunk | 3 | 0% |
| Over10Hatch2Sunk | 1 | 0% |
| OverhatchLateGas | 1 | 0% |
| Overpool+1 | 1 | 0% |
| OverpoolSpeed | 1 | 0% |
| OverpoolTurtle | 2 | 0% |
| ZvP_3HatchPoolHydra | 1 | 0% |
| ZvT_7Pool | 1 | 0% |
| ZvZ_Overpool9Gas | 9 | 33% |
| 25 openings | 100 | 28% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Fast rush | - | - | 2 | 2% | 0% | 0% | 0% | |
| Heavy rush | 99 | 99% | 28% | 90 | 90% | 24% | 90% | 4% |
| Safe expand | - | - | 3 | 3% | 100% | 0% | 0% | |
| Turtle | - | - | 1 | 1% | 100% | 0% | 0% | |
| Unknown | 1 | 1% | 0% | 4 | 4% | 50% | 0% | 0% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 41 | 1:13 | 1:09 | 2:36 |
| gas steal success | 37 | - | - | - |
| enemy scout | 98 | 2:13 | 1:19 | 15:06 |
| enemy combat units | 99 | 2:35 | 2:15 | 5:59 |
| enemy air units | 51 | 13:57 | 5:15 | 20:37 |
| enemy cloaked units | 48 | 14:01 | 6:02 | 17:11 |
PurpleWave in contrast went with mostly 2 gate openings against Steamhammer; that’s what “heavy rush” means for protoss. Steamhammer countered with early sunkens plus hydras or, less successfully, mutalisks (this version had a bug that weakened mutalisk play). There are also 3 wins with a ZvZ fast mutalisk opening. 2 gates should beat that, so protoss either played poorly or chose a different build in those games.
| opening | games | wins |
|---|---|---|
| 10HatchHydra | 1 | 0% |
| 11Gas10PoolLurker | 2 | 0% |
| 11Gas10PoolMuta | 10 | 10% |
| 11HatchTurtleHydra | 1 | 0% |
| 12Hatch_4HatchLing | 1 | 0% |
| 2.5HatchMuta | 1 | 0% |
| 2HatchLingAllInSpire | 1 | 0% |
| 3HatchHydra | 2 | 0% |
| 3HatchHydraBust | 1 | 0% |
| 3HatchHydraExpo | 1 | 0% |
| 3HatchLateHydras | 1 | 0% |
| 3HatchLingExpo | 9 | 11% |
| 5PoolHard | 1 | 0% |
| 6Pool | 1 | 0% |
| 6PoolSpeed | 1 | 0% |
| 7-7HydraLingRush | 1 | 0% |
| 8Gas7PoolLurker B | 1 | 0% |
| 9HatchMain9Pool9Gas | 1 | 0% |
| 9PoolBurrow | 1 | 0% |
| 9PoolSpeed | 1 | 0% |
| 9PoolSpire | 1 | 0% |
| AntiFact_2Hatch | 15 | 40% |
| AntiFact_Overpool9Gas | 1 | 0% |
| AntiZeal_12Hatch | 10 | 0% |
| Over10Hatch1Sunk | 1 | 0% |
| Over10HatchBust | 28 | 25% |
| OverpoolSpeed | 1 | 0% |
| OverpoolTurtle 0 | 1 | 0% |
| ZvP_Overpool3Hatch | 2 | 0% |
| ZvT_3HatchMuta | 1 | 0% |
| 30 openings | 100 | 15% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Heavy rush | 70 | 70% | 14% | 32 | 32% | 3% | 33% | 39% |
| Naked expand | 2 | 2% | 0% | 1 | 1% | 100% | 0% | 50% |
| Proxy | - | - | 4 | 4% | 0% | 0% | 0% | |
| Safe expand | 23 | 23% | 17% | 16 | 16% | 31% | 17% | 35% |
| Turtle | 5 | 5% | 20% | 10 | 10% | 20% | 0% | 20% |
| Unknown | - | - | 37 | 37% | 16% | 0% | 0% | |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 50 | 1:26 | 1:09 | 1:38 |
| gas steal success | 31 | - | - | - |
| enemy scout | 100 | 1:56 | 1:21 | 3:17 |
| enemy combat units | 100 | 2:56 | 2:19 | 8:19 |
| enemy air units | 83 | 5:19 | 2:51 | 11:41 |
| enemy cloaked units | 61 | 6:26 | 3:27 | 14:05 |
BananaBrain contrasts with both previous opponents in that it played a variety of builds. Steamhammer was unable to predict what was coming. It looks strange that the best reaction was an opening designed to counter terran factory-first builds that include a vulture runby, but in fact it is a mildly specialized 2 hatch mutalisk variant and not so surprising. BananaBrain made corsairs and dark templar in most games.
| opening | games | wins |
|---|---|---|
| 10HatchHydra | 1 | 0% |
| 10Pool9Hatch | 1 | 0% |
| 11Gas10PoolLurker | 11 | 9% |
| 11Gas10PoolMuta | 1 | 0% |
| 11HatchTurtleLurker | 1 | 0% |
| 12Hatch12Pool | 1 | 0% |
| 12HatchTurtle | 2 | 0% |
| 12Hatch_4HatchLing | 2 | 0% |
| 2HatchHydraBust | 1 | 0% |
| 2HatchLurker | 1 | 0% |
| 3HatchHydra | 1 | 0% |
| 3HatchHydraBust | 1 | 0% |
| 3HatchHydraExpo | 4 | 0% |
| 3HatchLing | 1 | 0% |
| 3HatchLingBust2 | 10 | 20% |
| 3HatchLingExpo | 1 | 0% |
| 4HatchBeforeGas | 3 | 0% |
| 4HatchBeforeLair | 3 | 0% |
| 4PoolSoft | 1 | 0% |
| 5HatchBeforeGas | 2 | 0% |
| 5Scout | 1 | 0% |
| 8-8HydraRush | 1 | 0% |
| 8Hatch7Pool | 1 | 0% |
| 8Hatch7PoolSpeed | 19 | 16% |
| 9GasLair | 1 | 0% |
| 9HatchExpo9Pool9Gas | 2 | 0% |
| 9PoolBurrow | 1 | 0% |
| 9PoolSpeedAllIn | 1 | 0% |
| AntiFact_2Hatch | 1 | 0% |
| AntiFactory | 1 | 0% |
| OverhatchExpoLing | 3 | 0% |
| OverhatchExpoMuta | 1 | 0% |
| OverhatchLateGas | 1 | 0% |
| Overpool+1 | 1 | 0% |
| OverpoolSunk | 1 | 0% |
| ZvP_2HatchMuta | 1 | 0% |
| ZvP_3BaseSpire+Den | 11 | 0% |
| ZvZ_12Gas11Pool | 1 | 0% |
| ZvZ_12HatchMain | 1 | 0% |
| ZvZ_12Pool | 1 | 0% |
| 40 openings | 100 | 6% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Heavy rush | - | - | 4 | 4% | 0% | 0% | 0% | |
| Proxy | - | - | 6 | 6% | 0% | 0% | 0% | |
| Safe expand | 11 | 11% | 9% | 23 | 23% | 13% | 18% | 0% |
| Turtle | 89 | 89% | 6% | 63 | 63% | 5% | 62% | 4% |
| Unknown | - | - | 4 | 4% | 0% | 0% | 0% | |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 43 | 1:26 | 1:09 | 1:58 |
| gas steal success | 24 | - | - | - |
| enemy scout | 99 | 1:34 | 1:14 | 9:35 |
| enemy combat units | 100 | 5:26 | 4:07 | 6:58 |
| enemy air units | 31 | 9:47 | 8:54 | 16:19 |
| enemy cloaked units | 36 | 9:44 | 7:23 | 14:39 |
DaQin played forge-expand and has similar timings to Locutus, for the same reasons. The fast scout is to allow adjustment of the cannon count and timing, and the late combat units are due to getting a gateway later. Steamhammer couldn’t find any better reaction than to try to bust with zerglings, either early or late, and it was not particularly successful.
| opening | games | wins |
|---|---|---|
| 2.5HatchMuta | 1 | 0% |
| 3HatchLingExpo | 1 | 0% |
| 9HatchExpo9Pool9Gas | 3 | 67% |
| 9PoolLurker | 9 | 33% |
| 9PoolSpeedAllIn | 1 | 0% |
| 9PoolSunkHatch | 12 | 58% |
| 9PoolSunkSpeed | 9 | 33% |
| OverpoolSunk | 13 | 38% |
| ZvZ_Overgas9Pool | 12 | 58% |
| ZvZ_Overpool9Gas | 39 | 82% |
| 10 openings | 100 | 59% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Turtle | 100 | 100% | 59% | 79 | 79% | 71% | 79% | 21% |
| Unknown | - | - | 21 | 21% | 14% | 0% | 0% | |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 26 | 1:14 | 1:11 | 1:37 |
| gas steal success | 12 | - | - | - |
| enemy scout | 99 | 2:55 | 0:37 | 7:23 |
| enemy combat units | 100 | 4:06 | 2:25 | 4:43 |
| enemy air units | 66 | 5:29 | 5:03 | 10:11 |
| enemy cloaked units | 0 | - | - | - |
ZZZKBot mostly played a turtle-into-mutalisks strategy against Steamhammer, and was somewhat successful. You can read the idea straight out of the tables above. The 2:25 earliest timing but 4:06 median timing for combat units says that ZZZKBot sometimes rushed zerglings, but usually not.
| opening | games | wins |
|---|---|---|
| 11Gas10PoolLurker | 28 | 43% |
| 11Gas10PoolMuta | 15 | 20% |
| 2HatchHydra | 1 | 0% |
| 3HatchLing | 1 | 0% |
| 3HatchLingBust2 | 1 | 0% |
| 5PoolHard | 1 | 0% |
| 6Pool | 1 | 0% |
| 7-7HydraLingRush | 1 | 0% |
| 9GasLair | 1 | 0% |
| 9HatchMain9Pool9Gas | 1 | 0% |
| 9PoolLurker | 1 | 0% |
| OverhatchLing | 1 | 0% |
| OverhatchMuta | 20 | 30% |
| OverpoolLurker | 1 | 0% |
| PurpleSwarmBuild | 1 | 0% |
| Sparkle 1HatchMuta | 8 | 12% |
| ZvZ_12HatchExpo | 1 | 0% |
| ZvZ_12HatchMain | 2 | 0% |
| ZvZ_Overpool11Gas | 1 | 0% |
| ZvZ_Overpool9Gas | 1 | 0% |
| ZvZ_OverpoolTurtle | 12 | 25% |
| 21 openings | 100 | 25% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Heavy rush | 7 | 7% | 29% | 2 | 2% | 50% | 0% | 86% |
| Naked expand | 89 | 89% | 26% | 23 | 23% | 17% | 25% | 73% |
| Turtle | 4 | 4% | 0% | 1 | 1% | 0% | 0% | 75% |
| Unknown | - | - | 74 | 74% | 27% | 0% | 0% | |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 54 | 1:30 | 0:42 | 1:57 |
| gas steal success | 1 | - | - | - |
| enemy scout | 100 | 2:39 | 1:37 | 3:47 |
| enemy combat units | 100 | 2:27 | 2:14 | 3:58 |
| enemy air units | 39 | 6:25 | 5:21 | 9:19 |
| enemy cloaked units | 0 | - | - | - |
Microwave played a 9 pool speed build into expansion and then spire, which you cannot read out of the plan table because Steamhammer didn’t recognize it accurately. But in the timing table you can see that combat units (zerglings) were early and air units (mutalisks) were not late.
Steamhammer was not able to steal Microwave’s gas. It probably should have stopped trying.
| opening | games | wins |
|---|---|---|
| 2.5HatchMuta | 1 | 0% |
| 5HatchBeforeGas | 1 | 0% |
| 5Scout | 1 | 0% |
| 7-7HydraLingRush | 43 | 84% |
| 8Gas7PoolLurker B | 1 | 0% |
| AntiFact_13Pool | 11 | 55% |
| AntiFactory | 39 | 64% |
| OverhatchExpoMuta | 1 | 0% |
| OverhatchMuta | 1 | 0% |
| Sparkle 2HatchMuta | 1 | 0% |
| 10 openings | 100 | 67% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Factory | 100 | 100% | 67% | 91 | 91% | 70% | 91% | 9% |
| Unknown | - | - | 9 | 9% | 33% | 0% | 0% | |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 30 | 1:26 | 1:25 | 2:03 |
| gas steal success | 0 | - | - | - |
| enemy scout | 87 | 3:27 | 0:34 | 15:09 |
| enemy combat units | 100 | 2:59 | 2:29 | 5:27 |
| enemy air units | 23 | 13:53 | 10:11 | 20:07 |
| enemy cloaked units | 69 | 6:39 | 5:35 | 11:47 |
Look at that huge range of scout timings! 0:34 means that the scout SCV was sent immediately at the start of the game and went directly to the zerg base. 15:09 probably means that no enemy unit got into the base until the end of the game when Steamhammer lost (Steamhammer is on BWAPI 4.1.2 and cannot detect scans). Steamhammer prevented the scout entirely in 13 out of the 100 games by its own count; 15:09 is probably the same. Steamhammer was not able to steal Iron’s gas, and did eventually give up trying.
| opening | games | wins |
|---|---|---|
| 12Hatch13Pool | 1 | 0% |
| 2HatchLingAllInSpire | 16 | 19% |
| 2HatchLurkerAllIn | 1 | 0% |
| 3HatchLurker | 1 | 0% |
| 3HatchPoolMuta | 1 | 0% |
| 5PoolSoft | 1 | 0% |
| 7-7HydraLingRush | 36 | 69% |
| 7PoolMid | 24 | 75% |
| AntiFact_13Pool | 9 | 33% |
| AntiFactory | 1 | 0% |
| AntiFactoryHydra | 8 | 12% |
| Over10Hatch | 1 | 0% |
| 12 openings | 100 | 50% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Factory | 98 | 98% | 51% | 74 | 74% | 41% | 74% | 21% |
| Naked expand | - | - | 1 | 1% | 100% | 0% | 0% | |
| Safe expand | - | - | 3 | 3% | 33% | 0% | 0% | |
| Unknown | 2 | 2% | 0% | 22 | 22% | 82% | 0% | 50% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 46 | 1:26 | 1:05 | 2:08 |
| gas steal success | 1 | - | - | - |
| enemy scout | 92 | 2:37 | 1:34 | 7:29 |
| enemy combat units | 100 | 2:39 | 2:25 | 3:22 |
| enemy air units | 55 | 12:23 | 8:55 | 16:30 |
| enemy cloaked units | 61 | 7:39 | 5:42 | 17:07 |
Steamhammer liked 7 pool against XiaoYi, just as Microwave did, but also liked its dawn hydra rush.
| opening | games | wins |
|---|---|---|
| 2HatchHydraBust | 5 | 80% |
| 3HatchHydraBust | 6 | 67% |
| 9PoolHatch | 19 | 84% |
| Over10Hatch2Sunk | 32 | 88% |
| Over10Hatch2SunkHard | 26 | 92% |
| OverpoolTurtle | 12 | 83% |
| 6 openings | 100 | 86% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Heavy rush | 97 | 97% | 87% | 64 | 64% | 80% | 63% | 19% |
| Safe expand | 2 | 2% | 100% | 11 | 11% | 100% | 0% | 0% |
| Turtle | 1 | 1% | 0% | 7 | 7% | 100% | 0% | 0% |
| Unknown | - | - | 18 | 18% | 94% | 0% | 0% | |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 53 | 1:28 | 1:11 | 1:33 |
| gas steal success | 33 | - | - | - |
| enemy scout | 92 | 2:21 | 1:14 | 9:55 |
| enemy combat units | 98 | 2:42 | 2:15 | 8:51 |
| enemy air units | 69 | 10:02 | 5:06 | 14:18 |
| enemy cloaked units | 30 | 10:29 | 5:01 | 16:39 |
| opening | games | wins |
|---|---|---|
| 5Scout | 28 | 75% |
| Over10Hatch2Sunk | 1 | 0% |
| OverpoolTurtle | 71 | 97% |
| 3 openings | 100 | 90% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Factory | 5 | 5% | 100% | 8 | 8% | 100% | 0% | 0% |
| Fast rush | 4 | 4% | 100% | 11 | 11% | 100% | 0% | 25% |
| Heavy rush | 86 | 86% | 88% | 47 | 47% | 87% | 48% | 24% |
| Naked expand | 5 | 5% | 100% | 10 | 10% | 100% | 0% | 40% |
| Unknown | - | - | 24 | 24% | 83% | 0% | 0% | |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 43 | 1:12 | 0:00 | 1:16 |
| gas steal success | 23 | - | - | - |
| enemy scout | 79 | 2:11 | 1:19 | 4:23 |
| enemy combat units | 61 | 2:43 | 1:46 | 4:33 |
| enemy air units | 10 | 14:20 | 12:02 | 16:57 |
| enemy cloaked units | 12 | 14:25 | 2:38 | 16:57 |
Thanks to pre-learning, I expected Steamhammer to play its overpool turtle build every game. I’m not sure why it didn’t. I also don’t know how it hit on the 5 scout build, which means send out a drone at 5 supply to scout very early, then leave all decisions to the strategy boss. It’s a logical try against a random opponent, especially one that has a single strategy for each race, and it was fairly successful. But it did not appear in the pre-learned data.
| opening | games | wins |
|---|---|---|
| 7-7HydraLingRush | 12 | 92% |
| 9HatchExpo9Pool9Gas | 30 | 100% |
| AntiFact_13Pool | 22 | 100% |
| AntiFactory | 21 | 95% |
| AntiFactoryHydra | 14 | 93% |
| ZvT_3HatchMuta | 1 | 0% |
| 6 openings | 100 | 96% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Factory | 87 | 87% | 97% | 30 | 30% | 97% | 28% | 62% |
| Fast rush | 4 | 4% | 100% | 4 | 4% | 100% | 0% | 50% |
| Heavy rush | 4 | 4% | 100% | 2 | 2% | 100% | 25% | 50% |
| Turtle | 4 | 4% | 100% | 5 | 5% | 60% | 0% | 25% |
| Unknown | 1 | 1% | 0% | 59 | 59% | 98% | 0% | 0% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 44 | 1:25 | 1:12 | 1:58 |
| gas steal success | 3 | - | - | - |
| enemy scout | 25 | 3:31 | 2:41 | 19:11 |
| enemy combat units | 100 | 3:23 | 1:57 | 8:09 |
| enemy air units | 31 | 11:27 | 7:46 | 19:34 |
| enemy cloaked units | 59 | 7:38 | 5:19 | 16:34 |
AITP scored zip against both mass zerglings (9HatchExpo9Pool9Gas) and against fast mutalisks (AntiFact_13Pool). And it successfully scouted Steamhammer’s base only 25% of the time. If you don’t scout reliably, it will be hard to withstand rushes.
| opening | games | wins |
|---|---|---|
| 9PoolExpo | 42 | 100% |
| 9PoolSunkHatch | 31 | 100% |
| 9PoolSunkSpeed | 27 | 100% |
| 3 openings | 100 | 100% |
| plan | predicted | recognized | accuracy | |||||
|---|---|---|---|---|---|---|---|---|
| count | games | wins | count | games | wins | good | ? | |
| Proxy | 66 | 66% | 100% | 35 | 35% | 100% | 36% | 36% |
| Unknown | - | - | 42 | 42% | 100% | 0% | 0% | |
| Worker rush | 34 | 34% | 100% | 23 | 23% | 100% | 15% | 53% |
| timing | # | median | early | late |
|---|---|---|---|---|
| gas steal attempt | 40 | 1:35 | 1:32 | 1:37 |
| gas steal success | 33 | - | - | - |
| enemy scout | 91 | 2:10 | 1:47 | 3:47 |
| enemy combat units | 84 | 2:43 | 2:09 | 3:27 |
| enemy air units | 0 | - | - | - |
| enemy cloaked units | 0 | - | - | - |
Steamhammer was not able to judge whether BunkerBoxeR was playing a proxy (with its proxy bunker) or a worker rush (since it sent SCVs in support). But it didn’t matter. The reactions are nearly the same. Since BunkerBoxeR never wants gas, stealing its gas was a waste.
| total | ZvT | ZvP | ZvZ | ZvR | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| opening | games | wins | games | wins | games | wins | games | wins | games | wins |
| 10HatchHydra | 2 | 0% | 2 | 0% | ||||||
| 10Pool9Gas | 1 | 0% | 1 | 0% | ||||||
| 10Pool9Hatch | 1 | 0% | 1 | 0% | ||||||
| 11Gas10PoolLurker | 41 | 32% | 13 | 8% | 28 | 43% | ||||
| 11Gas10PoolMuta | 27 | 15% | 12 | 8% | 15 | 20% | ||||
| 11HatchTurtleHydra | 51 | 43% | 51 | 43% | ||||||
| 11HatchTurtleLurker | 2 | 0% | 2 | 0% | ||||||
| 11HatchTurtleMuta | 15 | 20% | 15 | 20% | ||||||
| 12Hatch12Pool | 2 | 0% | 2 | 0% | ||||||
| 12Hatch13Pool | 1 | 0% | 1 | 0% | ||||||
| 12HatchTurtle | 2 | 0% | 2 | 0% | ||||||
| 12Hatch_4HatchLing | 4 | 0% | 4 | 0% | ||||||
| 2.5HatchMuta | 5 | 0% | 1 | 0% | 3 | 0% | 1 | 0% | ||
| 2HatchHydra | 2 | 0% | 1 | 0% | 1 | 0% | ||||
| 2HatchHydraBust | 10 | 40% | 10 | 40% | ||||||
| 2HatchLingAllInSpire | 19 | 16% | 16 | 19% | 3 | 0% | ||||
| 2HatchLurker | 1 | 0% | 1 | 0% | ||||||
| 2HatchLurkerAllIn | 1 | 0% | 1 | 0% | ||||||
| 3HatchHydra | 3 | 0% | 3 | 0% | ||||||
| 3HatchHydraBust | 13 | 31% | 13 | 31% | ||||||
| 3HatchHydraExpo | 7 | 0% | 7 | 0% | ||||||
| 3HatchLateHydras | 1 | 0% | 1 | 0% | ||||||
| 3HatchLateHydras+1 | 5 | 0% | 5 | 0% | ||||||
| 3HatchLing | 3 | 0% | 2 | 0% | 1 | 0% | ||||
| 3HatchLingBust2 | 14 | 14% | 13 | 15% | 1 | 0% | ||||
| 3HatchLingExpo | 12 | 8% | 11 | 9% | 1 | 0% | ||||
| 3HatchLurker | 1 | 0% | 1 | 0% | ||||||
| 3HatchPoolMuta | 1 | 0% | 1 | 0% | ||||||
| 4HatchBeforeGas | 4 | 0% | 4 | 0% | ||||||
| 4HatchBeforeLair | 9 | 0% | 9 | 0% | ||||||
| 4PoolSoft | 1 | 0% | 1 | 0% | ||||||
| 5HatchBeforeGas | 5 | 0% | 1 | 0% | 4 | 0% | ||||
| 5PoolHard | 2 | 0% | 1 | 0% | 1 | 0% | ||||
| 5PoolHard2Player | 2 | 0% | 2 | 0% | ||||||
| 5PoolSoft | 2 | 0% | 1 | 0% | 1 | 0% | ||||
| 5Scout | 31 | 68% | 1 | 0% | 2 | 0% | 28 | 75% | ||
| 6Pool | 2 | 0% | 1 | 0% | 1 | 0% | ||||
| 6PoolSpeed | 1 | 0% | 1 | 0% | ||||||
| 7-7HydraLingRush | 93 | 77% | 91 | 79% | 1 | 0% | 1 | 0% | ||
| 7Pool12Hatch | 1 | 0% | 1 | 0% | ||||||
| 7PoolMid | 24 | 75% | 24 | 75% | ||||||
| 7PoolSoft | 1 | 0% | 1 | 0% | ||||||
| 8-8HydraRush | 2 | 0% | 2 | 0% | ||||||
| 8Gas7PoolLurker B | 2 | 0% | 1 | 0% | 1 | 0% | ||||
| 8Hatch7Pool | 2 | 0% | 2 | 0% | ||||||
| 8Hatch7PoolSpeed | 19 | 16% | 19 | 16% | ||||||
| 8Pool | 1 | 0% | 1 | 0% | ||||||
| 9GasLair | 2 | 0% | 1 | 0% | 1 | 0% | ||||
| 9HatchExpo9Pool9Gas | 35 | 91% | 30 | 100% | 2 | 0% | 3 | 67% | ||
| 9HatchMain9Pool9Gas | 2 | 0% | 1 | 0% | 1 | 0% | ||||
| 9Pool | 2 | 0% | 2 | 0% | ||||||
| 9PoolBurrow | 3 | 0% | 3 | 0% | ||||||
| 9PoolExpo | 42 | 100% | 42 | 100% | ||||||
| 9PoolHatch | 21 | 76% | 21 | 76% | ||||||
| 9PoolLurker | 10 | 30% | 10 | 30% | ||||||
| 9PoolSpeed | 1 | 0% | 1 | 0% | ||||||
| 9PoolSpeedAllIn | 3 | 0% | 2 | 0% | 1 | 0% | ||||
| 9PoolSpire | 1 | 0% | 1 | 0% | ||||||
| 9PoolSunkHatch | 43 | 88% | 31 | 100% | 12 | 58% | ||||
| 9PoolSunkSpeed | 36 | 83% | 27 | 100% | 9 | 33% | ||||
| AntiFact_13Pool | 42 | 74% | 42 | 74% | ||||||
| AntiFact_2Hatch | 16 | 38% | 16 | 38% | ||||||
| AntiFact_Overpool9Gas | 2 | 0% | 2 | 0% | ||||||
| AntiFactory | 62 | 73% | 61 | 74% | 1 | 0% | ||||
| AntiFactoryHydra | 22 | 64% | 22 | 64% | ||||||
| AntiZeal_12Hatch | 11 | 0% | 11 | 0% | ||||||
| DefilerRush | 2 | 0% | 2 | 0% | ||||||
| HiveRush | 1 | 0% | 1 | 0% | ||||||
| Over10Hatch | 3 | 0% | 1 | 0% | 2 | 0% | ||||
| Over10Hatch1Sunk | 4 | 0% | 4 | 0% | ||||||
| Over10Hatch2Sunk | 35 | 80% | 34 | 82% | 1 | 0% | ||||
| Over10Hatch2SunkHard | 26 | 92% | 26 | 92% | ||||||
| Over10HatchBust | 28 | 25% | 28 | 25% | ||||||
| Over10HatchSlowLings | 1 | 0% | 1 | 0% | ||||||
| Over10PoolMuta | 1 | 0% | 1 | 0% | ||||||
| OverhatchExpoLing | 5 | 0% | 5 | 0% | ||||||
| OverhatchExpoMuta | 4 | 0% | 1 | 0% | 3 | 0% | ||||
| OverhatchLateGas | 2 | 0% | 2 | 0% | ||||||
| OverhatchLing | 1 | 0% | 1 | 0% | ||||||
| OverhatchMuta | 21 | 29% | 1 | 0% | 20 | 30% | ||||
| Overpool+1 | 2 | 0% | 2 | 0% | ||||||
| Overpool2HatchLurker | 1 | 0% | 1 | 0% | ||||||
| OverpoolHatch | 1 | 0% | 1 | 0% | ||||||
| OverpoolHydra | 12 | 0% | 12 | 0% | ||||||
| OverpoolLurker | 1 | 0% | 1 | 0% | ||||||
| OverpoolSpeed | 6 | 0% | 6 | 0% | ||||||
| OverpoolSunk | 15 | 33% | 2 | 0% | 13 | 38% | ||||
| OverpoolTurtle | 85 | 93% | 14 | 71% | 71 | 97% | ||||
| OverpoolTurtle 0 | 1 | 0% | 1 | 0% | ||||||
| Overpool_4HatchLing | 2 | 0% | 2 | 0% | ||||||
| PurpleSwarmBuild | 2 | 0% | 1 | 0% | 1 | 0% | ||||
| Sparkle 1HatchMuta | 9 | 11% | 1 | 0% | 8 | 12% | ||||
| Sparkle 2HatchMuta | 2 | 0% | 1 | 0% | 1 | 0% | ||||
| ZvP_2HatchMuta | 1 | 0% | 1 | 0% | ||||||
| ZvP_3BaseSpire+Den | 12 | 0% | 12 | 0% | ||||||
| ZvP_3HatchPoolHydra | 3 | 0% | 3 | 0% | ||||||
| ZvP_4HatchPoolHydra | 14 | 21% | 14 | 21% | ||||||
| ZvP_Overpool3Hatch | 2 | 0% | 2 | 0% | ||||||
| ZvT_12PoolMuta | 2 | 0% | 2 | 0% | ||||||
| ZvT_3HatchMuta | 2 | 0% | 1 | 0% | 1 | 0% | ||||
| ZvT_7Pool | 1 | 0% | 1 | 0% | ||||||
| ZvZ_12Gas11Pool | 1 | 0% | 1 | 0% | ||||||
| ZvZ_12HatchExpo | 1 | 0% | 1 | 0% | ||||||
| ZvZ_12HatchMain | 3 | 0% | 1 | 0% | 2 | 0% | ||||
| ZvZ_12Pool | 1 | 0% | 1 | 0% | ||||||
| ZvZ_12PoolLing | 1 | 0% | 1 | 0% | ||||||
| ZvZ_12PoolLingB | 1 | 0% | 1 | 0% | ||||||
| ZvZ_Overgas9Pool | 12 | 58% | 12 | 58% | ||||||
| ZvZ_Overpool11Gas | 1 | 0% | 1 | 0% | ||||||
| ZvZ_Overpool9Gas | 50 | 70% | 10 | 30% | 40 | 80% | ||||
| ZvZ_OverpoolTurtle | 12 | 25% | 12 | 25% | ||||||
| total | 1200 | 52% | 400 | 78% | 500 | 28% | 200 | 42% | 100 | 90% |
| openings played | 111 | 24 | 93 | 29 | 3 | |||||
Steamhammer knows 142 different openings. In the whole tournament, it was only able to try 111 of them! It tried the most openings versus protoss, since it was looking everywhere for an escape from the overwhelming top protoss bots. Most openings were tried only a few times and lost every game, which means that Steamhammer would have performed better without them. That’s expected and even intentional; my plan is to add smarts until it is able to make good guesses about what to try. The work is underway.
Microwave keeps its result files in the same format as UAlbertaBot: A file for each opponent, and in the file a list of strategies tried, each with win and loss counts. But Microwave independently restricts the win count and the loss count to not exceed 10. This amounts to intentionally forgetting older history when there has been a lot of it. The advantage is that Microwave adapts its strategies more quickly if the opponent shifts its play. The disadvantage, of course, is that information is thrown away. As a side effect, the numbers in the “total” and “overall” cells of my tables are not too informative.
This post looks at Microwave’s result_*.txt files for each opponent, since it’s what I’ve done before and I already had a script to parse them. This year Microwave also kept history_*.txt files with a record of each game. I could get a fuller picture of what Microwave did from the history files. I’m not sure whether Microwave uses the history files to make decisions. Still, if this is about “what Microwave learned,” then the result files are what Microwave learned, at least in large part.
Microwave has pre-learned data files for a number of opponents. Data from those files survived to be included in these tables. In other words, the tables here include not only tournament games, but in some cases preparation games played before the tournament.
Microwave’s author MicroDK commented that Microwave might have a bug in keeping its learning files, since the numbers did not always agree with official tournament results. As explained yesterday for UAlbertaBot, the player cannot always know what the tournament manager decides is the outcome of the game. Between that and the pre-learned data, I see reason to doubt that Microwave had a bug. But I didn’t look into details.
This year Microwave recorded a total of 32 strategies, compared to 19 last year. I tried to keep the tables tractable by breaking them down by opponent race, since not all strategies were tried against all races. Nevertheless, prepare to scroll right!
It seems that most of Microwave’s openings worked about equally poorly against Iron, which is interesting and hard for me to explain. 2 hatch muta equals 3 hatch hydra bust equals 7 pool—among others? XiaoYi was vulnerable to rushes, and Microwave settled on 7 pool. After seeing the learning files of only 2 bots, I’m already getting a picture of XiaoYi as strong but apparently not robust against tricky strategies; UAlbertaBot chose DT rush against it. AITP and BunkerBoxeR were easy opponents and seem to have been vulnerable to the first thing Microwave tried, so that zerg never felt the need to vary.
The tournament had 100 rounds. Totals of more than 100 games versus an opponent, as versus Iron here, are a sign that pre-learned data was carried over. Microwave did not have time during the competition to try this many strategies so many times each.
| # | bot | total | 10Hatch9Pool9gas | 2HatchHydra | 2HatchLurker | 2HatchLurkerAllIn | 2HatchMuta | 3HatchHydraBust | 3HatchHydraExpo | 3HatchLingBust | 3HatchPoolHydra | 4HatchBeforeGas | 4PoolHard | 4PoolSoft | 5Pool | 5PoolSpeed | 6Pool | 6PoolSpeed | 7Pool | 8Pool | 9Pool | 9PoolLurker | 9PoolSpeed | 9PoolSpeedLing | OverpoolTurtle | ZvZ_Overpool11Gas |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 8 | iron | 63-175 26% | 1-5 17% | 1-5 17% | 1-5 17% | 2-7 22% | 5-10 33% | 5-10 33% | 1-5 17% | 0-5 0% | 1-5 17% | 2-7 22% | 5-10 33% | 5-10 33% | 1-5 17% | 5-10 33% | 1-5 17% | 3-8 27% | 5-10 33% | 5-10 33% | 3-8 27% | 4-10 29% | 2-7 22% | 2-7 22% | 3-8 27% | 0-3 0% |
| 9 | xiaoyi | 22-13 63% | 0-2 0% | - | 0-1 0% | - | 0-2 0% | - | - | - | - | - | - | 10-4 71% | 1-1 50% | - | - | - | 10-0 100% | - | 1-1 50% | - | - | 0-2 0% | - | - |
| 12 | aitp | 10-0 100% | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | 10-0 100% | - | - |
| 13 | bunkerboxer | 10-0 100% | - | - | - | - | - | - | - | - | - | - | - | - | 10-0 100% | - | - | - | - | - | - | - | - | - | - | - |
| overall | - 36% | 1-7 12% | 1-5 17% | 1-6 14% | 2-7 22% | 5-12 29% | 5-10 33% | 1-5 17% | 0-5 0% | 1-5 17% | 2-7 22% | 5-10 33% | 15-14 52% | 12-6 67% | 5-10 33% | 1-5 17% | 3-8 27% | 15-10 60% | 5-10 33% | 4-9 31% | 4-10 29% | 2-7 22% | 12-9 57% | 3-8 27% | 0-3 0% | |
Aha, Bananabrain had a weakness against Microwave’s 3 hatch zergling bust! I’ve seen the same on BASIL, e.g. Microwave-BananaBrain on Empire of the Sun, where BananaBrain was negligent in setting up the defense of its natural. In general, Bananabrain showed sensitivity to the opponent’s strategy; the other top protoss bots were more consistent.
| # | bot | total | 10Hatch9Pool9gas | 2HatchHydra | 2HatchLurker | 2HatchLurkerAllIn | 2HatchMuta | 3HatchHydraBust | 3HatchHydraExpo | 3HatchLingBust | 3HatchPoolHydra | 4HatchBeforeGas | 4PoolHard | 4PoolSoft | 5Pool | 5PoolSpeed | 6Pool | 6PoolSpeed | 7Pool | 8Pool | 9Pool | 9PoolLurker | 9PoolSpeed | 9PoolSpeedLing | ZvP_10Hatch9Pool | ZvZ_Overgas11Pool | ZvZ_Overgas9Pool | ZvZ_Overpool11Gas |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | locutus | 0-202 0% | 0-10 0% | 0-10 0% | 0-10 0% | 0-8 0% | 0-10 0% | 0-10 0% | - | 0-8 0% | 0-8 0% | 0-8 0% | 0-10 0% | 0-10 0% | 0-10 0% | 0-8 0% | 0-8 0% | 0-8 0% | 0-10 0% | 0-8 0% | 0-10 0% | 0-7 0% | 0-10 0% | 0-7 0% | 0-7 0% | - | - | 0-7 0% |
| 2 | purplewave | 26-154 14% | 2-10 17% | 2-9 18% | 0-6 0% | 0-5 0% | 2-10 17% | 2-10 17% | 0-4 0% | 3-10 23% | 0-4 0% | 0-4 0% | 0-3 0% | 3-10 23% | 3-10 23% | 0-3 0% | 0-3 0% | 0-3 0% | 3-10 23% | 2-9 18% | 0-3 0% | 0-5 0% | 1-7 12% | 3-10 23% | 0-3 0% | - | - | 0-3 0% |
| 3 | bananabrain | 85-130 40% | 1-3 25% | 2-4 33% | 2-5 29% | 1-5 17% | 2-4 33% | 0-2 0% | 1-4 20% | 10-4 71% | 1-4 20% | 0-5 0% | 6-7 46% | 10-9 53% | 10-9 53% | 5-7 42% | 3-5 38% | 4-6 40% | 1-3 25% | 4-6 40% | 4-6 40% | 0-5 0% | 2-4 33% | 4-6 40% | 0-2 0% | - | 7-8 47% | 5-7 42% |
| 4 | daqin | 8-64 11% | 2-9 18% | 0-4 0% | 0-4 0% | - | 3-10 23% | 0-3 0% | - | 3-10 23% | 0-3 0% | - | - | 0-3 0% | 0-3 0% | - | - | - | 0-3 0% | - | 0-3 0% | - | 0-3 0% | 0-3 0% | 0-3 0% | - | - | - |
| 10 | mcrave | 95-78 55% | 2-2 50% | 2-3 40% | 5-3 62% | 2-3 40% | 10-4 71% | 10-0 100% | 0-4 0% | 2-3 40% | 1-2 33% | 1-4 20% | 3-2 60% | 10-4 71% | 1-4 20% | 2-3 40% | 5-4 56% | 10-5 67% | 4-5 44% | 2-3 40% | 7-4 64% | 0-3 0% | 3-3 50% | 3-2 60% | 2-2 50% | 8-4 67% | - | 0-2 0% |
| overall | - 25% | 7-34 17% | 6-30 17% | 7-28 20% | 3-21 12% | 17-38 31% | 12-25 32% | 1-12 8% | 18-35 34% | 2-21 9% | 1-21 5% | 9-22 29% | 23-36 39% | 14-36 28% | 7-21 25% | 8-20 29% | 14-22 39% | 8-31 21% | 8-26 24% | 11-26 30% | 0-20 0% | 6-27 18% | 10-28 26% | 2-17 11% | 8-4 67% | 7-8 47% | 5-19 21% | |
Steamhammer and ZZZKBot are opposite opponents, from Microwave’s point of view. Whatever worked against one did not work against the other. Most of the numbers in Steamhammer’s row, by the way, are from preparation games. I see the same numbers in the pre-learned data file. According to the history file, Microwave played its 9 pool speed opening in every game.
| # | bot | total | 12Pool | 4PoolHard | 4PoolSoft | 5Pool | 5PoolSpeed | 6Pool | 6PoolSpeed | 7Pool | 8Pool | 9HatchMain8Pool8Gas | 9PoolHatch | 9PoolSpeed | 9PoolSunken | OverpoolSpeed | OverpoolTurtle | ZvZ_Overgas11Pool | ZvZ_Overpool11Gas |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 5 | steamhammer | 26-16 62% | 2-2 50% | - | - | 1-2 33% | - | - | - | - | - | 2-2 50% | 1-2 33% | 10-0 100% | 1-2 33% | 4-3 57% | - | - | 5-3 62% |
| 6 | zzzkbot | 67-70 49% | 0-2 0% | 1-5 17% | 0-2 0% | 10-7 59% | 0-2 0% | 0-2 0% | 5-10 33% | 1-5 17% | 7-10 41% | 10-7 59% | 10-4 71% | 0-2 0% | 0-2 0% | 3-4 43% | 10-4 71% | 10-0 100% | 0-2 0% |
| overall | - 52% | 2-4 33% | 1-5 17% | 0-2 0% | 11-9 55% | 0-2 0% | 0-2 0% | 5-10 33% | 1-5 17% | 7-10 41% | 12-9 57% | 11-6 65% | 10-2 83% | 1-4 20% | 7-7 50% | 10-4 71% | 10-0 100% | 5-5 50% | |
UAlbertaBot was the only random participant. It’s striking how similar openings can have different outcomes, though the numbers are noisy because the game counts intentionally limited and an opening that makes a bad first impression may not be repeated.
| # | bot | total | 4PoolHard | 4PoolSoft | 5Pool | 5PoolSpeed | 6Pool | 6PoolSpeed | 7Pool | 8Pool | 9PoolSpeedLing |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 11 | ualbertabot | 34-21 62% | 5-4 56% | 10-0 100% | 4-4 50% | 10-3 77% | 4-3 57% | 1-2 33% | 0-2 0% | 0-2 0% | 0-1 0% |
| overall | - 62% | 5-4 56% | 10-0 100% | 4-4 50% | 10-3 77% | 4-3 57% | 1-2 33% | 0-2 0% | 0-2 0% | 0-1 0% | |
#11 UAlbertaBot was one of the weaker participants, but no player shut it out. Even against #1 Locutus, UAlbertaBot scored 1 win and learned a little bit about its opponent. That also tells us something about each opponent.
The “total” column gives UAlbertaBot’s view of how many games it won and lost, which does not always line up with the tournament results. The results give UAlbertaBot 6 crashes, when it presumably could not record any information. Also if one side overstepped the frame time limit (UAlbertaBot never did), or if the game timed out and was decided on points (12 instances for UAlbertaBot), the player has no way to know what the tournament manager decided, and the two may disagree about who won. Something like that must explain why UAlbertaBot recorded 3 wins for itself against #2 PurpleWave when officially it won only 2 games. These issues cause difficulties for learning, but as long as most games finish normally it shouldn’t be serious.
| # | bot | total | Terran | Terran | Terran | Terran | Protoss | Protoss | Protoss | Zerg | Zerg | Zerg | Zerg |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 4RaxMarines | MarineRush | TankPush | VultureRush | DTRush | DragoonRush | ZealotRush | 2HatchHydra | 3HatchMuta | 3HatchScourge | ZerglingRush | |||
| 1 | locutus | 1-99 1% | 0-9 0% | 0-8 0% | 0-8 0% | 0-8 0% | 0-11 0% | 1-15 6% | 0-10 0% | 0-8 0% | 0-8 0% | 0-7 0% | 0-7 0% |
| 2 | purplewave | 3-93 3% | 0-8 0% | 0-8 0% | 0-8 0% | 0-8 0% | 3-18 14% | 0-8 0% | 0-7 0% | 0-7 0% | 0-7 0% | 0-7 0% | 0-7 0% |
| 3 | bananabrain | 16-82 16% | 0-7 0% | 1-10 9% | 0-6 0% | 0-6 0% | 0-4 0% | 0-4 0% | 9-20 31% | 0-4 0% | 0-4 0% | 0-4 0% | 6-13 32% |
| 4 | daqin | 21-77 21% | 0-10 0% | 0-9 0% | 0-9 0% | 0-9 0% | 0-3 0% | 3-8 27% | 5-8 38% | 0-2 0% | 0-2 0% | 0-2 0% | 13-15 46% |
| 5 | steamhammer | 9-89 9% | 0-4 0% | 8-9 47% | 0-4 0% | 0-4 0% | 0-6 0% | 1-9 10% | 0-5 0% | 0-12 0% | 0-12 0% | 0-12 0% | 0-12 0% |
| 6 | zzzkbot | 10-89 10% | 0-8 0% | 0-8 0% | 0-8 0% | 0-7 0% | 0-4 0% | 0-4 0% | 8-16 33% | 0-7 0% | 0-7 0% | 0-7 0% | 2-13 13% |
| 7 | microwave | 18-81 18% | 0-7 0% | 2-12 14% | 0-7 0% | 0-7 0% | 0-3 0% | 0-3 0% | 13-11 54% | 1-9 10% | 0-5 0% | 1-9 10% | 1-8 11% |
| 8 | iron | 9-90 9% | 1-9 10% | 1-8 11% | 0-5 0% | 0-5 0% | 0-8 0% | 0-8 0% | 3-18 14% | 0-6 0% | 0-6 0% | 0-6 0% | 4-11 27% |
| 9 | xiaoyi | 26-68 28% | 0-4 0% | 0-5 0% | 4-13 24% | 0-4 0% | 21-5 81% | 0-2 0% | 0-5 0% | 0-7 0% | 0-7 0% | 0-6 0% | 1-10 9% |
| 10 | mcrave | 56-44 56% | - | 22-9 71% | - | - | 0-4 0% | 10-19 34% | 0-5 0% | - | - | - | 24-7 77% |
| 12 | aitp | 71-23 76% | - | 19-8 70% | - | - | - | - | 24-5 83% | 19-2 90% | 7-2 78% | 1-2 33% | 1-4 20% |
| 13 | bunkerboxer | 88-12 88% | - | 34-4 89% | - | - | - | - | 30-0 100% | - | - | - | 24-8 75% |
| overall | - 28% | 1-66 1% | 87-98 47% | 4-68 6% | 0-58 0% | 24-66 27% | 15-80 16% | 92-110 46% | 20-64 24% | 7-60 10% | 2-62 3% | 76-115 40% | |
UAlbertaBot was random. Its learning plan is to first play its best opening for each race (terran marine rush, protoss zealot rush, zerg zergling rush), and switch away only if it lost too often. If you are always losing, there is no harm in experimentation. Against strong opponents it tried everything, to little avail. Against weak opponents, the best opening might be reliable, so it did not try others.
UAlbertaBot’s configuration file has enemy-specific strategies defined for many historical opponents. In this tournament, 2 of them reappeared: Iron and ZZZKBot, and the declaration for ZZZKBot says “make the default choices.” I don’t see evidence in the table that UAlbertaBot paid attention to its Iron-specific strategies, so I watched replays to find out. It turned out as I expected, an enemy-specific strategy became the default strategy, the expected best opening, and if it failed severely enough (as it always did against Iron) then UAlbertaBot would try its other strategies.
The “overall” row across the bottom tells us that its best openings truly were the best. In most cases, it did no good to try alternatives. The notable exceptions are that the dark templar rush won against XiaoYi, while the 2 hatch hydra rush won against AITP (this suggests that AITP consistently followed a mech strategy). Of course, UAlbertaBot played random, which can confuse opponents that learn. It’s possible that a protoss bot that always rushed dark templar might do less well against XiaoYi, and so on.
Some openings were useless in the tournament, and UAlbertaBot would have done better without them. For example, the 3 hatchery scourge opening is designed to combat XIMP by Tomas Vajda, and scored miserably. The terran vulture rush made 58 losses and no wins at all, a weight pulling down the ranking.
There is more to learn from the table. Steamhammer had some trouble against the terran marine rush, but shut out the zealots and the zerglings. The other 2 zergs had more trouble against the hard zealot rush (which was historically difficult for zerg bots to cope with, at least zerg bots other than KillerBot by Marian Devecka). I think the difference ultimately reflects the skills of the different bots. Steamhammer has micro and defensive weaknesses against ranged units in general (the one loss against protoss was to the dragoon rush). Its opening learning is ingenious enough to cover the weakness, but only at the expense of losses against protoss and zerg. So instead Steamhammer’s learning converged on the idea of allowing the marines to win sometimes, and strictly controlling the other races. It’s counterintuitive but effective.
I’ve uploaded Steamhammer 2.3.6 to SSCAIT. The main purpose of this point release is to fix a combat simulation bug that I cleverly—nay, brilliantly inserted just before the AIIDE tournament, to ensure that Steamhammer’s results didn’t discourage other bot authors. The bug caused deviations from excellence such as scoring 67% against Iron rather than 95%. The bug had a variety of effects, but the most important is that mutalisks were afraid of enemies that they could not see, even enemies like vultures that could not shoot back. Come into view and die, stay out of sight and live forever.
After AIIDE prep I wanted to do something fun, so I also added queen skills, improved defiler plague, and fixed a bunch of easier bugs and weaknesses, including a few important ones. Important changes are in bold.
• Setup of combat simulation is corrected. In the AIIDE version I added code in the CombatSimulation class (which works the details of setting up a combat sim) to bypass the combat sim and return a short-circuit result in certain easy cases where the enemy has undetected cloaked units. FAP does not simulate cloaking and detection, so it was an important improvement. I reversed a condition in an important bit of code, which had the effect that the short-circuit worked correctly in the cases where it was supposed to, but also worked in cases where it was not supposed to. Ouch.
• An infested command center was misrecorded as belonging to both sides. That was a fun bug! There was a correct record saying it was zerg, and a leftover incorrect record claiming that it was still terran. I didn’t test mind control, but the bug must have affected that too. The most obvious effect was that a squad might be ordered to attack the location of the “enemy base,” after which they would gather around the infested CC and warm their hands (well, claws).
• A lifted command center no longer establishes a base. The code that checked “does somebody own this base?” did not consider whether a command center in the correct location might be in the air. That generally led units to collect underneath the lifted CC until it was either shot down or moved away from the base location. It didn’t cause any losses that I saw, but it did cause bad play.
• Workers start transferring to a new base before the base’s resource depot completes. It’s something of a big deal, because Steamhammer zerg deliberately overproduces drones to populate a new base as soon as the hatchery starts, so that the base can become productive as early as possible. But then it didn’t transfer the drones until the hatchery completed. Now it computes the distance and transfers the drones to arrive after the hatchery finishes. It uses the shorter air distance instead of the true ground distance so workers are sent later than they could be, but it’s nevertheless an honorable improvement. Be afraid of the big macro.
For fun, I added broodling and ensnare and made command center infestation more reliable. Steamhammer already had parasite skills. Parasite was more successful than I expected; in recent games I think the queen sometimes paid for itself in information about the enemy. Broodling and ensnare make games more fun when they come up, especially ensnare, and they’re not too costly. There remains a lot of room to improve queen play, especially queen maneuvering and coordination.
• Broodling. If Steamhammer sees enough enemy units that want to turn into broodlings (like tanks, or high templar, or ultralisks), it will eventually make 1 or 2 queens and research broodling. Making 2 queens is new behavior. If broodling is researched, then broodling is the queen’s highest priority: The queen will stay home until it has enough energy, then join the army and broodling any enemy that wants it enough. Only if there is extra energy will it consider ensnare or parasite.
• Ensnare. If Steamhammer sees a substantial number of enemies that enjoy being ensnared, it will eventually produce a queen, research ensnare, and oblige them. If ensnare is researched, then ensnare has priority over parasite: Steamhammer will only use parasite if the queen has enough energy that a future ensnare could still happen. (Ensnare and parasite both cost 75 energy.) The ensnare code works similarly to plague: It scans around and scores the possible ensnare targets to choose the best. It likes to ensnare fast units, and it likes to reveal cloaked units with ensnare, and of course it likes to goop up as many enemies as possible. Also, I updated FAP to understand that ensnare slows down the movement and firing rate of units. FAP’s understanding of ensnared movement is approximate, but its understanding of firing rate is nearly accurate. That way Steamhammer understands that ensnared units are weaker, and now might be a good time to attack them.
• If ensnare or broodling is researched, eventually also research the queen energy upgrade.
• Infest command centers more reliably. Formerly, Steamhammer had no special infestation skill at all. It could infest a command center solely as a side effect of the queen’s behavior of staying with the army; if the army was hitting a command center, then the queen was in infestation range because the army was there. If the queen didn’t have energy for a spell, it stayed home and could not infest. Now the queen wakes up whenever an infestable command center is seen on the map, and moves toward it. Also, formerly the army might destroy the command center before the queen could infest it. Now the army recognizes when a queen is near and stops attacking the command center when it becomes infestable (below 1/2 HP). The army is more efficient, and more command centers turn to the dark side where they belong.
• Change to queen behavior that mainly affects cases where Steamhammer is contained to its natural: If a queen has enough energy to cast a spell, then its fallback retreat position is the front defense point, where it may be able to do some good. Otherwise its fallback retreat is the main base, where it should be relatively safe to sit and gain energy. This can make the queen more useful in a bad situation, but the queen is not likely to help much.
• There was an awesome extra digit in the constant “how many HP can plague eat up at most?” that Steamhammer uses in its forecast of how much damage a given plague will do. Oh... that is why it insisted on plaguing buildings even as I discounted them more and more—it thought it would do awesome damage! After fixing it, Steamhammer still loves to plague buildings; the practical effect of the fix is limited. But it has shifted its preference somewhat toward enemy units.
• I simplified the plague scoring code and tweaked it. Plague gets a higher score for putting a terran building into the red (so that it burns down if not repaired), and it will plague even a single enemy unit if it seems worth it.
• The defiler might retreat to the main base and be useless when Steamhammer was contained to its natural and needed the defiler there to break out. I changed the defiler’s fallback retreat point to be the front defense point, which is also where any sunken colonies are placed. It’s not quite the same as the queen’s fallback retreat behavior. The queen needs a safe place to gather energy, the defiler can consume.
• The finishing unit mix is drone-mutalisk. Formerly, when the opponent looked dead and Steamhammer wanted to chase down its last buildings, it made mutalisks plus whatever ground unit came out of the usual unit mix calculation, usually zerglings. That had rare unfortunate results when Steamhammer made too many ground units and could not get mutalisks. The drone count is capped at 75, so with a drone-mutalisk mix, Steamhammer will not run itself out of supply to make mutalisks and should almost never fail to finish off the opponent.
• Ensure that there is at least one zergling or hydralisk in the army at all times after the opening book. Steamhammer scouts the enemy army primarily with its own army. If its army was wiped out in battle, it might sit back behind sunkens and drone up, thinking that the enemy army was also weak, and never learn better because it didn’t have forward units to see the enemy move out. “You mean, if I keep my eyes closed, I’m not safe after all?”
• If terran or protoss has too much air, make a defensive spore colony even if Steamhammer also has a spire. Formerly, Steamhammer skipped the spore if it had a spire, because it used to be that scourge was defense enough. But if the enemy has too many air units, scourge is not enough. McRave (after an update this summer) is especially good at massing its corsairs and shooting down scourge. (In ZvZ, Steamhammer follows different rules for making defensive spores.)
• A temporary production freeze happened if Steamhammer wanted to upgrade air carapace... at the same time that it was morphing a greater spire. All production stopped until the greater spire completed. It was surprisingly common, it seemed to happen in most games where Steamhammer got a greater spire. Anyway, fixed now.
• Added a protoss opening GoonObserver to directly counter DT rushes and other cloak rushes. Unfortunately the automatic “oh no, cloaked units, hurry and build cannons” reaction still happens and tends to delay the observers, but it’s still not a bad counter.
Yesterday’s game Simplicity vs Locutus on Andromeda on BASIL starts out as one of the most entertaining bot games I have seen. The pictures show some of the cool stuff that Simplicity tried—with success. Then, after a tremendous fight where each side pressed temporary advantages and maxed its army, the replay loses sync and OpenBW cannot show the last half of the game.
Queens with broodling. The Research tab shows broodling research, and there are broodlings on the ground. Simplicity made 8 queens early and even researched queen energy, and the queens paid for themselves with interest. When Locutus attacked, zerg sent out as many queens as had energy to simultaneously spawn broodlings, helping to break the attacks. It’s a simple way to coordinate the queens to get tactical results, and is more effective than the common bot approach of using the queens as attrition weapons. Simplicity’s queens eventually died to corsairs; with more careful play, they could have lived to the end of the game, because Locutus was not skilled with its corsairs.
Island base with static defense. The overlord on the left has just dropped off another drone to join the miners.
Drops. Simplicity repeatedly dropped small numbers of units into the far end of Locutus’s base, and Locutus did not react properly. The drops were not decisive, but were cost-effective.
Both sides maxed their supply, or nearly so. At that point, Locutus had better upgrades but Simplicity had a larger army. Locutus could not keep its natural safe. Luckily for protoss, it was already mined out.
But Locutus had a stronger economy with more bases and a large bank of resources, and Simplicity ran out of resources. The desync hides the end of the game, which timed out after an hour. I believe that Locutus wiped out all zerg it could reach on the ground, and then had no answer for the island base. When the game timed out, BASIL gave the win to Simplicity on points. Moral: You need at least enough island skills to make air units to attack inaccessible bases.
Finishing off the enemy just means destroying all their buildings. It sounds simple, but it is a sophisticated skill, and there are a lot of ways to go wrong. Steamhammer has a number of special provisions for quickly finding the last enemy remnants, but small loopholes persist and occasionally a game slips through one.
PurpleSpirit-Steamhammer on La Mancha is an example. It’s an entertaining game, thanks to the purple habit of playing all over the map, but I want to focus on the end, after PurpleSpirit has lost, when Steamhammer fails to destroy the floating terran buildings that are right over its head. That part is entertaining too, but not for the same reason.
Everything terran on the ground is destroyed, except one command center which was infested instead. The remaining terran force is 2 full-strength battlecruisers, and the remaining terran infrastructure is 2 floating ebays. Steamhammer is maxed and banking resources, but its only anti-air units are 8 scourge, plus a defiler with plague. Notice how much game time is left?
One of Steamhammer’s special game-finishing skills is that it makes mutalisks to chase down the residue of the enemy. The condition is, if the enemy has no known bases and no known anti-air units, then Steamhammer will tech to mutalisks and make mutas its primary unit. The mutas scout faster than ground units, and can find floating buildings and island bases that ground units can’t reach. But here terran still has battlecruisers, so the mutalisk rule does not kick in. First the terran army, such as it is, must be defeated.
Some scourge have hit, and the battlecruisers are no longer at full HP. But Steamhammer has been replacing losses primarily with more zerglings and ultralisks, which are of no use. Oops, the unit mix is wrong. Now there are only 2 scourge, and a battlecruiser can kill a scourge in one shot—2 battlecruisers, if not distracted by other targets, are safe from 2 scourge. The ebays choose to park over the terran natural, and zerg units have congregated there. The battlecruisers seek zerg stuff to shoot, and the defiler responds by blanketing the area in defensive swarm, consuming zerglings like crazy.
Well, the 2 scourge hit one of the battlecruisers, which was distracted seeking zerg units that strayed from under dark swarm. And Steamhammer is now making 3 new pairs of scourge to replace various losses; if it can keep this up, the battlecruisers will eventually fall. Best of all, the defiler has plagued the terran buildings, despite the zerg units underneath. That will put the ebays into the yellow. One more plague should put them into the red, after which they will burn down.
Whew, finally the battlecruisers are shot down by scourge.
But that’s all she wrote. The swarms wore off and there was no need to renew them. The defiler did not plague again because it thought the zerg units underneath were more valuable. Scourge are coded to avoid floating buildings, because it is usually wasteful to spend gas destroying them. The mutalisk rule is engaged, and there is supply to build 1 mutalisk, but Steamhammer happened to choose to spawn zerglings first, and after that there was no supply to make a mutalisk. The game timed out with no more progress.
Finishing off the enemy can be hard. In this case, Steamhammer had the wrong unit mix; to make zerglings and ultralisks when all enemies were in the air was no good. The mutalisk rule should make mutalisks only, not mix them with other units. The scourge might have understood that when only floating buildings are left, they are good targets. Also the zerg ground units that can’t shoot up might have known better than to chase floating buildings (though it can be useful when they track a building trying to escape), and the defiler might have realized that damage to its own units was irrelevant when it could eliminate the enemy. That is a lot of flaws, and yet Steamhammer rarely fails to finish a game!
And fixing all the problems would only narrow the loophole, not eliminate it. In the worst case, Steamhammer would need to be able to destroy some of its own units to clear supply to make mutalisks to finish off the enemy. And that’s a high-end skill that I am in no hurry to add.
Next: The start of CoG 2019 analysis.