archive by month
Skip to content

cannon rush reactions

In Martin Rooijacker’s post on the end of the rushbots: rushes and how to defeat them, the suggested plans to defeat a cannon rush are perfunctory, only enough to get started with. In my earlier post cannon like Nal_rA I suggested other ideas, but also did not go into full detail.

Cannon rushes have become more important in bot play. Jakub Trancik builds cannons in unpredictable places (usually easily visible places, though). Juno by Yuanheng Zhu tries to cannon contain and push in; it wants to contain as close as possible, but is willing to back off and contain the entrance to the natural if it judges that it can’t get closer (though it tends to judge optimistically). AIUR can place cannons in hidden positions to hit the mineral line. And now Krasi0P likes to set up a cannon contain outside the natural and then cannon push in as far as it can, plus it has a dangerous followup game plan. And those aren’t all the possibilities! So here are more ideas on how to react. I plan to implement all of these in Steamhammer, some soon and some eventually.

categorizing cannon rushes

Placement. Cannons can be placed to restrict your movement. The most restrictive placement is a containment, which might be a containment inside the main preventing you from reaching your exit, a containment outside your exit preventing you from passing your exit, or a containment outside the natural preventing you from reaching the center of the map. Or cannons can be placed to deny access to an area, such as your natural mineral line, without stopping you from leaving your base (consider cannons above the natural on Heartbreak Ridge). Or cannons can be placed to hit critical areas, such as the mineral line, the main resource depot, a key tech building like the spawning pool, or your first production building. The mineral line is a common target, since it does the most immediate harm.

Timing. In the fastest cannon rushes, the first pylon is hidden near the enemy and the forge is built next to it. Current bot rushes are played with the forge in the main and the cannons powered by the second pylon. But cannon attacks can be played at any point in the game. If you leave a base undefended, they can put cannons near it that may double as defense when they take the base for themselves (amateurs try this sometimes). On some maps, cannons on high ground can hit a mineral line on low ground (Heartbreak Ridge is only one example; see the mineral only bases on Python for another).

Followup. Most bots will keep making cannons, trying to push in as far as they can. Objectively, once there are enough cannons to give the enemy pause (maybe 4, depending on what you’re aiming for), it’s often better to make gateways and zealots instead; the zealots and cannons defend each other, and the zealots can exploit opportunities to attack. (Presumably bots don’t switch to offense until late because it’s complicated, but it’s only a matter of time before somebody implements it well). If the cannon rush holds the other side in check, then the rusher can expand and/or tech freely and get ahead in any way it chooses.

Goal. Most bots play all-in cannon rushes to win outright (because they know bot opponents will often fall over). Most humans play pressure cannon rushes to set the enemy back so they can get ahead (because they expect that opponents will know how to react). Also possible are low-cost harassment cannon rushes to cause distraction and delay (think 1 pylon and 1 cannon in a hard-to-hit location; the cannon can even be canceled before it finishes depending on what happens).

defeating a cannon rush

In defending a cannon rush, you have a series of goals. 1. It’s best if you can prevent cannons from finishing, or at least hit them while they are few and can be defeated efficiently. 2. If the cannons finish, you need to put a brake on it so the situation doesn’t grow worse. Mitigate the threat. 3. Ultimately, you want to restore your freedom of movement or your access to a denied area.

1. Stop the cannons from finishing. If you see a cannon warping in or near your base, you need to react. If you only see a pylon, you should at least check it out in case you need to react, but it is also easy to overreact. On the one hand, if it is a manner pylon or blocking pylon to delay your natural, you react differently than to a cannon rush. On the other hand, nothing stops the enemy from building cannons next to a blocking pylon. (Or a gateway. Or a shield battery for zealots which are about to arrive.)

You can pull workers to stop cannons. To be worth it, the pull needs to be not too far away, to stop at least some cannons, and to not risk too many losses. In principle, a combat simulator can tell you whether cannons can be stopped before they finish. Are any current combat simulators accurate for cannon rushes? I doubt it. This seems easy to do crudely, difficult to do with fine judgment. Another try is to chase the cannon-building probe and make its job risky, but it’ll be hard to catch.

You also want combat units as early as possible. Start a barracks, gateway, or spawning pool. Cancel stuff if you have to. Pulling workers cuts your income and can delay combat units. Again, rules of thumb will help, excellent decisions are hard.

2. Mitigate the threat. First of all, if the cannons are in containment position, do your level best to get a worker outside before the containment is complete. If you have a scout worker already outside, it should first locate the enemy, which should be safe because there will be no gateway in the enemy main. Then keep the worker alive and hide it. If the containment is complete, you can still try to get a worker out with a diversionary attack: Send a few workers past and at the same time try to kill cannons; one or the other may succeed. If you’re zerg, the escaped drone wants to someday turn into a hatchery. If you’re terran or protoss, it might build anything. You may want a base to replace one that was denied by cannons, or production to go attack the enemy main that will be underdefended because of all the spending on cannons elsewhere. Escaping a worker is less important if you’re terran, first because terran can clear the cannons with a tank, second because terran can lift buildings to the outside.

If the cannons threaten to push closer, you may have to stop them. Zerg can commonly stop encroachment by building 1 sunken as close to the cannons as possible while out of range. Only make more than 1 if absolutely necessary. Protoss may want to add 1 cannon for the same reason, but the forge is an extra expense so it’s not as appealing. Terran needs a tank. An unsieged tank can prevent new cannons from warping in ever closer (it does need micro), and of course once siege finishes the cannons become fodder.

If the cannons deny something vital, you have to replace it. If you can’t mine enough because your main mineral line is under attack, expand. If a critical building is under attack, you may want to start a replacement before it dies. Terran should lift buildings that need to be saved or that can’t be used where they are (e.g. marines spawn in cannon range).

