archive by month
Skip to content

backing up is hard to do

If you want to beat Steamhammer without really trying, I have a suggestion. All you have to do is maneuver your army to the other side of Steamhammer’s and put yourself on the path between Steamhammer and its base. You leave your base wide open, but you’ll probably win. It works versus ground units and versus air units.

At some point Steamhammer will want to retreat. Even when winning, it sometimes retreats for no apparent reason (I haven’t looked into why yet). It pays no attention to its surroundings when it decides to retreat, so if you are on the path between Steamhammer and its base, it will retreat through your army. And Steamhammer does not fight when it retreats—the units are on move command.

Here Steamhammer forced its way into Carsten Nielsen’s base, started in on the probes, then got scared for no good reason and left, giving the zealots free kills. If more zealots had been near the ramp, all the zerglings could have been caught.

Steamhammer loses zerglings

The next one is even more infuriating. Sometimes, Steamhammer retreats from a threat but does not retreat out of weapons range. It seems unpredictable when. It’s most glaring with mutalisks and goliaths: Mutalisks approach, take hits, retreat without firing, turn around before escaping goliath range and approach again, continue to take hits, retreat without firing... it doesn’t go on long, soon they’re all dead with nothing accomplished.

Here Steamhammer’s mutalisks are moving back and forth in goliath range, offering free lunch. The mutas did eventually escape, only to get caught again.

Steamhammer loses mutalisks

It also happens sometimes with mutalisks and bunkers, zerglings and bunkers, and zerglings and tanks. And probably other unit combinations. But it doesn’t happen every time, only sometimes.

I don’t have immediate plans to fix either of these weaknesses.

Later: I’ll have at least one more post about bugs and weaknesses in Steamhammer 0.2.

Steamhammer’s bunker obsession

The #2 most frustrating weakness in the play of Steamhammer 0.2 is its insane obsession with bunkers.

Here’s the kind of strongpoint Icebot builds when it sees Steamhammer’s mutalisks coming: A bunker, surrounded by turrets, with SCVs to repair, placed out in front where it can’t be overlooked. Objectively, it’s a stupid move, because the rest of the terran base is barely defended. Against an opponent that knows how to bypass strongpoints, like Overkill, Icebot collapses.

Icebot's strongpoint

But against Steamhammer, Icebot holds and usually wins. Steamhammer sees that bunker and can’t take its eyes away. Steamhammer measures the air defense and realizes it can’t attack, so it pulls back a little, waits, collects some more mutalisks, pokes in to take another look, still doesn’t have enough, waits some more... soon Icebot has goliaths and valkyries and it is too late. Steamhammer’s opening is a low-econ rush, and the last thing it can afford is to wait.

It’s frustrating for two reasons. One, it’s intolerably foolish and must be fixed. And two, it’s not a simple bug that can be set right with an hour of coding. It’s an ingrained behavior with both tactical and micro aspects—it’s the result of a design attitude, and it has more than one cause.

I already fixed one cause in moving from Steamhammer 0.1 to the tournament 0.2 version. In 0.1, the mutalisks were grouped with zerglings in the same squad and followed the same path, so the mutas were constrained to ground paths and could not avoid front bunkers. In 0.2 the mutas are in their own squad and can fly as they will, so in some cases they fly a straight line path far from any bunker and ravage the terran. It helps noticeably, but not enough.

Another cause is targeting priorities. Steamhammer 0.2 believes that a bunker is more important to attack than a marine or a turret. When it collects enough mutalisks to fight, it should pick off turrets until the bunker is laid bare—the turrets are easier to destroy. Instead it ignores the turrets and goes straight for the bunker, which of course terran repairs. The development version of Steamhammer gets the priorities mostly right, after about 3 rounds of tinkering, so this cause is fixed too (well, fixed enough for now). New Steamhammer plays clearly better around bunkers.

But improved Steamhammer still shows obsessive tendencies. Given an unguarded command center and a bunker, instead of winning the game without risk it will too often divert to fight the bunker, depending on what happens to catch its attention.

