archive by month
Skip to content

Steamhammer and the SSCAIT finals

The round robin phase of SSCAIT 2016 has just finished. Seconds ago, Matej Istenik beat OpprimoBot in the last remaining game. Did Steamhammer make it into the round of 16?

It was a nailbiter! Only fiction gives us closer decisions. As the end approached, Steamhammer and Zia were tied for 16-17th places, each with 1 game remaining to be played. One would be in and one out! As the last dozen or so games came up, Zia was scheduled to play MegaBot, and after 2 intervening games—just enough time to enjoy the tension—Steamhammer to play Tscmoo protoss.

Zia had beaten MegaBot in their previous game, and easily won again. In the previous Steamhammer-Tscmoo game, Tscmoo had opened forge expand; Steamhammer did not know how to adapt its build and lost. (That is why Steamhammer opens three hatch before pool against XIMP and ZerGreenBot.) Tscmoo is unpredictable.... I thought the odds were poor, but I knew anything was possible. This game Tscmoo opened 14 nexus and then gas before gateway, a crazy greedy opening, and went down like a house of cards. What a way to deflate expectations of an exciting decision!

Steamhammer and Zia finished in a tie for 16-17th places. I don’t know how tiebreaking will work. Their result against each other was (I’m sure you already guessed this) 1-1, so that doesn’t help. Maybe they’ll have a playoff game. Either way, I’ll enjoy watching the finals and I’m happy that my bot performed so well after such a short development time. Watch out for the next version!

Next: Some of the bugs that came up in the round robin phase.

win ruthlessly like LetaBot and ZZZKBot

One of the stories of SSCAIT 2016 is that LetaBot (playing under its author’s name, Martin Rooijackers) scored easy wins over certain tough opponents with SCV rushes. Classic LetaBot used to play bunker rushes and recent LetaBot versions still sometimes performed SCV-marine rushes, so the rush opening should not have been a total surprise. But it worked perfectly against Krasi0 and even against micro-virtuoso Iron. The losers tried hard to keep their own SCVs safe, lost too much mining time, and could not keep up.

I approve. That’s the way to do it. If you find a weakness, exploit it ruthlessly and don’t worry about whether people look down on you as a cheeser. In fact, that is ZZZKBot’s entire modus operandi, and ZZZKBot is doing well with it, departing from its traditional 4 pool often and effectively with opponent-specific builds. Ruthless wins are your opponent’s way of telling you what you need to fix, and that’s good for everybody.

LetaBot’s rush looked similar to the rush we used to see from Stone, before Stone evolved into Iron. LetaBot pulled back its damaged SCVs into loving mutual-repair couples before returning them to the fray. I rather wish Stone were still playing alongside Iron. Stone would constantly remind other bot authors of the importance of good worker micro—worker micro is difficult (and I sure haven’t gotten around to it in Steamhammer), but it’s key.

don’t lose that scout

Wow, it’s down to the wire on whether Steamhammer will make it into the final 16. Steamhammer has been scoring a little lower in the final third of the tournament, and as I write it is standing on the edge at rank 16. With 10 games left, I look at the opponents and expect 4 losses and 6 wins, probably not enough to hold rank 16.

But we don’t know until we know. In an unexpected loss to PeregrineBot (which it easily beat in their first game), Steamhammer suffered at least 2 different play bugs, including one caused by losing its initial scout before finding the enemy base. Gotta fix more bugs. Then it followed up with an unexpected win against Bereaver; the protoss had easily won the first game. Bereaver was careless with its early probe scout and lost it before zerglings spawned, and Steamhammer’s aggressive play caught it off guard. Without information on what zerg was doing, Bereaver did not make enough zealots to hold. Moral: That scout is important!

We’ll see what happens! Steamhammer plays sharply and is prone to upsets in both directions.

Steamhammer versus IceBot

Steamhammer defeated IceBot 2-0 in SSCAIT 2016, but the numbers are deceiving. In the first game, IceBot built its strongpoint defense with a bunker surrounded by turrets, Steamhammer became obsessed with the bunker but was barely able to attack it, and IceBot countered the mutalisks in good time with goliaths and valkyries. Steamhammer was falling behind, but took more bases. IceBot moved out with an unstoppable army and crushed the zerg natural and main; Steamhammer was still able to stop dropship harassment with its remaining army, but zerg was dead. Then IceBot crashed.