Those are the overall reactions. You have to get micro reactions right too. Don’t try to mine a mineral patch that is in cannon range; do mine any patches that are out of range. Don’t try to build a building, or land a floating building, in cannon range.

3. Restore your freedom. Don’t throw units away against the cannons; build up until you can take them out. This is the most basic thing, and yet most bots do it wrong, including Steamhammer. Terran only needs a tank and siege mode. Protoss wants dragoons, and if the number of cannons is huge, a reaver. Zerg prefers hydralisks. Ideally, attack containing cannons from both sides at once, including forces you’ve built up outside the containment. (Though as mentioned, the outside forces might want to hit the enemy main first.)

If you’re surviving well enough but you can’t afford to break the cannons (there are too many or the enemy reinforced them with an army), bypass them. Protoss should make a robo and shuttle. Zerg can go air or drop, depending on the situation—drop may be needed if you never got a drone out.

Steamhammer already has reactions to pull drones and to get an early pool (canceling stuff if necessary). It needs defensive fixes to prevent throwing away zerglings when the cannons are too strong. On my list for soon-ish are the encroachment-stopping sunken when needed, escaping a drone to make a hidden base, and mining and building only where safe. With those changes, Steamhammer should be resilient in the face of unexpected cannon rushes, at least until the next and stronger wave of cannon rush bots.

Long post, but I’m sure I know more than I remembered to write. What critical points did I forget or not know about?

Update: I reformatted the post and added a couple small bits.

Overpool village

Today I learned that Overpool is the name of a village in England. It raises a question: What opening can I design that it would make sense to name Liverpool?

Also today: More what X learned.

Randomhammer-ZurZurZur game with vulture-wraith opening

Randomhammer terran played its first public game with the vulture-wraith opening against zerg ZurZurZur. As I have mentioned, I wrote vulture-wraith originally as an extra test of Steamhammer’s anti-factory zerg opening. I found that the vultures and wraiths bring terror to unprepared zergs, so I made it a permanent part of the terran arsenal.

ZurZurZur, it turned out, was not prepared at all. It could not get a sunken colony up, and it did not get hydralisks into the fight until its natural was destroyed. By then it had lost all overlords so it could not reinforce and the hydras were quickly defeated. I can see how Tscmoo terran does so well with a similar strategy.

ZurZurZur loses its natural

I’m working on zerg stuff now for the upcoming tournaments, but I have a note to revisit this opening. It shows its legacy as a test opening; the execution and followup could be much stronger.

Next: A latent bug.

Hao Pan’s bunker rush

Hao Pan has started to play a cheese opening: Barracks in the center of the map at 6 supply, followed by a bunker at the enemy base, usually near the entrance. Many bots seem unready for the trick and react poorly. Krasi0 has been losing games. Bereaver stopped the bunker with skillful probe micro, but then forgot to make gateway units and suffered for it.

If the bunker fails, then Hao Pan’s marines will scatter and try to lure the enemy units all over the map like the Pied Piper. Most bots fall for it, including Steamhammer and forks. The game Hao Pan-Antiga is entertaining to the end.

LetaBot used to play a similar opening, though not with the strong basics of an Iron fork. There are still new cheeses to try, and old ones to improve on, and every time somebody does it, they catch unsuspecting victims. I have some cheesy ideas in mind; maybe I’ll get one ready in time for AIIDE.

Steamhammer finally tries its AntiFactory opening

Steamhammer-Iron is the first game in which Steamhammer played its AntiFactory opening, which counters Iron’s vulture runby skill (as well as other stuff that opponents could try with a mech opening, and some opponents do try). If Steamhammer started with no history, it would counter Iron on the second game. In fact it started with all its past game records on SSCAIT since version 1.4, so it thought AntiFactory was just another opening to explore, more important than the average opening because it counters the predicted enemy plan, but still just another opening and not worth special attention. Since it lost, it probably won’t try the opening again for a while (though there is a lot of randomness in the decision).

If you’re familiar other Steamhammer-Iron games, like that one, you’ll notice that in this game the AntiFactory opening stops Iron’s early vulture pressure more or less neatly and gets mutalisks in time to break up the next attack, the followup that adds marines and 1 tank. Then Steamhammer starts to flounder. The mutalisks neither defend efficiently nor attack the enemy base efficiently, and zerg desperately wants a 3rd base and sends drone after drone to die. Still, it was a tough fight and Iron only gradually took the upper hand. With this opening, Steamhammer has a moderate chance to beat Iron.

Steamhammer needs more skills to beat Iron regularly.

  • Place the initial sunken correctly. It makes a surprisingly big difference.
  • Don’t send drones directly into enemy forces. If you can’t expand safely, make a macro hatchery in your base instead.
  • Once another base is up, defend it. Steamhammer tends to lose all the drones there.
  • Play more incisively with the mutalisks. Don’t hesitate in front of defenses, immediately switch to another target. Be more eager to pick off tanks and less willing to chase fleeing vultures and SCVs.

I think those 4 skills would be enough to win most games against Iron, and only 1 of them is a complex skill. Likely even 2 of them, any 2, would put the win rate over 50%. Tilt the game a tiny bit, and it rolls your way over time. More skills would help more. For example:

  • Don’t lose overlords like an idiot from Idiot City, even if you are one. Steamhammer regularly flies into turrets.
  • When it’s time to expand, coordinate actions: Clear any blocking spider mine, push attackers away, if necessary escort the drone to the expansion site.
  • Use scourge properly.
  • Clear spider mines systematically. Steamhammer has the infrastructure to track spider mines that it has seen once, but doesn’t use it; units ignore mines that are not detected at that moment.

Am I going to actually work on any of these skills soon? Maybe. Overlord safety is high on my list, because it is a critical weakness in all matchups. For the more complex skills, I am waiting for the revamp of squad structure, which won’t start for months yet. Priorities are hard.

Next: Priorities in light of the AIST competition.