The most fundamental cause is that the tactical system is not conceived with guerilla warfare in mind. I think many bots share this weakness, maybe most bots. Steamhammer, like its parent UAlbertaBot, draws a line from its base to the enemy’s and wants to progress down the line: Defeat the units in front of me, move forward, defeat the units in front of me, etc. It’s a super-simplified tactical framework. And for the guerilla warfare of air units, it is exactly backwards. The guerilla wants to bypass the units in front and hit wherever the defenders aren’t.

The simplification shows in how the combat simulator SparCraft works. SparCraft wargames out a battle under the assumption that both sides stand and fight, and predicts who will win: The side that is not annihilated. But in the fight of mutalisks versus terran base, only the terrans want to stand and fight. The mutalisks are happy to hit and run, as long as they don’t suffer too much. The mutalisks would prefer to ask SparCraft the question, “can I kill something—anything—and get away without any mutas dying?”

Anyway, I’m not going to fix this fundamental cause soon. Someday I hope to work on SparCraft and teach it to answer more questions. But that is at the tactics level, and I’m doing strategy first.

Tomorrow: The #1 most frustrating weakness: Retreating is hard to do.

picking the opening randomly

Why does random UAlbertaBot score so well? Its 5 pool rush is easy to counter. Its marine rush is weak and easy to counter. Its zealot rush is strong, but it can be stopped too. I think the secret is: What opening counters all 3? Well, overpool works, but you have to play it very differently depending on what race UAlbertaBot turns out to be. Bots struggle to adapt. Randomness has value in itself, because it forces the opponent first, to choose openings carefully, and second, to scout and adapt.

Steamhammer’s new strategy boss is not far along; it can only respond to a few basic emergencies, like having no drones. (Steamhammer 0.2 freezes; the development version orders up a drone and can play on if it has 50 minerals.) But yesterday I decided it would be more fun to switch the order of improvements around and do randomized openings before getting the strategy basics down.

I was right, the variety is a lot more fun. I don’t know in advance what Steamhammer is going to do; I have to watch and see.

Today I played a long ZvZ match versus Zia to make sure that the random openings don’t hurt performance. Steamhammer played 5 different openings. One of the openings dominates Zia, but Zia has answers to the other 4—if it can find the answers with its opening learning. Does mixing in the weaker openings give Zia a chance to find the answers, or does the randomness wipe out any learning signal and make life even harder for Zia?

Answer: After 45 games, giving Zia time to learn, Steamhammer scored 40-5. Zia won 4 games by accidentally hitting on a counter and 1 by playing better tactically. At worst, the weaker openings do not hurt. They were chosen to have different counters, and Zia’s implicit assumption that there should be One Best Counter is wrong.

Lesson: Opening learning is not enough, at least not this kind. As difficult as it may be, you have to recognize what the opponent is doing and adapt to it.

On the downside, to earn the full advantage from random openings I have to implement more openings and make sure that Steamhammer plays all of them well enough. At the moment it only has enough variety in ZvZ. But someday, with both random openings and opening learning, Steamhammer will turn fearsome.

Update: I should have added a couple points. 1. Random openings make it hard for other bot authors to hand-code counters to your strategy. This change to Steamhammer should defeat Chris Coxe’s plan of countering specific opponents. 2. Random openings are more fun for humans to play against.

Tomorrow: The curséd bunker obsession. After that: Retreating is hard to do.

Korean visitors

In the last couple days there have been a lot of Koreans on the SSCAIT stream chat. The total number of viewers zoomed up. I guess SSCAIT suddenly got publicity in South Korea.

My impression is that since the AlphaGo shock, AI is hot in Korea. I get the idea that it’s at both the grassroots level, “hey, this is cool,” and at corporate and government decision levels, “we need a strategy so we don’t fall behind in the tech race.”

So I hope that we get some new Korean bots this year! Of course a strong player community is very different from a strong bot community, but still, doesn’t it seem that there should be some feedthrough? In any case, I think the interest is there, and that’s what counts.

Update: As LetaBot mentions in comments, some spectators were brought in on Friday by a post on the Factorio game site (scroll down).