The only good news is that I taught Steamhammer 0.2 that dropships are critical targets and must be eliminated. IceBot’s drop attempts were shut down hard and only hurt terran. In every other way, IceBot played better.

The second game was exciting. IceBot again built its strongpoint defense and Steamhammer again became obsessed with the bunker. But for some reason IceBot did not raise the mutalisk defense flag, and instead kept pushing columns of marines out beyond turret range to die. Steamhammer took more bases, its mutalisk flock was growing, and it was upgrading air carapace. It even made some dents in the strongpoint, destroying the first bunker. IceBot also took two side bases, and Steamhammer did not scout them, much less attack. IceBot finally switched to goliaths and valkyries, but by then the mutalisks were so strong that they could fight on even terms. IceBot made its big tank push, but the push was defeated. Steamhammer had most of the map and IceBot could not expand any more, but terran tried to stay in the game with drops and vulture harassment and long distance mining. In the end IceBot mined out and Steamhammer was still going, the terran army wore away to nothing, and the strongpoint finally fell like the gate to a fortress. Good game.

Steamhammer showed a lot of weaknesses, but the key one was the obsession with that bunker. It turns out that there are multiple causes. One cause is that bunkers were given high priority as targets, so that mutalisks would attack an empty bunker surrounded by turrets and ignore the turrets and other enemies. I made a quick fix for that in the next version. Another cause has to do with the way squad orders are computed. It turns out that squad orders made based on early scouting tend to direct play for the rest of the game. I’m still thinking about that one; my first attempt to fix it is no good. A third cause is the way it calculates whether a bunker can be successfully attacked. SparCraft does not support bunkers, but bunkers can’t be ignored. Dave Churchill’s workaround was to pretend that a bunker is actually 5 marines with hitpoints pro-rated based on the bunker’s health! It’s an ingenious idea, but it’s also a poor approximation. The damage rate is wrong, the health is wrong, and the 5 imaginary marines can be shot down one by one. SparCraft will need some work.

At some point I’ll study SparCraft closely and improve it. It seems reasonably accurate, but it’s not all the way there. On the one hand, SparCraft doesn’t support every unit. On the other, SparCraft does seem to support medic healing and unit upgrades, but UAlbertaBot does not take advantage of the support. Well, one step at a time. It’s not a priority yet.

trying out ZZZKBot

What is it with ZZZKBot? In most SSCAIT games it has stayed with its traditional 4 pool, but it has also been playing a variety of other builds against some opponents. Against Steamhammer it played mass sunkens into spire, a build that seemed tailored to beat Steamhammer’s anti-rush opening, which Steamhammer had never publicly played before the tournament, but which could have been discovered by local testing.

I set up ZZZKBot locally and tried it out. The github version is out of date, so I took the SSCAIT version. Does it win against Steamhammer’s standard ZvZ 12 pool? No, it loses, but what is this build it’s playing? I hadn’t seen that on the stream. It opened 9 pool, more drones, second hatchery in main, late gas, lair, queen’s nest—it was walking slowly toward greater spire! Steamhammer beat it before it got that far, though. ZZZKBot wrote no data file; it was not learning.

What about Steamhammer’s anti-rush build, as it is playing in SSCAIT? ZZZKBot played the same slow march toward greater spire. The anti-rush build is weak against 9 pool, but the greater spire build is worse and Steamhammer still got mutas out first and won.

Does it depend on the map? I ran 3 games on the same map as in the SSCAIT game, Roadrunner, versus the anti-rush build, and ZZZKBot aimed for greater spire and lost each game. In one game it managed to get out a couple guardians before dying. ZZZKBot never repeated its anti-anti-rush build.

ZZZKBot also never wrote a data file. I suspect that it keeps some extra static data that the SSCAIT server doesn’t serve up, an optional configuration file with counter-builds for specific matchups. That would explain its varied and effective build orders.

the fast success of Steamhammer