6 pool speed opening build

More delays for the burrow post. I have a busy weekend.

For some reason, I’ve been working on openings a lot for this version. Looking at Microwave’s openings, I noticed “5Pool Zergling Hell”, which researches speed for the zerglings after the second hatchery. That is very late zergling speed, and it didn’t seem to fit with the rush build. That may be why Microwave doesn’t use it; by the time speed finishes, the game is probably already won or lost. But it gave me an idea.

This morning I coded up a 6 pool speed opening. By using the extra drone on an extractor, the build can produce 3 zerglings before hitting the supply limit, just like 5 pool, and ends up with the same drone count. 5 pool gets the zerglings a little faster and also can start the second hatchery sooner because it spends less, but zergling speed is powerful and (I reason) should make up the difference. 6 pool is a little slower, but it’s still a fast rush.

During testing, I noticed that Steamhammer’s 5 pool opening was optimized for 3- and 4-player maps, an unfortunate choice since it is played most often on 2 player maps. The difference is the income produced by the scouting drone, which is not needed on a 2-player map. So I also coded up 5PoolHard2Player as a separate build, and configured it to be chosen over 5PoolHard on 2-player maps. The rush becomes a little bit meaner.

6 pool usually beats 5 pool head to head; the extra drone is used up, so the advantage is zergling speed. 6 pool puts up a surprisingly tough fight against 9-9 gate before losing (as it should, since 9 pool loses too), and it tends to beat the 8 barracks bunker opening that Steamhammer terran relies on to defend fast rushes. The rush is slower but need not do as much damage to succeed, because the extractor and zergling speed make it easier to transition to the middle game. Overall, I conclude that 6 pool speed is about as dangerous as 5 pool, and it poses a different challenge to opponents so it is worth having.

All the rush openings should become stronger when I fix the bug in the building manager which causes unnecessary worker movement before starting a building. It’s on my list to fix soon.

developing an anti-vulture opening for Steamhammer

I decided I was tired of seeing Steamhammer lose helplessly to Iron’s vulture runby and Tscmoo’s factory openings. Terran can start with vultures and force zerg to defend: Zerglings quickly become useless, drones are at risk, and terran can run by defenses into the main as Iron does. Steamhammer’s strategy boss understands that a sunken is needed at the front, and has a vague idea that hydralisks may be useful if the book line happens to end, but in the end it doesn’t defend adequately. Then terran can follow up with more factory units or with wraiths, and zerg has to be ready for a range of possibilities. Against Steamhammer, Tscmoo likes to follow up with goliaths, which is effective against Steamhammer’s mutalisk openings. Too many crushing losses.

Zerg has a standard way to defend: Place a sunken at the front as a vulture obstacle and keep a modest number of unupgraded hydralisks in a defensive position. The hydras are general purpose and can fight off vulture runbys, wraith harassment, small drops—all the natural followups. Zerg then continues to mutalisks as usual. The mutas are delayed, but terran is playing a slow strategy so it’s OK.

Today I set about developing an “AntiFactory” opening that implements the standard defense. I decided on development tests against Iron to see whether the runby defense works. In the very first test, when the opening timings were still all screwy, Steamhammer put up a persistent defense and didn’t lose until well into the middlegame. An improvement already, good. I made a few fixes and tried again. Steamhammer held the early aggression cleanly and fought a long level game until Iron finally mined out and collapsed.

I did not expect that! Steamhammer lost drones by the barrel and miscontrolled scourge and chased 1 SCV with 3 ultralisks, all its usual mistakes, but Iron struggled too and could neither stop zerg from expanding nor keep a fourth base up. I guess Iron depends heavily on the success of the early vulture runby.

Well, one win does not make a champion. We’ll see how it goes as I polish the opening. It’s just that the test game was so long that by the time I finished watching it, I had forgotten what needed fixing in the opening....

When the opening is ready, will the opponent model be able to select it when it should? I think the answer is no. I think I will have to extend the plan recognizer to recognize early vulture plans. Then Steamhammer should be able to counter the vultures in the second game, and ideally cope with the followup. It would be nice if Steamhammer could get back into the learning war against Tscmoo terran, and come out on top this time.

AntiFactory branches fairly late from related openings. When the opening tree is available, Steamhammer should be able to recognize the vulture plan during the game and choose the right build on the fly, more like a human player. It might need some scouting improvements first, though.

Next: The new bots GuiBot and WillyT.

Steamhammer will get a tree of openings

I have a simple idea that will both make it easy to restructure Steamhammer’s openings as a tree of opening build orders, and at the same time make the opening lines shorter and easier to understand. There are 2 parts.

Part one: Add a touch of new syntax. If the first item in an opening build order is the name of another opening, then substitute in the other opening’s build in its place. This applies recursively, of course.

For example, I could then recode Steamhammer’s 12 hatch openings to factor out the 12 hatch part. These 3 openings

"ZvZ_12HatchExpo" : { "Race" : "Zerg", "OpeningBuildOrder" : ["4 x drone", "overlord", "4 x drone", "go scout once around", "hatchery", "spawning pool", "extractor", "3 x drone", "4 x zergling", "Lair", "drone", "creep colony @ natural", "metabolic boost", "2 x zergling", "spire", "9 x zergling"] },

"ZvT_2HatchMuta" : { "Race" : "Zerg", "OpeningBuildOrder" : ["4 x drone", "overlord", "4 x drone", "go scout once around", "hatchery", "spawning pool", "extractor", "4 x drone", "3 x zergling", "Lair", "drone", "metabolic boost", "2 x drone", "spire", "3 x drone", "hatchery", "drone", "extractor", "2 x overlord", "12 x mutalisk", "hydralisk den", "5 x drone"] },