Steamhammer’s funniest bug

Here is Steamhammer’s most hilarious bug. When facing Jakub Trancik’s cannon bot, Steamhammer opens with 9 pool, a sunken, and then an expansion. The idea is that 9 pool counters the cannon rush; zerglings should be out before any cannons finish. If that somehow fails, the sunken prevents cannons from completely destroying the base, and the expansion gives zerg a foothold on the other side of the cannons; Steamhammer should be able to go destroy the protoss main. I hadn’t tested it, but with 3 separate counters to proxy cannons I felt confident. I was wrong, though. As it turned out, Steamhammer went 1-1 versus Jakub Trancik in the round robin phase of SSCAIT 2016.

In the losing game, here’s the probe trying to cannon up the zerg base. The probe took 1 sunken hit, escaped and started a pylon, then the probe and pylon immediately died. The defensive plan worked exactly as intended.

Jakub Trancik’s probe about to die

So how did Steamhammer lose? In the minimap, you can see Steamhammer’s overlord headed toward the northwest and drone scouting the southwest. The protoss main hadn’t been seen yet. When it saw a pylon warping in its base, Steamhammer applied a heuristic: I see an enemy building in this base location, so—this must be the enemy base! The scouting probe immediately returned home and starting running loops around the home base, because it was the enemy base too, and the scout never saw the enemy’s real base. It’s not entirely foolish behavior if your enemy likes to proxy! Zerglings explored around and found “another” enemy base filling up with cannons, and started to build up numbers in preparation for an eventual attack. The mistake didn’t look too bad so far.

Then Steamhammer built an extractor on its gas. Since the extractor was in enemy territory, it was obviously a gas steal, so the bot did not collect any gas. The drones will die in the enemy base, right? The zerg build was not able to progress, Steamhammer stopped building anything, and Jakub Trancik eventually did its zealot switch and won, gg.

Here is the unused “gas steal” extractor. That drone moving up the right is the scouting drone, still circling the “enemy” base. The minimap shows zerglings out exploring, looking for the “last remnants” of the protoss. You can see 2 zerg expansions; Steamhammer 0.2 is slow at it, but it set about methodically building up.

Steamhammer is about to freeze up

All those consequences from 1 flaky heuristic! I’m still laughing over it—I get to laugh because the fix is a 1-liner and I already made it in December. The heuristic and the bug are inherited from UAlbertaBot, but I have never seen the bug in UAlbertaBot’s play. I’ve also never seen the heuristic fail any other way, although it can. On the one hand, it’s a critical bug that can cause losses; on the other hand, it’s not that important to fix because it’s rare. Bugs are weird that way.

Next: More bugs and weaknesses (they won’t all get such a thorough writeup, though).

Steamhammer versus Zia for the SSCAIT round of 16

Steamhammer and Zia tied for 16-17th place in the round robin phase of SSCAIT 2016, and played a best-of-3 tiebreaker match to decide who would move on to the round of 16. The video is out with commentary, and here are the games. They’re all somewhat entertaining, if you can tolerate weak bot ZvZ. The caster seemed unfamiliar with bot play, so I’ll explain the reasons behind some of the events.

Game 1 was on Destination. Zia had learned from past games that its most successful opening was an aggressive 9 pool, and that’s how Zia opened. This version of Steamhammer follows a fixed 12 pool build, which is riskier on this 2 player map. When Zia’s initial 6 zerglings arrived at its base, Steamhammer was just about to produce its first 4 zerglings, so Steamhammer pulled drones to defend. With drones and 4 zerglings, Steamhammer should have defended safely. But Steamhammer tends to be overeager with its drone defense and pulls its drones too far out; it should defend in the mineral line, or at least on the creep, but it pulled drones most of the way to the ramp. (This is one of its most severe weaknesses, one step behind the absolutely-must-fix problems.) When Steamhammer’s zerglings followed the drones moments later, the drones got in their way, and too many drones were lost. Zia was far ahead, cautiously built up, and won easily.