SSCAIT 2016 is beyond the halfway point, and Steamhammer’s score ratio has been holding steady near 2:1, good enough to place it in the bottom half of the top 16. It will probably make it into the finals (no guarantee; some tough games are still ahead). Its rate of upsets suggests a 30% chance that it could win in the round of 16 and make it through to the round of 8. It is unlikely to get further than that.

I’ve seen a few people wonder how a brand-new bot could do so well. Steamhammer 0.2 has less than 3 weeks of my development effort in it. I can answer that!

1. Steamhammer builds on a strong foundation in UAlbertaBot. I changed the openings and the strategy followup, and fixed bad play where I had time to, but most of Steamhammer’s play comes straight from UAlbertaBot. Tactics are only slightly changed; micro has modestly improved targeting but is otherwise nearly identical.

2. I know the game and I’ve been following the bot scene for a long time. I was able to make choices that both fit within UAlbertaBot’s limitations and pose challenges to other bots. Knowledge is power. Most new bots play inefficient builds; Steamhammer builds inefficiently only to work around other problems.

3. Strong new bots usually show good results at first and then decline as other bots adapt. I’ve seen it before and I see it now with Steamhammer. The opening learning bots find the right openings to play; I played a test match versus Zia in which Steamhammer scored 1 1 1 1 1 0 0 0 0, switching from wins to losses when Zia hit on the right opening. The actively developed bots get fixes to any weaknesses that the new bot reveals; both Krasi0 and LetaBot have mentioned improvements to mutalisk defense.

Steamhammer plans

My goals and plans for Steamhammer development. What, I told you it was next, didn’t you believe me?

Start with the usual 3 levels of abstraction: Strategy, tactics, unit control. My eventual goal is to conquer the levels one after another with machine learning, starting at the top with strategy—it’s more fun that way. I think I have to tackle each level separately, because any learning method that can learn all levels at once will devour more data than I can feed it—it will be beyond my resources.

My vague plan for each level is to start with a hand-made approximation of good play and learn the differences between the approximation and actual good play. That’s also because it’s more fun that way. First, play will never be too awful, so it won’t be discouraging. Second, learning will be faster because there’s less to learn, which is important because I expect to have to relearn each model repeatedly. For example, every time the tactics change too much, the strategy model should relearn what strategy is good with this set of tactical skills.

One goal is to learn opponent models, at least at the strategy level. I’d love to learn models at each level. We’ll see if I get that far.

Another goal for the strategy level is to be capable of every opening. If an absurd build like 8 gas 14 pool is good against some weird opponent, I want Steamhammer to be able to figure that out, at least in principle. I want to be able to say: If Steamhammer played enough games, it could eventually figure it out, no matter how unusual. Humans can develop new builds, bots should do it too.

For the moment I’m working on infrastructure. I renamed UAlbertaBot’s MetaType data structure which represents “a thing to build/research/etc.” to MacroAct, since I like names I can understand. I added “command” actions to MacroAct, and so far have implemented commands for scouting and taking drones off gas (both of which affect macro—they are macro actions). You can now write these into build orders in the config file, which makes the build orders more powerful; the bot’s behavior is no longer hardcoded. (Dave Churchill was apparently planning something similar, since the original MetaType already had an unused “command” variant.) I’ll use the same system for communication from the strategy boss to the production manager.

After a few more commands, I’ll add positioning information to MacroAct, so that it can distinguish between an expansion hatchery and a macro hatchery, specify which base gets the static defense building, and stuff like that.

That covers the most vital missing skills. Then I’ll start on the strategy boss. Goals are versatility, good macro, fast adaptation, and the ability to recover from upsets, all of which Steamhammer 0.2 is weak at.

A first working version should be ready to release some time in January. Depending on how fast I can make progress, I would like to add one more feature before the release, random choice of openings. Learning bots quickly learn to exploit Steamhammer 0.2’s fixed openings, and that’s no good. I’ll start with fixed probabilities for each opening, specified in the config file. Since the strategy boss can adapt to the game situation, the opening build orders will be shorter than now. A random mix of aggressive openings and macro openings with different tech choices should be difficult for the learners to exploit, as long as Steamhammer can play all the openings well enough. It should also be more fun for humans to play against.