"2HatchLurker" : { "Race" : "Zerg", "OpeningBuildOrder" : ["4 x drone", "overlord", "4 x drone", "go scout once around", "hatchery", "spawning pool", "extractor", "go gas until 1075", "3 x drone", "3 x zergling", "Lair", "2 x drone", "metabolic boost", "hydralisk den", "extractor", "drone", "lurker aspect", "drone", "2 x zergling", "5 x hydralisk", "overlord", "5 x lurker", "drone", "hatchery", "3 x zergling"] },

could become these 5 openings

"12Hatch" : { "Race" : "Zerg", "OpeningBuildOrder" : ["4 x drone", "overlord", "4 x drone", "go scout once around", "hatchery", "spawning pool", "extractor", "3 x drone"] },

"ZvZ_12HatchExpo" : { "Race" : "Zerg", "OpeningBuildOrder" : ["12Hatch", "4 x zergling", "Lair", "drone", "creep colony @ natural", "metabolic boost", "2 x zergling", "spire", "9 x zergling"] },

"12HatchTech" : { "Race" : "Zerg", "OpeningBuildOrder" : ["12Hatch", "drone", "3 x zergling", "Lair", "drone", "metabolic boost"] },

"ZvT_2HatchMuta" : { "Race" : "Zerg", "OpeningBuildOrder" : ["12HatchTech", "2 x drone", "spire", "3 x drone", "hatchery", "drone", "extractor", "2 x overlord", "12 x mutalisk", "hydralisk den", "5 x drone"] },

"2HatchLurker" : { "Race" : "Zerg", "OpeningBuildOrder" : ["12HatchTech", "go gas until 1075", "hydralisk den", "extractor", "drone", "lurker aspect", "drone", "2 x zergling", "5 x hydralisk", "overlord", "5 x lurker", "drone", "hatchery", "3 x zergling"] },

I think of it as stems plus branches. Currently, you have to repeat the opening stems in every opening. Doing it the new way, the stems will be factored out and only written once each. It’s shorter and could prevent mistakes.

If you read closely, you’ll see that one detail of the original 3 openings is lost: The ZvZ opening scouts earlier. After recoding, all openings scout at the same timing. I want to change scout timing to be decided by the opponent model rather than by the opening book, removing the decision from the opening altogether. Also the number of drones made in the lurker opening is changed in this version; it’s not quite the same opening, though it’s close. When I do it for real, I will probably recode the openings differently than in this example.

One other detail is changed in an unimportant way. The 2 hatch lurker opening limits how much gas it collects, because once it has its initial set of lurkers, it wants to make drones and hatcheries to transition into a longer game. The original version specifies "go gas until 1075" right after the extractor is started, while the stem-and-branch version gives it after the opening stem. The change doesn’t affect how the opening plays out in any way.

I’m also thinking of factoring the openings into 3 subsections, one for each race. Then you don’t have to repeatedly specify the race. Instead of

"2HatchLurker" : { "Race" : "Zerg", "OpeningBuildOrder" : ["12HatchTech", "go gas until 1075", "hydralisk den", "extractor", "drone", "lurker aspect", "drone", "2 x zergling", "5 x hydralisk", "overlord", "5 x lurker", "drone", "hatchery", "3 x zergling"] },

it would become

"2HatchLurker" : { "OpeningBuildOrder" : ["12HatchTech", "go gas until 1075", "hydralisk den", "extractor", "drone", "lurker aspect", "drone", "2 x zergling", "5 x hydralisk", "overlord", "5 x lurker", "drone", "hatchery", "3 x zergling"] },

I can’t reduce it to a bare list until I change how terran and protoss openings work. They specify an opening group that says what unit mix to build in the middle game. Someday, they’ll have their own strategy boss that figures that out for them. Though I can think of other reasons to add tags to opening lines.

Part two: Interpret the stems and branches as a tree. Why allow opening names only in the first item of the build order? Because then you get a tree of openings.

Here’s how Steamhammer will make opening decisions. There will be a bunch of initial opening stems, 4 pool, 5 pool, 9 pool, and so on up through 3 hatch before pool. Steamhammer can choose an opening stem first, and go from there. Alternately, it can pick any opening it wants, just as it does now, and backtrack to the stem as a starting point. Anyway, at first it plays only the stem of the opening, then it is time for another decision: It can follow any of the opening lines branching from that stem, or it can stop following any opening and let the strategy boss take over.

Suppose it starts off choosing 2 hatch lurker. First it plays out the 12 hatch opening stem, then it thinks: “I found out that my random opponent is terran and not zerg, so I’ll continue down my original path.” It plays from there, treating the 12 hatch tech branch as the stem of an opening subtree. At the end of the 12 hatch tech branch, it thinks again: “I see an early factory, so lurkers might be bad. Better follow the mutalisk branch.” (I think the best reaction to an early factory is to get a hydralisk den and a few hydras for defense against vultures and/or wraiths, then continue into mutalisks. Steamhammer won’t be that smart at first.)

Or it reaches the end of the 12 hatch opening stem, then “Uh oh! Marines already!” It can bail out immediately instead of following any branch, and let the strategy boss take over and try to survive. Whatever opening line the bot finished on will be recorded in the data for the opponent model. Every opening line, stem or branch, can be treated identically, except that some of them have further branches and some don’t. In effect, at the end of each line is an implicit branch “now let the strategy boss do its job,” and that branch can be chosen like any other. The idea of treating every opening line identically is key; it gives the learning algorithms flat data that is easy to digest.

Using scouting information at each decision point will make Steamhammer’s openings much more reactive. Making decisions later, when more information is available, means the decisions will be better. (Project management works the same way!)

I’ll implement this in the 1.4.x series. It won’t be in 1.4.1 or 1.4.2, but it might be the version immediately after. The idea is simple and it provides necessary flexibility that Steamhammer has always missed. At first, only the zerg strategy boss will have the smarts to make decisions between branches of the opening tree, though. Terran and protoss will have to wait until they have more software infrastructure.