Game 2 was on Circuit Breaker, a 4-player map where the aggressive 9 pool is less likely to work. Also, the players spawned in cross positions, so the rush distance was longer. Nevertheless, Zia had learned that it worked, so Zia played the aggressive opening. And sure enough, Zia arrived with more zerglings and Steamhammer again defended poorly, frittering away its lings against a larger force instead of massing for a short time before engaging. Zia was tearing down the natural hatchery while safely expanding itself, and the game seemed to be decided. Then Zia’s remaining zerglings settled on the wrong targets, one attacking an egg and another a larva. The hatchery was deep in the red and would have died if attacked by those 2 lings. Instead Steamhammer’s next wave cleared the invaders and the hatchery survived with 34 hit points, a sliver of red on its health bar. Then Steamhammer had both economic and tech advantages and went on to win. Steamhammer does not make the same targeting mistake, so you could say it was a deserved win, but it was no less a lucky win.

Game 3 was on Fighting Spirit. Zia’s learning algorithm said “uh oh, that didn’t work, better try another opening” and picked a defensive 9 pool instead. Zia massed its zerglings but held them on its ramp for safety. Steamhammer’s opening gave it more larvae, a stronger economy, and a faster tech path, all at the cost of fewer and later zerglings, so Zia’s choice to stay home was poor. Then Zia made another mistake when it wanted to expand to its natural. It should have swept its ling force out to secure the natural, but instead pulled back to the main hatchery to let the expansion drone out. Only after Steamhammer sniped a few expansion drones did Zia change its mind and attack across the map. Steamhammer defended with its characteristic incompetence, overeagerly pulling all drones and losing every one, but mutalisks were out and cleaned up.

Zia has a sneaky fallback when it repeatedly fails to take its natural: It takes a hidden base instead. This time it took the center base on Fighting Spirit. Zia is capable of rebuilding from a hidden base and the cash for a drone or two, but of course it takes a long time. Steamhammer’s mutalisks abolished Zia’s main and then set out across the map to find remaining buildings. Steamhammer’s search behavior (inherited from UAlbertaBot) is inefficient and looks strange, and the caster was understandably confused about it. The algorithm is simple. Steamhammer keeps track of when it explores each square of its map grid, and picks one of the squares that it has least recently explored as the next destination. It’s good enough.

Steamhammer will play LetaBot in the round of 16. The pairings are 1-16, 2-15 and so on, the arrangement with the least likelihood of upsets for the top finishers. Nevertheless, Steamhammer does defeat LetaBot occasionally and has a small chance to move on to the round of 8. If Steamhammer pulls off the upset, it will almost surely lose in the round of 8—it loses 100% against Wuli’s 9-9 gate zealot rush, and nearly as often against Overkill by Sijia Xu. I’ll borrow the bracket image.

SSCAIT 2016 finals bracket

Steamhammer and software development

I’m going to make a post about bugs and flaws in Steamhammer, with pictures. Some are hilarious, some are to weep over. But there are so, so many that I’m too busy fixing them to write about them! So far, my change log for the next version shows 22 new features and bug fixes worth mentioning, and yet the issues marked DONE are thin on the ground.

On my first day of development on Steamhammer, December 2 or 3 I think, I started tracking issues to deal with. Within a day the list was large enough to need organizing. I divided it into topics: Macro issues, build order issues, targeting issues, code issues.... After a while that grew to become unwieldy too, so I also prioritized the issues to concentrate on the critical absolutely-must-fix ones. Today I ran test matches against various opponents and found serious bugs, and now the absolutely-must-fix issues are more than I can keep an easy overview of. I’m overwhelmed, and it’s harming my ability to solve problems in the right order.

This is why it takes a long development period before a new bot can threaten the top ranks. Well, I knew I was in for it. One step at a time. I will eventually get to the good part.

Not that the test matches went poorly. The development version of Steamhammer with new skills and a new ZvZ opening scored 26-4 against Zia, a huge improvement. Zia tried all its openings and could not find an answer. The 4 losses were all due to play bugs that I hope to fix soon—if they don’t get swamped by other bugs. Steamhammer also finally has a non-awful ZvRandom opening.

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.