Then it will finally be machine learning time. I’ll decide whether to learn openings or strategic play (after the opening) as the next step. The first target of opening learning will not be “learn the best opening,” it will be “learn the best mix of openings.” The second will be to develop new openings, of course.

Along the way I’ll be fixing bugs, improving micro decisions, and whatever else seems essential. But since I plan to completely replace the tactics and micro code, I’d like to minimize the work I put in and only do the essential.

Steamhammer versus Killerbot and XIMP

I got my SSCAIT wish and saw the first Steamhammer versus Killerbot and Steamhammer versus XIMP games today.

Steamhammer versus Killerbot by Marian Devecka: Would my counter-build work? In my tests Steamhammer wins with it about half the time. Killerbot went with its +1 speed lings and Steamhammer opened 11 pool and held with its own slow lings while teching to lair. Timing is critical—12 pool is too slow on some maps! In this game Steamhammer managed to sneak in a drone kill while Killerbot’s lings were busy chasing the scouting drone (UAlbertaBot doesn’t do that natively, I had to improve the decision making). Steamhammer added 2 sunkens for protection while getting mutalisks—it still had only 1 hatchery, while Killerbot was headed for 3 hatcheries, and it is impossible to hold without static defense. Steamhammer’s first 3 mutalisks hatched and headed for the enemy base, and as soon as the flyers were safely out of range to intervene, Killerbot’s zerglings attacked! Steamhammer pulled drones to defend and lost every single drone, but the sunkens held and the base was left barren but secure for the moment. The 3 mutalisks killed all of Killerbot’s drones in return and then tore down the enemy zerg base with excruciating slowness—Steamhammer won a close game. Steamhammer-Killerbot games often go down to the wire like this in my testing; I’ve seen one side or the other win with only 1 or 2 buildings left bleeding onto the map. But without the special-purpose counter-build, Steamhammer loses every game; Killerbot is far superior in tactics and robustness.

Steamhammer versus XIMP by Tomas Vajda: Steamhammer opened with 3 hatcheries before pool, the only bot I’ve seen play this logical response to forge-expand. (Though I saw auxanic open unsoundly with 5 hatcheries before pool!) XIMP cannoned up for carriers, as always. I hadn’t tested this matchup, so I wasn’t sure what would happen. Steamhammer went hydras with +1 attack, and soon had enough to tear down the cannon wall (slightly before +1 finished, annoyingly), wipe out XIMP’s natural, and start on the main. That’s what I intended, and I’m pleased it worked. XIMP seemed about to fall, but suddenly the first carriers started to make a difference—they finally had enough interceptors. The hydras did not have critical mass to fight carriers and were cleared from the main. At this point, Steamhammer had 6 bases though not enough drones to saturate them, and XIMP was mining minerals with 6 probes and gas with 3. Steamhammer was still winning by a mile.

As the game went on, the carriers moved to the middle of the map and Steamhammer trickled hydras toward them, losing them a few at a time for no apparent gain. There were 2 obvious problems. First, Steamhammer only attacked interceptors; as I watched, I realized “carriers don’t attack, so they’re at the bottom in the target priority list.” The code is easy to rewrite, though I’m not sure what solution is best. And second, trickling the hydras in was suicidal. I concluded while watching that SparCraft must not know about carriers. It ignores units that it does not know about, so when asked to predict the combat outcome, SparCraft always reported “zerg wins,” and Steamhammer moved its hydras confidently to their deaths. That may be harder to fix.