Some time in the future I’ll add an abstraction layer to openings, and cleanly distinguish between specific opening build orders and general opening strategies. Next: Abstract opening strategies.

testing 12 hatchery in ZvZ

Today I tested a 12 hatchery in main opening for ZvZ. 12 hatch gets zerglings late, and it is risky against 9 pool openings, which are common in both human and bot play. Steamhammer in the past (after version 0.2 from 2016) rarely plays even the faster 12 spawning pool, because its poor defensive skills leave it vulnerable to normal play. I only added a 12 hatchery opening for ZvZ in version 1.4, to be played when the opponent model predicts that the opponent will also open slowly. Otherwise it seemed too risky.

The hatchery on 12 lets the player get more drones than any other opening that is playable in ZvZ. I realized that you can make a sunken colony and still end up with 11 drones, a strong count for ZvZ. So I made a 12 hatchery in main opening with a creep colony timed to finish a little before the spawning pool finishes (a deliberate production delay would make it more efficient). The sunken colony gives it a chance to survive early aggression despite poor drone defense skills. It uses the 2 hatcheries to make many zerglings, threatening any 1 hatchery opening, and at the same time techs to mutalisks fairly quickly, threatening zergling openings.

How did it work out? I tested with self-play versus different openings.

I started with Steamhammer’s 9 pool speed opening, which builds up to 3 hatcheries as it gets the money, going all-in on zerglings. Would the 12 hatchery survive? On 2 player maps, the 9 pool zerglings could arrive too early and win. On 3 player maps, the 12 hatchery seemed risky. On 4 player maps, the 12 hatchery usually won: It survived the early attack, matched zergling numbers later, and won with mutalisks. The plan worked.

It also got a plus score versus fast mutalisk openings like overgas 9 pool and 11 gas 10 pool. The 12 hatchery could not catch up in mutalisks and struggled to defend in the air, but still won the majority of games with mass zerglings. The one hatchery openings could not keep up in zergling count. The plan worked here too.

I didn’t bother to test against in-between openings like 9 hatchery, or overhatch, or the various overpool openings. The 12 hatch survived more extreme openings, and it has a superior economy to middle-of-the-road openings, so it should be competitive. I will try a few tests against other opponents, to see how it stands up against bots with different skills.

I already configured Steamhammer to play the 12 hatchery in main opening, on 4 player maps only, at a fairly high rate. I predict it will help. I also configured it for all maps as an alternative to the 12 hatch at natural opening when the opponent model says that it is playable.

I want Steamhammer to learn to select its own openings not only to suit the opponent, but to suit the maps. Next: Ideas for adapting to specific maps.

optimizing one opening build

Yesterday I revised the ZvP_10Hatch opening. It was originally designed to counter 2 gate zealot rushes, and now (with the opponent model) it is used to counter expected heavy rushes by terran and random opponents too. I renamed it Over10Hatch. The basic build order is extractor trick for a 10th drone, overlord, hatchery, and a couple of sunkens to help hold off the mass zealot pressure so it’s safe to make drones and tech.

The changes are small. If you watch casually, you might not notice. The extractor trick is now before the overlord, not after, a careless oversight in the original. The first sunken is delayed slightly, and the second sunken needed to deter masses of zealots is delayed longer. The number of early zerglings is cut back to just the number needed in the worst case. The early game plays out much as before, it only looks as though Steamhammer might be cutting it a little close. (CherryPi’s versus-protoss opening often gives a similar impression. The team knows what it is doing.) You could miss that there is a slightly higher drone count.

A pro would cut it closer, but a pro has good judgment. The way the rest of the game plays out looks different. In the old build, Steamhammer would often narrowly hold the zealots, get lurkers just in time to survive, and use the opponent’s lack of tech to slowly push for victory. With the extra income from the new build, Steamhammer holds the zealot pressure easily, safely gets lurkers, and quickly smashes the protoss with a mass of lurkers and lings. The turnaround in the game looks completely different. The effect versus no-academy marine rushes like UAlbertaBot’s is similar.

I thought it was a good lesson in the importance of an efficient build.

the donated openings from Antiga

Here’s what I found out about Antiga’s donated openings. (Thanks again to Iruian, by the way.) This post is only about the openings themselves. Also donated are weights, how often to play each opening in each matchup, which I’ll consider separately. My plan is to distribute the donated file along with Steamhammer’s source, so that whoever wants to can easily borrow the openings and weights. The openings are good, so I’ll also put most of them directly into Steamhammer’s regular configuration; Randomhammer will play them when it rolls protoss.

Going by names, Antiga’s openings are a superset of Steamhammer’s. But 3 of the openings with the same names are different, so it’s a little confusing.

identical openings

  • 1ZealotCore
  • DTRush
  • DTDrop
  • CorsairDT (weak because Steamhammer sucks with corsairs)
  • 12Nexus
  • 13Nexus

openings new in Antiga

These are good openings, so at the moment I’m thinking I’ll throw them into Steamhammer’s config for active use. The weights are a separate question.

  • 9-10Gate
  • NoZealotCore
  • 10-15GateGoon
  • 2ZealotCore
  • 2GatewayGoonExpo
  • Nexusfirst5zealotExpo

openings that are shared but different

I tested the shared openings by playing them against each other head-to-head. I’ll call it Steamhammer versus Antiga, though both sides were running identical Steamhammer code. I didn’t pay attention to the results of the games, which varied depending on how battles happened to come out. I paid attention to macro: Who had more income, who produced units more efficiently, who was able to expand sooner.

9-9 gate The 2 openings proceeded in lockstep until Antiga went out of book. Then Steamhammer’s beautifully optimized UAlbertaBot zealot rush quickly pulled ahead. It evened out somewhat after Steamhammer also went out of book, but not entirely.

10-12 gate Steamhammer’s 10-12 gate opening is not as highly optimized. Again the openings were identical until Antiga went out of book. Steamhammer pulled ahead, but not dangerously. I don’t see any big difference in strength between the openings, only a small advantage to Steamhammer’s existing opening.

ForgeExpand The openings are the same, except that Antiga adds a third photon cannon at the end of the opening. It barely delays the early zealots and dragoons, so I judge it an improvement: Safer and practically as aggressive. I will switch Steamhammer’s opening to this version.

optimizing Steamhammer’s openings

Iruian donated some protoss openings with weights as used in the bot Antiga. I will distribute them with Steamhammer, but I’m still pondering exactly how. The openings are supposed to be straight from Liquipedia, and the ensemble is claimed 50 to 100 elo stronger than Steamhammer’s default protoss openings. I don’t have any reason to doubt it, but I’m still in the process of checking the openings myself.

Unfortunately, there are reasons not to take openings straight out of Liquipedia without testing. Most of Steamhammer’s provided openings are modified from Liquipedia versions, and sometimes the changes are major. (Some were taken from other sources, and a few were developed from scratch, starting with no more than the opening stem and a plan.)

Sometimes Liquipedia is unhelpful, if not outright wrong. I think the 12 pool lurker build on this page is a prime example. It says you should adhere to the build strictly. But if you build everything that the build order calls for, then lurkers are severely delayed, and the build order makes no sense (at least to me); use a 12 hatch build instead. If you minimize the build to get lurkers as fast as possible, then you end up with 4 or more larvas for a long stretch after the second hatchery finishes, meaning that there was no reason to get the second hatchery so soon; you should have stuck with a single hatchery build. Presumably a pro can weigh the situation and decide what extra stuff is good to make, but Steamhammer doesn’t have that skill. So I found the Liquipedia build order unhelpful.

Often Steamhammer plays poorly in the middle game, and the weak play can be worked around or delayed by extending the opening. This is the main reason to deviate from standard builds: Alter the opening so that Steamhammer plays it better.

BOSS is weak, which causes terran and protoss to play poorly after the opening. BOSS tends to build too many production buildings—I often see 6 or 7 gateways on a one-base income that can support 4 gateways, which is wasteful. BOSS also likes to bunch the production of similar things, not keeping the nexus and gateways busy at the same time, but rather “probe probe probe probe zealot zealot zealot zealot”, where first the nexus is busy, then the nexus goes idle and the gateways become busy. It’s crazy inefficient.

That is why Steamhammer’s 9-9Gate opening is so long and detailed. If it ended early like the Liquipedia build, then BOSS would take over sooner and build inefficiently, and the bot would fall behind in probe count and zealot count for the rest of the game. I know this for sure, because I’ve run the different variants head-to-head. Dave Churchill optimized the 9-9 gate opening already for UAlbertaBot, and he did an excellent job. I optimized the 10-12 gate opening myself in a similar way and did not do it as thoroughly; it has room for improvement.

Someday I’ll write a new macro system and drop BOSS, but not yet. I might be able to get to it this year....

Sometimes the middle game strategy decisions are silly. Terran and protoss are especially short on strategy smarts, but the zerg strategy boss also has many weaknesses. In one frustrating example, if the opening build makes a spire but doesn’t make the mutalisks, Steamhammer may decide that lurkers were a better idea after all, get no lair units for a long time, and lose. There are many ways for the strategy boss to misunderstand the strategy behind an opening, so that you have to write a long explicit build order. Some openings I have shortened after improving the strategy boss. Some openings have legacy endings that it might be good to remove.

Anyway, the bottom line is that Steamhammer is not strong enough to play Liquipedia opening builds uncritically. Some are fine, some will confuse the poor bot.

On the other hand, Steamhammer’s existing protoss openings leave a lot to be desired. They’re more a demonstration of what’s possible than a sound selection. It’s no surprise if Antiga’s openings are stronger.

Next: Looking at the donated openings.

Steamhammer’s ZvZ secret weapon revisited

As some people have noticed, Steamhammer’s “secret weapon” ZvZ opening, which when I first tested it scored overwhelmingly against all opponents including Steamhammer itself, is simply overhatch.

Overhatch means making up to 9 drones, spawning an overlord, and then starting a hatchery while still on 9 supply. Steamhammer’s version is overhatch 9 pool 9 gas (with drones in between buildings), parallel to its faster 9 hatch 9 pool 9 gas build. The overlord lets zerg get in a couple extra drones, so that when the spawning pool finishes the bot has 10 drones and can immediately spawn 8 zerglings. The timing is fast enough to hold off 5 pool except on 2-player maps. It puts the player in a reasonable economic position (by ZvZ standards), but also commits to zergling-heavy play because the lair will be later.

Overhatch is a rare opening and it is not written up on Liquipedia, and that is for a good reason: It is dominated by 10 hatch. In a ZvZ 10 hatch opening, you go up to 9 drones, spawn an overlord, and do the extractor trick to get a 10th drone. The 10th drone can mine for a while before minerals are available to morph the hatchery, so 10 hatch is always ahead of overhatch in minerals. There is no disadvantage to 10 hatch; it can only be better than overhatch (though only by a little). Steamhammer plays overhatch because it still does not work around the extractor bug (I have more important bugs to fix first).

results

The opening is strong against bots. Results on the SSCAIT server have been good, though less convincing than my original tests.

Steamhammer has lost several games by failing to build an extractor when it came up in the build order. It is a bug that I didn’t see in testing and haven’t solved. For some reason it hits overhatch much more often than other builds.

Steamhammer has also lost a game to Microwave’s 9 pool and another to Dawid Loranc’s 5 pool. Steamhammer’s zerglings were in time to defend with correct play, but Steamhammer pulled its drones too soon and lost some. It’s a severe defensive error. At some point I will teach Steamhammer how to defend with a drill, and then these losses won’t happen.