Steamhammer then won when XIMP overstepped a time limit, taking too long on a frame. That was disappointing. :-( I’m not sure how the game would have turned out. Steamhammer was still ahead but was playing like an idiot, and XIMP did finally re-expand to its natural and may have been able to add carriers before Steamhammer could take the rest of the map and start to make progress.

After these two uncertain wins, Steamhammer played against protoss Ian Nicholas DaCosta, a weaker bot which it had beaten in their previous game. Steamhammer got unlucky with base positions and scouting, placed its 3rd hatchery directly on the path that zealots were taking toward its main, and lost. Luck runs both ways!

SSCAIT 2016 links

For convenience, links related to the SSCAIT 2016 tournament that’s going on now.

LetaBot posted the unofficial crosstable link in a comment.

I haven’t seen a plain explanation of the tournament format, although many people seem to understand it. There are 45 players. The tournament will be in 2 stages. The first stage or “student division” is 1980 games in a double round robin: Each bot plays each other twice. Top students in the student division can win prizes. Then the top 16 go into a second stage, the “mixed division,” played in single elimination style.

Iron’s surprise losses

Among SSCAIT tournament watchers, the talk of the moment is of Iron’s two surprise defeats against zergs Steamhammer by me and GarmBot by Aurelien Lermant. Iron got unlucky 2 games in a row.

In the Steamhammer game, Iron became overcautious against the few early zerglings, bunkered its ramp, and was late with its vulture attack. Provoking reactions like that is one of the reasons Steamhammer makes zerglings. When the mutalisks came out, they soon had enough numbers to safely break the bunker and then were free to ravage Iron’s base (they could have gone ravaging from the start, but they were obsessed with the bunker). Iron’s vultures moved in and quickly wiped out every drone, but the mutalisk swarm split up, some cleaning vultures and the rest cleaning the terran base. Steamhammer won with empty bases but unchallenged air supremacy. In my testing, Steamhammer has never won against Iron with this build order—Iron got unlucky, or perhaps a late change weakened its play in this situation.

In the GarmBot game, GarmBot randomly expanded to Iron’s natural and built a sunken that covered the ramp. Iron was again overcautious: It double bunkered its ramp and blocked with vultures and many SCVs, and sent no vultures past the sunken. It seemed in no hurry to get tanks and blow away the sunken. Mutalisks showed up and started picking at a supply depot; nothing stopped them. But the lethal blow did not come until lurkers arrived and burrowed in good position on the ramp. There was no detection. Lurkers defeated the blocking units and cleared the bunkers while mutalisks killed the engineering bay, and then there was no hope. Iron reacted poorly to GarmBot’s bizarre expansion and GarmBot followed up well.

It’s a hard game! Even a bot as well-rounded as Iron is not prepared for everything.

Steamhammer’s surprises

Krasi0 and LetaBot congratulated me in comments on Steamhammer’s strong 4-1 start in the SSCAIT tournament. It’s too early—5 games are not enough to say, of course. For myself, I have mixed feelings because Steamhammer sprung one of its surprises, and it backfired resulting in the 1 loss!

I gave Steamhammer 5 counter-builds for 7 specific opponents.

  • Killerbot by Marian Devecka - 11 pool into spire
  • Iron by Igor Dimitrijevic - 2 hatch hydra
  • ZZZKBot by Chris Coxe - 9 pool into expo and finally spire
  • PeregrineBot - the same anti-rush 9 pool build
  • XIMP by Tomas Vajda - 3 hatch before pool into hydras
  • ZerGreenBot - the same 3 hatch build
  • Jakub Trancik the cannonbot - a 9 pool zergling build

The counter-builds for Killerbot and Iron score about 50% in my local tests. The build vs Iron scored nearly 100% against a November version of Iron, but Iron improves fast! Killerbot and Iron are far more sophisticated than Steamhammer, and only countering their strategies can make up the difference.

I’m eager to see how the 3 hatch before pool build does, especially since Steamhammer still has a terribly weak macro game. The opening is sound against the forge expand of those 2 protoss bots, but I know some of the mistakes Steamhammer will make. And the anti-cannon build for Jakub Trancik is a shot in the dark that I haven’t really tested. Steamhammer ought to tech to guardians once nearby cannons are eliminated, but time was short.

The anti-rush 9 pool build is slow and cautious and it’s effective against the version of ZZZKBot that I tested. (I haven’t tried PeregrineBot; I just hope it’s close enough.) So when I tuned in to Steamhammer vs. Chris Coxe on the stream and saw mutalisks beating up a barren zerg base, at first I thought “Good, it worked.” But no, Steamhammer was losing! ZZZKBot had switched to an entirely different ZvZ build! ZZZKBot built 5 sunkens to hold off lings and then went mutalisks, which counters builds that counter ZZZKBot’s former 4 pool. Steamhammer’s usual ZvZ 12 pool would crush, but instead my evil plot was thwarted. I expect that Killerbot will also find itself countered, and Zia may or may not be able to adapt.

It’s a double-edged lesson in the risk of fixed builds. By the way, Steamhammer’s 12 pool also counters most of Zia’s strategies, but Zia does have 1 strategy that beats it and soon learns. I expect to lose against Zia this tournament.

With enough time, I could find counter-builds for other troublesome opponents. But the best, like Krasi0 and Bereaver, play more strategically soundly and good openings would not make up much of the skill difference. Or at least that’s what I figured. I thought the effort would go to waste.

Next time! Late last night I fixed the double overlord bug, which sometimes caused Steamhammer to spawn 2 overlords when it needed 1. That messed up its opening timings, which led me to write overcautious opening builds in some cases. Expect more accurate openings in January.

SSCAIT 2016 surprise entries

The deadline is past. Here are the surprise eleventh-hour SSCAIT entrants this year:

  • Aman Zargarpur - terran
  • auxanic - zerg
  • BeeBot - terran
  • Tommy Fang - terran
  • XelnagaII - protoss

Of these, XelnagaII is the only name I recognize. It finished in the middle of the pack in AIIDE 2016. As LetaBot says, BeeBot had a bug in its first upload which was fixed before the deadline, explaining its inconsistent results. It may be a dangerous mech bot. Auxanic has been around long enough for me to get an impression of its style: It is a single-minded macro zerg which doesn’t believe in making units for early defense. Auxanic can recover and win after having its main and tech destroyed, so at least it’s robust. Aman Zargarpur has played 1 game so far and Tommy Fang none yet.

I think we’re in for some variety, and that is good.

As LetaBot notes in the comments, they have returned to calling this the 2016 tournament, so that the sequence of numbers is unbroken. They called it 2017 until lately.

BeeBot

So, who’s watching the brand-new terran BeeBot? As I write, its record on SSCAIT is 4 wins and 9 losses. 2 of its wins are a crash by the opponent and a timeout where the game went over the time limit and BeeBot won on points. Surely it should be no threat to the top bots! And yet the other 2 of its 4 wins are against top bots Iron and Martin Rooijackers (that is, the latest LetaBot). Those are legitimate “BeeBot played better” wins. What’s going on here?

Steamhammer 0.2

Steamhammer 0.2 is up on SSCAIT. Unless I discover a last-minute bug, and it’s a simple bug that I can fix without risk, this is the tournament version. It includes improvements at all levels, strategy, tactics, and micro. Most are inconspicuous, but some should be easy to see. The glaring weaknesses that I didn’t have time to fix are also easy to see!

I have built in some surprises. My hope is that after the tournament, a few bot authors will be thinking “Uh oh, I really need to do something about that.”

Steamhammer’s web page with downloads and discussion should be up some time tomorrow.

Still next: Future development will take a sharp left turn. I’ll outline my plans.

Steamhammer 0.1 download

Want to run Steamhammer 0.1 yourself? Here is Steamhammer’s zip file as I uploaded it to SSCAIT. The contents are:

  • Steamhammer.dll
  • Steamhammer_Config.json
  • BWAPI.dll

Steamhammer needs the config file and expects it at the path bwapi-data/AI/Steamhammer_Config.json. The BWAPI version is 4.1.2.

The config file system was inherited from UAlbertaBot (I made minor changes). The config file is easy to read and modify, and fun to play around with. Besides the active build orders and other config settings, it includes a few leftover build orders from UAlbertaBot plus build order experiments that I tried or meant to get around to trying. Items at the top of the “Strategy” section declare which build orders are active. In my view, the current ZvZ and ZvT build orders are adequate, the ZvP build order is poor but an interesting try, and the ZvRandom build order is awful.

Expect Steamhammer 0.2 in time for the SSCAIT tournament. It will have some surprises.

Around this weekend, Steamhammer will get its own web page where I’ll post new versions in source and binary as they come out.