Steamhammer has also lost occasional games to strong opponents like Killerbot by Marian Devecka due to tactical errors. It does win most, though, even against opponents like Arrakhammer that know about the overhatch opening and are prepared to meet it.

counters

Like every opening, overhatch can be countered provided you know it is coming: You can safely open 12 hatch to end up equal in hatcheries, ahead in economy, and behind in nothing important. So Steamhammer doesn’t play overhatch every game. Steamhammer is set to play overhatch in half of games. Its other openings counter 12 hatch, which is a slow and risky opening in ZvZ. The random openings ensure that no opponent build can give a sure win; opponents have to either play better or get lucky.

If you want to counter overhatch safely, Liquipedia suggests that 12 pool gives a slight advantage. 12 pool is a safe ZvZ opening if played well. But I learned by experience that it is tough to teach a bot to play it well.

other matchups

The classic use of 10 hatch is in ZvP, where in old days it was considered a strong counter to 2 gate zealot play. 2 gate play is popular with protoss bots, so I tried overhatch against protoss too. It seems effective. I think it is doing better than overpool, which was already successful.

In ZvT, Steamhammer up through the current version has always played either zergling openings with heavy early pressure, or mutalisk openings with minimal zerglings and a heavy air attack. Thinking it through again after working on surviving early terran attacks, I decided to add a compromise opening for the next version. I picked an overhatch opening with early zergling pressure followed by a later, lighter air attack, at the cost of a weaker economy in the long run. I think it is objectively worse, but other zerg bots have been successful with similar approaches and it may work well against bots. It’s an idea that should be tried.

Tomorrow: Arrakhammer’s attempt to counter overhatch

a new secret weapon in ZvZ

Yesterday I watched a pro ZvZ game from 2010 where the winner played an opening I had not seen before. “Hmm, does that have good timings against overpool?” I thought. It seems to be a rare opening and is not documented on Liquipedia, but I coded up a version and tested it out. The scores are Steamhammer 1.2.2 set to play one fixed opening, versus each opponent.

victimscoreversion
Ailien13-2uploaded 4 April
Killerbot14-1SSCAIT 2016
Microwave14-10.15, uploaded 5 April
Steamhammer11-41.2.2, latest release with 11 ZvZ openings
Zia15-0uploaded 7 September

Holy Saint Isidore, Batman! Bots are not prepared for this!

Killerbot scored 1 win when Steamhammer made a tactical mistake of a kind that I intend to fix in the upcoming version. Microwave was able to exploit a risk inherent to the opening—once. Zia tried its builds one after another and lost with all of them. Ailien’s machine learning came the closest to finding an answer; it tried different tacks, and a few of the games were fierce. By the end of the match it seemed to be grasping at straws: Do hydras work? No! Do lurkers work? No! Every fixed opening has counterbuilds, and a human player who knew what was coming would find it easy to beat. It is possible that the counterbuilds are outside Ailien’s gamut, or take over 15 games to find. The release version of Steamhammer itself put up the strongest fight but was forced down.

Of course Steamhammer does not play fixed openings outside of tests like this. I think that adding the new opening to its repertoire is likely to make Steamhammer impervious for a long time to machine learning attacks on its openings.

I’ll be holding my secret weapon in reserve until version 1.2.3 comes out. Everything will be published then, but I also enjoy springing surprises. This will change the meta, and I would like to be 2 steps ahead.

recreating the Newbie Zergrush strategies

Newbie Zergrush has vanished like the morning dew. If you want to test against its nonstandard strategies and missed the boat, I reconstructed two of them. You can configure Steamhammer 1.0 to play these openings. The experience is not 100% authentic, but it’s close. I made these by watching the build orders, not by copying the original configuration, so there may be slight differences. Also there should be code differences, so the way the openings play out should be a little different. It’s still a good test of whether your bot survives these aggressive strategies.

Newbie Zergrush played 7 pool 12 hatch versus zerg and 8 hatch 7 pool versus terran and, at least at first, protoss. It also had a mass sunken build which I did not try to recreate.

    "7Pool12Hatch"  : { "Race" : "Zerg", "OpeningBuildOrder" : ["drone", "drone", "drone", "spawning pool", "go scout location", "drone", "overlord", "zergling", "zergling", "zergling", "zergling", "zergling", "hatchery @ min only", "zergling", "zergling", "zergling"]},
    "8Hatch7Pool"   : { "Race" : "Zerg", "OpeningBuildOrder" : ["drone", "drone", "drone", "drone", "hatchery @ min only", "spawning pool", "go scout location", "drone", "overlord", "zergling", "zergling", "zergling"]},

I cheated and cut these down to keep the post short. At the end of each build order, use the power of copy-paste to extend the line of , "zergling" out a long distance. That’s because the strategy manager doesn’t know these openings, so it will start an unhelpful default strategy as soon as the opening book ends.

Get the Steamhammer 1.0 binary release from from my page or from SSCAIT. I wrote documentation for the config file. Add the two opening book lines above (with the extra zerglings) to the “Strategy” subsection (be careful about commas, JSON files are unforgiving). Then configure Steamhammer to play the opening against your bot. For example, if you’re testing a terran bot, one way is to rip out the original ZvT setting and replace it with "ZvT": "8Hatch7Pool",.

the end of the rushbots: rushes and how to defeat them

Today I have a guest post by none other than Martin Rooijackers, on fast rush strategies and how to beat them. The rest of this post is written by Martin Rooijackers, author of terran bot LetaBot.


This Saturday (28 January) will be the last time that my bot will go for a rush strategy. The reason for this is simple, rush strategies will stop working against almost all the top bots. Already most top bots can hold just about anything you can throw at them off 1 base. There are a few holes in their play that I managed to exploit this SSCAI, but after those are patched, any bot will be forced to expand in order to win a game versus a top bot. In the case of my own bot: even with the suboptimal building placement, it can already hold zergling rushes more than 50% of the time. With that improved, Zerg bots will (almost) always lose if they open spawning pool first.

The only use that rush strategies would have after that would be to defeat a bot that rushes to a resource depot (14 CC, 14 Nexus and 3 hatch before pool come to mind). But you can play slightly from behind and still win with better tactics. So I prefer to go that route.

Anyway, here are the rush builds that are still effective, along with some information as to how to stop them

Worker rush

Bots that used it: Stone (predecessor to Iron bot), LetaBot. Any bot that lets its scouting unit attack the enemy workers.

The earliest rush you can do. You take your worker units and let them attack the enemy base. In the early stages of Brood War AI competitions, it sometimes happened that the scouting worker would attack the workers at the mineral line. Since some bots didn’t have any worker defence code, the scouting worker unit would simply destroy the entire work force of the opponent.

After a while, most bots would pull a worker off the mineral line and send it to attack the scouting worker. The problem with that solution was that the opponent could send more than just the scouting worker to attack the opponent.

An example of this happening in a human vs human game is Idra vs AllAboutYou (in SC2).

The first bot to specialize in the worker rush was Stone by Igor Dimitrijevic. Besides the usual attack move and retreat to repair that LetaBot was capable of before in its worker rush, Stone also prioritized SCVs that were building buildings. It got 3rd place in the SSCAI 2015. However it did get defeated by LetaBot (who had a worker rush strategy in it since its very first tournament in CIG 2014).

In 2016, LetaBot used the same strategy to defeat several bots (BeeBot, XelnagaII, Iron Bot, Krasi0). Krasi0 has already improved its worker defence in its latest version.

There are many ways to stop it. The main key is to keep on building worker units no matter what. After all, with this your production of worker units will be at the same rate as your opponent, ensuring that you will always have numerical superiority with which you should be able to hold easily. Don’t rush for a tier 1 combat unit, that only plays into the hand of the one that worker rushes you.

Terran: Watch the LetaBot vs Stone video above. You simply pull back workers that are on low hp. Just follow the regular build order (9 supply, 11 barracks) and pump marines. You will hold it easily

Protoss: Just like terran, pull back worker units that are damaged. Build a pylon when you have 100 minerals, and a gateway when you have 150. You should have a zealot out before the opponent has a critical mass of worker units.

Zerg: Go for a spawning pool when you have 200 minerals, and build a zergling when you have 50 minerals. If you went for a 4 pool, cancel the pool and build 3 worker units immediately.

Bunker Rush:

Bots that used this strategy: LetaBot

The favorite strategy of Boxer.

LetaBot is known for doing this rush back in 2014. But in the case of LetaBot, it was the proxy 5 rax variant instead of the usual marine rush:

Proxy 5 Rax from Liquipedia

Krasi0 vs LetaBot (2014).

To stop it, you shouldn’t go for a fast expansion, since the bunker rush hard counters such a build order. Pull workers to destroy the enemy bunker. More specifically

Terran: Pull SCVs to destroy the enemy bunker and get a bunker of your own on your ramp.

Protoss: Photon cannons out-range bunkers, so get them up asap in case the opponent managed to finish its bunkers. See Bunker Rush (vs. Protoss) from Liquipedia.

Zerg: Zerg Counter to Bunker Rush from Liquipedia.

Barrack Barracks Supply (BBS)

Also known as a marine rush.

Bots that used this strategy: LetaBot, Tyr

Example, LetaBot vs IceBot in SSCAI 2014.

Liquipedia has more information on this one. See Barracks Barracks Supply.

How to counter it:

Terran: Pull SCVs to force the marines back and build a bunker on the ramp. Terran Counter to Barracks Barracks Supply on Liquipedia.

Protoss: Protoss Counter to Barracks Barracks Supply on Liquipedia.

Zerg: Zerg Counter to BBS on Liquipedia.

4 pool

Bots that use it: ZZZKbot, way too many other ones to list here.

A popular strategy where you try to get zerglings as fast as possible. Could be considered the “Hello World” of Brood War Bot programming.

Example, Iron bot vs ZZZKbot in the SSCAI 2016.

counters:

Terran: Terran Counter to 4 Pool from Liquipedia.

Protoss: either 2 gate zealot, or Forge Fast Expand with 2 cannons and probes to block the opening.

Zerg: open with 9 pool and build a sunken colony if needed.

Cannon rush

Bots that use this: Aiur, Jakub Trancik

Example game AIUR vs Bakuryu (human player).

How to stop:

Terran: Make sure to chase the scouting probe to catch any pylon building in the main base. If outside the main base, build a wall and repair it till tanks with siege mode are out.

Protoss: go for a zealot rush.

Zerg: Go for a spawning pool. Then sunken colony or mass zerglings.

Zealot rush

Bots that use it: WuliBot, Dave Churchill, several other protoss bots

Example game: LetaBot vs WuliBot (Ro8 game 2 SSCAI 2016).

counters:

Terran: Terran Counter to Early Protoss Pressure on Liquipedia.

Protoss: 3 Gate Speedzeal (vs. Protoss) on Liquipedia.

Zerg: An overpool is a safe zerg build vs protoss. See Overpool (vs. Protoss) on Liquipedia.

safe build orders

So, with proper scouting, a bot should be able to stop any rush build if it starts out with a safe build order. There are many choices, but my suggestions for each matchup:

TvT: 2 factory build
TvP: Siege expand with a wall
TvZ: 1 rax FE. Build barracks at 10 supply.

PvP: 2 gate. start out with a zealot before dragoon
PvT: 1 gate Core
PvZ: Forge Fast Expand with 2 cannons, or 2 gate zealot

ZvT: It is usually best to go 12 hatch, but if you expect a rush go for 9 pool and put on pressure to come back from behind if terran plays standard.
ZvP: Overpool.
ZvZ: 9 pool into 1 hatch spire.