archive by month
Skip to content

Steamhammer’s new scouting skills

I decided to write up Steamhammer’s changes in parts. Scouting today, more stuff tomorrow. I wrote briefly about scouting improvements in September; here are the details. The scouting changes affect all races, though of course only zerg has an overlord to help. The overall effect of the changes is that Steamhammer collects more information sooner and makes better decisions, so it was worth the effort.

Steamhammer has suffered its usual ratings crash in the new version. I think the voters have the journalistic instinct to comfort the afflicted and afflict the comfortable, and top bots and new versions of well-known opponents count as comfortable. They say to themselves, “Let’s vote in a good challenge,” and in Steamhammer’s case succeed.

Even so, I’m satisfied with early results. I see plenty of familiar misbehaviors, and no surprise bugs. And play improvements are showing. For example, Microwave has opening learning, and learned that 5 pool usually beats Steamhammer’s default ZvZ opening mix. In Steamhammer-Microwave, Steamhammer played a gas-first opening that formerly would have lost instantly to the rush, but this time saw it coming and built a sunken in time to stay alive. It became a good game instead of a smash.

early game scouting

Classic Steamhammer scouting, from December 2016: Pick a base on the map, and send both the first overlord and the scouting drone to that base. It was a hack. The overlord waits there for the rest of its life whether the enemy is there or not, and the scouting drone keeps looking if necessary.

Good scouting: Send the overlord and drone to different bases. Redirect one or both depending on what is seen. Send later overlords to good locations to collect further information.

Steamhammer’s current scouting is in between. It uses only the first overlord and the scouting drone, and against terran doesn’t send the overlord because it still doesn’t understand how to keep it safe from marines. The overlord and drone go to different bases, so that the enemy is often found sooner. When the enemy base is located, the overlord changes its path if necessary to go there, so there is often a better view of the enemy’s play for a long time. If the overlord finds the base first, the drone either goes home or stops by to visit the base, depending on its orders.

I added only one clever feature, inference of the enemy zerg’s location from seeing its overlord. When Steamhammer sees an enemy overlord early in the game and the enemy base has not been located, it considers “what bases have I not yet scouted?” It calculates which of those bases the overlord might have come from, based on its position and top speed. If that narrows it down to one base, then “Bingo! Found you!” This doesn’t quite extract all the available information; it’s possible that seeing the overlord could eliminate one base and leave two possibilities, and Steamhammer doesn’t realize that. But that’s a rare case, and in practice the overlord sighting speeds up scouting fairly often. The feature was definitely worth adding, and it helps terran and protoss too.

I want a more general scout manager instead of the current one that is able to scout with one worker and one overlord. It should be: Dump whatever units you feel are free into the scout manager, and it will figure out how to employ them. I decided it was too much for now, but I’ll probably do it later.

middle game scouting

Most bots, I have noticed, scout only to see what’s up. Even Zia, which scouts in the middle game with a zergling, only sends the zergling to see stuff and doesn’t attack with it.

Purely out of orneriness, I decided to do middle game scouting differently. Steamhammer’s middle game scouting is reconnaissance in force.

When there are “enough” ground combat units for the main ground squad, Steamhammer redirects a small number of them into a squad named Recon. The choice of units depends on race, of course, but only certain ground unit types are considered suitable for Recon. The terran Recon squad can include medics, and there are actually remaining bugs in that. If the main squad loses too many units, Recon may be disbanded to join it.

Recon is another combat squad, and it gets orders to attack bases where the enemy is not known to be. Usually it discovers that the enemy is still not there, and it gets new attack orders. But if it sees enemy presence, then its orders remain the same; the combat simulator decides whether to attack or hold ground. Stray enemy units and naked expansions are at risk. If Recon holds ground too long, then its orders time out and it is given a new location to attack.

I added a couple parameters to squad behavior so that Recon can do its job better, while the main combat squad does its job as always. I’ll write that up tomorrow.

Recon usually moves around pretty fast and travels over most of the map, though it does get stuck sometimes holding ground. The effect of the Recon squad is that Steamhammer finds enemy expansions quickly and has much more vision of enemy army movement. It occasionally prevents expansions or catches enemy scouts or tears down misplaced buildings in the middle of the map, but my feeling is that that is less important. I’m curious to see how Recon copes with terrans that sow the map with spider mines. Recon does get dedicated detection when it is available, but the detector often lags behind. I may need to make changes if it struggles against spider mines.

other scouting-related stuff

• A new feature controls the damage of scouting misses, when the scout worker is lost before finding the enemy base. In past versions, that caused disastrously bad play when the early combat units came out: They scoured the map indiscriminately looking for enemy presence in unlikely corners, and were often out of position when the enemy came knocking. Now Steamhammer recognizes that is is likely to find the enemy in a starting base location, and looks there first. The enemy is found much sooner and the combat squad is out of position for a short time or not at all. It is more aggressive than Killerbot’s approach of leaving the combat units at home until the enemy is found.

• The gas steal works, though this version doesn’t use it. You can configure "go steal gas" and Steamhammer will find the enemy base and try to steal the geyser. Or "go scout" and "go steal gas", and the scout will steal gas and, if it still exists, continue to circle the enemy base. And some other combinations. Getting the gas steal to work for all races and cases was time consuming; the number of bugs was incredible.

• The previous Steamhammer version has a misbehavior when the scouting worker is on its way home: It stops to attack anything stationary that it runs across. It is the standard worker self-defense behavior popping up at an inappropriate time. Fixed.

• When doing worker harass on a map with other than 1 geyser in each main, there was a potential crash. It never happened, but I fixed it.

Steamhammer test version 1.4a1 uploaded

The annual rush of new bots is well underway. The latest is a batch of terran bots from the Charles III University of Madrid, none of which seems to be 100% working yet. One step at a time!

Meanwhile, Steamhammer has been unchanged on the server since September, a longer stretch than ever before. I have been working more slowly, but it has been a long time and I have done a lot in total. But mainly I delayed in order to release 1.4 with the promised opponent model, and yet I didn’t feel like working hard on the model.... And now the 20 December SSCAIT tournament deadline is threatening to wrap around my neck. I’ve made a ton of improvements, and it would be crazy to go into the tournament without a look to see what new bugs I’ve added too.

I’m still not sure exactly what will be in 1.4, but today I uploaded the test version Steamhammer 1.4a1. Why that version number? Because it’s inconsistent with the version numbering scheme I used before, and nothing could be more important than inconsistency!

This version has noticeably more complex and interesting play than the September Steamhammer. Most of the opponent model features are disabled; I expect to turn on more of them for the tournament version, because the gain can be big. But watch this version and you will see much improved scouting in the opening and middle game (to support the opponent model), somewhat smarter decisions from squads (to support the opponent model), better reactions to some kinds of rushes (as a result of the opponent model), and many tweaks to strategy (because it desperately needed them). On the stream, look in the upper left for the new “Opp Plan” line that tells Steamhammer’s inference of the opponent’s intention in the opening. It starts out as “Unknown” and often stays that way the entire game, but sometimes changes to “Fast rush” or “Heavy rush” or one of several other values. A few of the values can lead to dramatic strategy shifts, "Heavy rush" has only a subtle effect, and others are unimplemented and have no effect.

I’ll go into detail starting tomorrow.

Randomhammer’s marines versus protoss

This game Randomhammer-MegaBot 2017 is an example of why it’s not such a good idea to go marines versus protoss. Randomhammer still does it (15% of the time in the live version) because its other TvP strategies are also ineffective.

Stage 1: MegaBot went 2 gate zealots while Randomhammer answered with marines from 2 barracks. If MegaBot had been aggressive with the zealots it likely would have won early, because Randomhammer doesn’t understand early game marine-zealot micro and it lets the marines get hit far too often. But MegaBot did not press. In the picture, the larger zealot army is overcautiously retreating.

MegaBot retreats for no reason

Stage 2: Randomhammer got academy tech while MegaBot was still on zealots. The terran force had been dangerously small because of poor macro, but it was growing. Then the zealots took a bad engagement moving across a bridge in widely separated formation, and got wiped out. Stim is strong, and slow zealots are not the right unit to face marines and medics.

Randomhammer annihilates zealots

Stage 3: MegaBot got dragoons, which it should have done much earlier. Defending the ramp, a small number of dragoons was just able to hold the infantry force that had destroyed far more zealots. The better tactical situation (defending a choke instead of trying to pass through a choke) and better unit choice of dragoons versus marines made a huge difference.

MegaBot narrowly holds its ramp

Stage 4: MegaBot expanded and formed a mixed army of dragoons and zealots. Randomhammer built factories for tanks and also expanded but lost the command center to dragoons. It was partly due to more weak macro (gotta replace BOSS).

The game went on because MegaBot decided not to win on the spot, but morally Randomhammer was lost. In the end, though, MegaBot crashed. The game is also an example of the importance of reliability.

I chose the game to write up because of the stark contrasts between stages. The zealots seemed strong at first, then went poof after stim finished. A trickle of dragoons in the next stage was enough to turn it around again. The game would have been a better example if MegaBot had gotten reavers or storm and showed the infantry some real protoss devastation.

when the enemy unit is out of sight

If you have watched a game of Steamhammer versus Stone, then you have seen Steamhammer’s zerglings chase SCVs all over the map. The lings don’t seem to have the idea that they should find the enemy base and tackle the problem at its source.

if I don’t see you, you’re not there

If Stone’s base has been found, then the zergling squad actually does have orders to go to the enemy base. Why doesn’t it happen? The weakness is in micro targeting: When the squad chooses targets for each zergling to attack, it only considers visible targets. Against Stone, some SCVs are almost always visible and the base rarely is, so the zerglings become infinitely distractible and run hither and yon, chasing whatever pops into view. Eventually some zergling stumbles into the terran base and makes it visible, and then the squad is able to assign things in the base as targets.

The fix is, of course, to choose targets from a longer list that includes the enemy command center or mineral line, even if it hasn’t been scouted yet. I’ve been planning this fix for months, and it has never risen to the top of the list. Steamhammer beats Stone in the end, even if it looks silly doing it. But I can’t put it off too long, because the weakness does lose games against other opponents.

Another curious behavior you may have seen is that, if the zerglings are chasing an SCV that disappears up a ramp, they instantly lose interest and switch to chasing another target. The reason is the same: As soon as the SCV is out of sight, even for a moment, it is not a target. Steamhammer has object permanence and knows that the SCV is still there; it has a system (inherited from UAlbertaBot) which remembers the last known location of each enemy unit. But it can’t use its memory for micro targeting.

if I once saw you, you’re still there

Steamhammer does use its memory to feed the combat simulator with remembered units. If it runs into sieged tanks, it is important to remember them after we retreat out of sight range, so that we don’t immediately turn around and run back into tank fire. There is a curious flaw, though. Steamhammer uses the remembered location of an enemy unit even if it can see that location and the unit is not there! It only updates the location of a unit if it sees the unit again; seeing an empty spot where the unit used to be tells Steamhammer nothing. This is the cause of some strange retreat behavior, where the bot seems to shy away from invisible dangers.

This is, of course, also on my list to fix. I’m not sure what the fix should be. Sometimes shying away from invisible dangers is good, because the enemy units have not moved far. I may add an “it’s gone!” flag to the record for each remembered unit, if I can figure out how to update the flag efficiently (looping through every remembered unit or every visible tile each frame doesn’t feel like a good use of cycles). Then I’ll experiment. I might end up ignoring units which are gone, or using them if they’ve only been gone a short time. Or something.

For now, I added a flag to each squad “fight visible only”. If the flag is false, the squad behaves as now. If the flag is true, the squad does not include remembered enemies in the combat simulation, except enemy static defense, but only visible enemies. Setting the flag makes the squad bolder and more inquisitive; it will also run back into tank fire as soon as the tanks go out of vision. I think it’s suitable for scouting squads. The change is one of my improvements to scouting for the upcoming version.

early experience with Steamhammer’s new enemy opening plan recognition

I’ve been testing out Steamhammer’s new opening plan recognition to get a feel for it. I can summarize my findings in 2 points:

  1. Recognizing the enemy opening plan works pretty well.
  2. The reaction to the enemy’s plan is not easy to get right.

Right now, Steamhammer (development version) recognizes a half dozen different enemy opening plans. I’m likely to add or remove or switch around the recognized plans before release; it is still in an experimental state. The set of plans is not supposed to be exhaustive, because if Steamhammer’s usual behavior will do fine against some plan, then there is no need to recognize that plan. I may change my mind about that the next time I rewrite the strategy boss.

Plan recognition makes few mistakes of commission. I mean that, once it has decided what the enemy is doing, in my tests so far it seems to rarely change its mind (which it’s allowed to do as much as it wants) and rarely be wrong. On the other hand, it easily makes mistakes of omission, leaving the plan as Unknown because it doesn’t have enough information to draw a firm conclusion. I think it will take experience to learn whether that is a good tradeoff. I may want to relax conditions or add smarts.

Reacting to the enemy’s plan is a different story. So far, Steamhammer has a special reaction to worker rushes only, not to any of the remaining 5 possible enemy plans.

Opening plan recognition has 2 points. One point is that it will (it doesn’t yet, but this step is easy) tie into the opponent model, so that an opponent which usually follows the same plan will face openings intended to counter it. Stone, starting from the second game, will face Steamhammer’s anti-worker-rush opening. The other point is that, if the enemy plays unpredictably, Steamhammer will try to react when it recognizes the plan. PurpleWave and Tscmoo have been sometimes playing worker rushes that Steamhammer loses to, because the live version reacts poorly.

I think I have it working well now, pending more tests, but I found it hard to optimize and debug the worker rush reaction. Only zerg tries to react specially, for now. When Steamhammer recognizes the worker rush, it checks its build order to see whether it is playing an opening that does the right thing. That way, if it is already playing an anti-worker-rush opening or one that behaves similarly for the moment, it will keep calm and carry on. If the build order does something else, like make too many drones, then Steamhammer breaks out of the book opening and falls back on the strategy boss’s idea of what to do. And the strategy boss now has a special idea of what to do about worker rushes, starting from whatever situation Steamhammer finds itself in.

It’s a complicated arrangement, and it was hard to get right. Reactions to other plans will work differently, but even so I doubt I’ll have time to implement more than 1 or 2 more before the SSCAIT deadline on 20 December.

The game info in the upper left corner of the screen includes a line “Opp Plan” with the recognized enemy opening plan, so that stream watchers will be able follow along when the version goes live. It starts out as “Unknown” and changes if and when Steamhammer recognizes the plan. I think “Opp Plan” is a poor description, but I haven’t found a short string that is better (so if you have an idea...).

an implausible game

Today’s game Randomhammer vs Flash is unbelievable. What I mean is, if I didn’t know that the replay was generated automatically by bots playing, I would assume that it was a setup. That should not happen!

Randomhammer rolled protoss and opened with 1 gate and dragoons. Flash put down 2 gates and made zealots, so of course Flash had more units. Randomhammer had an easy defense in principle: Make a fighting withdrawal with the dragoons, to buy time and to put some bruises on the zealots. When and if the zealots reach its base, Randomhammer should have enough dragoons to outmicro the zealots, and it can run probes if necessary.

Randomhammer has no understanding of any of that. The only withdrawal it knows is headlong retreat, and instead of running probes it fought with them. When the surviving zealots were finally driven off, only 2 probes survived. Furthermore, the 2 probes were collecting gas and had no ability to switch to mining minerals, so Randomhammer had zero income for the rest of the game. “Game over,” I thought. It was 6 Randomhammer dragoons, versus an opponent that was briefly behind in units, but now had its own dragoons and 2 running bases.

Randomhammer loses probes

As I expected, Flash soon rivaled Randomhammer’s army size. But I could hardly trust my eyes when I saw the fight. Flash had just started dragoon range, and could not cope without it! The 5 ranged dragoons (1 froze in the middle of the map) outmicroed Flash’s dragoons and remaining zealots by an extreme margin, with Flash rarely getting shots off. Randomhammer smacked down the army and a long stream of reinforcements which came in piecemeal.

a battle of nearly equal armies

Then Flash showed that it is every bit as careless with probes as Randomhammer, and instead of mining safely in the main and building up a ramp defense force while the natural was slowly flattened, kept transferring probes. Randomhammer finished the game with 4 dragoons, having lost only 2 against a much larger number of enemies. Not plausible, only true.

The next Steamhammer version will turn off gas collection for terran and protoss when there is reason to, as it always has for zerg. It’s a simple feature, and I think it will make a difference.

Next: The theoretical right way to analyze the enemy’s build.

recognizing the enemy’s opening plan

I’ve been adding recognition of the enemy’s opening plan to Steamhammer, as part of the opponent model. Besides making the opponent model smarter, the OpponentPlan is directly valuable to the strategy boss. I’ve been concentrating on enemy plans that the strategy boss is clumsy in reacting to.

After writing recognition code for several plans, I already felt dissatisfied with how it works. It looks at buildings and timings, it counts bases, it notices if zerglings are out suspiciously early, all extremely basic stuff. “2 barracks and no gas, I know what’s coming next.” There is no “You should have a second pylon by now, where is it hiding?” and no “I see more zerglings than you can get from 1 hatchery, you must have 2.” Rich and complex inferences can be drawn from the game information, and the primitive code I wrote draws only simple ones.

So I looked at PurpleWave, which does opening recognition under the name of “fingerprinting”. PurpleWave tries to recognize specific openings for zerg and protoss: This is 4 pool, this is 12 pool, this is 10 hatch, etc. And the way it works is, at heart, the same as what I wrote in Steamhammer. It is written in a different style, but it checks almost exactly the same information.

The biggest difference is that Steamhammer does not try to recognize specific opening builds. I think there are too many, and some of the differences don’t matter. The OpponentPlan groups enemy openings into categories, like “this is a fast rush,” without distinguishing between 5 pool and other early pools, or even between 5 pool and 5 barracks and 5 gateway. 2 barracks no gas gets the same plan label as 2 gateways no gas. If you want to react differently to 2 barracks than to 2 gateways, that is for the strategy boss to figure out. I think the plan categories extract more information from the game and compress it into fewer labels for the rest of the code to handle.

Well, if PurpleWave gets away with it then I guess the primitive recognizers are good enough for now. Someday I hope to write a cleverer plan recognizer that draws the deep inferences, that (like a pro) knows when you’re trying to hide a base and triggers a goal to go look for it. Or that says “You’re proxying something and I don’t know what, but I don’t need to see it because the answer is to build turrets.”

when do the first zerglings hatch?

I collected data to calibrate openings so that Steamhammer’s opponent model can make more sense of the opponent’s opening. I thought some of the data might be of interest.

Here are the frame times at which Steamhammer’s first zerglings hatched with different spawning pool timings. These were all measured on Heartbreak Ridge, since the numbers vary depending on the layout of minerals on each map. Also the numbers vary somewhat from game to game, but it’s close enough. Steamhammer has wasted movement, so optimal timing is probably a touch faster.

poolframes
4 pool2630
5 pool2750
6 pool2920
7 pool cutting drones2990
7 pool going to 9 drones3120
8 pool3160
9 pool3230

Making a spawning pool on 7 leaves you with 6 drones. It’s possible to make 3 drones and an overlord before the zerglings, but the lings have to wait for the overlord and are slightly delayed. Instead, you can cut 1, 2, or all 3 drones and get that many pairs of zerglings before the overlord, saving a sliver of time. It’s an interesting tradeoff.

I like that there is a nice spread in the timings. It seems as though each of these builds might have some use, depending on what you think your opponent’s timings are and on how you plan to follow up.

untraceable Steamhammer crash

Steamhammer has had its first crash loss on SSCAIT since May. Or it may have overstepped the time limit. Randomhammer protoss has sometimes broken the time limit, but this is the first for zerg in a long time.

The game is Steamhammer-UPStarcraftAI 2016 (a zerg rushbot), and it looked like a routine Steamhammer win until 5:19 in, when suddenly bam, the 0/0 supply that means crash. Steamhammer has won dozens of these rushbot games without incident.

  • SSCAIT did not record an exception log.
  • If it was a time limit loss, why did it happen in a short game with few units?
  • It didn’t seem like server maintenance either. The games before and after were closely spaced.

It’s a mystery, and there doesn’t seem to be any information to start from.

Steamhammer does still have crashing bugs despite my rigorous eradication campaign. AIIDE 2017 reported 4 crashes out of 2964 games, a rate of about one per 740 games. The current SSCAIT version now has 1 crash in 385 games, which is not statistically different. I found a crash yesterday with a stress test where I forced Steamhammer to play an opening that caused it to lose bases and struggle to recover. After many games, I got one crash. I think I fixed the cause, but the crash is rare and difficult to reproduce, so....

mine-laying framework

What is a good framework for laying spider mines?

Steamhammer’s terran is much better with barracks units than with factory units. To catch up, it needs 2 skills. One is the ability to siege tanks non-ridiculously, and the other is the ability to lay spider mines in reasonable places. Right now it can’t lay mines at all.

It would be easy enough to code up a simple behavior like “lay mines along the path between the friendly and enemy main.” But I’m a little more ambitious. For terran and protoss, Steamhammer is primarily a starting point for authors to build their own bots. I want there to be enough structure that authors feel they can plug in their own mine-laying skills without having to figure out the details from scratch. I don’t think it would take much structure.

A brief reminder of some of the many uses of spider mines:

  • Provide map vision, so you can (for example) see incoming drops.
  • Obstruct paths so the enemy can’t move around as easily.
  • Catch fresh units just coming out of the gateway (say).
  • Deter cloaked units without needing detection.
  • Block expansion locations.
  • Directly attack sieged tanks or dragoons by being laid next to the target.

So what is a good framework for laying mines? I’m imagining something like a list of available behaviors and some way of telling when to use each, but I haven’t come up with a satisfying plan.

What would you do?

Steamhammer-Tyr game

A funny game, a comedy of errors: Steamhammer versus Tyr terran by Simon Prins, on the map Tau Cross. Steamhammer opened with 2 hatch mutalisks, and Tyr bunkered itself in and went with infantry on one base.

Phase 1: Steamhammer fiddled around with its mutalisk force, picking off several building SCVs but mostly wasting time.

Phase 2: Steamhammer happened to notice that the terran mineral line was also a possible target. “Oh, look, terran has SCVs mining. I didn’t know that!” Tyr didn’t defend but moved out to counter instead and lost all SCVs. Steamhammer had 3 mining bases to 0, and only had to survive Tyr’s attack to win. Terran could not reinforce, so that was easy, right?

Steamhammer finds the mineral line

Phase 3: Instead of defending itself, Steamhammer decided to sacrifice every mutalisk against the meaningless bunker. It also wasted units piecemeal against the terran ball. Tyr destroyed the zerg main and natural. Steamhammer lost many drones by sending them to mine gas at bases that were under attack. That makes 3 big mistakes, more than enough to lose.

Phase 4: Tyr spread out to find the zerg 3rd base, found it after a few tries, and then—decided to send its army home to rest. “No zerg anywhere! Not that I’ll admit, anyway.” The marines in the picture saw the base, and that is when Tyr started to send its troops home.

Tyr locates the zerg base

Phase 5: Steamhammer slowly recovered from 7 drones at its third base. It restarted its tech from zero, put down 4 sunkens because it knew there was a scary army out there, and belatedly switched to lurkers. Steamhammer made far too many drones before moving out, but finally sent a lurker and won easily because Tyr had no detection. The mutalisks had also killed the comsat.

In the picture, nothing can stop the lurker, and more lurkers will come. You can see in the minimap that Steamhammer has retaken its main and natural and a mineral only base as well.

one lurker can win

Both sides showed a lack of resilience. This time, Tyr turned out to be lacking a little more. Besides its opportunity to attack and win, Tyr had an unfinished science facility that it could have canceled (it’s in the upper right of the last picture). Then it would have had the resources to make an SCV and get back to mining.

impressive gas steal bug

Stealing gas is irritatingly complicated in Steamhammer. Today I discovered another bug: If the scout worker has been ordered to circle the enemy base forever, and while it’s doing that you decide (this late in the day) to steal gas, then the building manager goes haywire and moves the worker into a corner or some other useless location. Now what??? It worked when I told to it to scout once around the enemy base and interrupted the circle in the middle by deciding to steal gas, but circling more than once somehow breaks it... in a different module.

Of course everything works perfectly if you decide up front to steal gas, so the worker arrives at the enemy base knowing what to do. That’s the usual case. It sure would be nice to support late decisions, but there are interactions with the scouting command.

I think I should write a general purpose plan sequencer and reduce the gas steal to a plan represented as data, not code. It will be more complicated, but I only have to debug it once and it will have tons of uses.

Steamhammer-ICEbot impressive blunder

I’m still going through AIIDE 2017 games in which Steamhammer lost to weaker opponents. Steamhammer scored 98-12 against ICEbot. I thought this game on Tau Cross was full of depressing and/or informative mistakes.

The biggest mistake is that Steamhammer didn’t usually scout or react to enemy expansions. That is fixed in the development version. I think the new version would have won this game easily, despite the second mistake.

The second and interesting mistake came when ICEbot tried one of its 4 goliath drops.

an unnoticed goliath attacks

Steamhammer’s notion of “this base is under attack” is not accurate. One goliath wandered outside Steamhammer’s danger recognition zone and found itself still in weapons range. It killed dozens of drones and eventually one of the hatcheries before dying. In the picture we see the totally non-dangerous goliath killing drones while Steamhammer does nothing because “the base is safe now.”

This weakness is not fixed. I’ve seen it before. The base defense code is inherited from UAlbertaBot and needs a bigger rewrite than I’ve given it.

ICEbot was playing weakly too, though, or else it would have scored more than 12 wins in 110 games. Zerg recovered from the huge deficit and made a fight of it. The game timed out after an hour with the map mined out and the winner still undecided. ICEbot was given the victory on points.

Steamhammer’s losses against ICEbot followed a curious pattern, by the way. Steamhammer lost in rounds 0, 2, 4, and 6. Then in the rest of the tournament, which ran to round 109, it lost 8 more games. Neither bot was learning, so the early losses of every second game were purely coincidence.

too many devourers

I’ve been watching the replays of Steamhammer’s losses in AIIDE 2017 against its lowest-scoring opponents. I reason that if A beats B nearly every time, then a weakness which causes A to lose to B must be a severe weakness that I should fix.

Steamhammer scored 105-5 against Overkill in this tournament. The losses were all due to the same basic strategy blunder, teching too fast and not making enough mutalisks. One loss was an interesting one that taught me something: It involved making too many devourers.

Here’s the game. Steamhammer played its turtle opening, which it was set to do 1% of the time in ZvZ. (It’s a weak opening, but it is played rarely and it poses challenges that some bots can’t meet, so I don’t mind.) Meanwhile, Overkill also turtled, on 2 bases instead of 1 but with fewer drones.

As in the other losses, Steamhammer spent on zerglings and on teching to hive when it should have been making mutalisks. Overkill flew over, killed a lot of drones—then left for no apparent reason. Overkill was ahead, but Steamhammer could recover. Mistakes like that may explain how Overkill scored so poorly. Steamhammer still didn’t feel like making many mutas, but it did add scourge and morphed a greater spire, which (since it was behind and had already invested in a hive) was reasonable.

Steamhammer started morphing its mutas into devourers. It can’t catch up in mutalisks, so it was a good try to turn the game around. But as I watched, I realized there was a flaw in the strategy logic: It wanted to morph all the mutalisks and go straight devourer. The unit mix is declared as mutalisk + devourer, but because of how gas accounting works, the strategy boss preferred to turn gas-heavy mutas into mineral-heavy devourers.

Overkill finally moved out when it was maxed, with 72 mutalisks. Steamhammer had 20 devourers and 4 mutalisks, plus a fleet of scourge. Now, devourers are support units. They don’t do much damage; their benefit is that they splash acid spores which reduce the enemy’s attack rate and increase the damage taken, and to get the benefit you need fast-attacking units to deal the damage. Because acid spores only stack up to 9, it is not likely that 20 devourers will ever be useful, and definitely not if you fly them around in a group. I guess that about 6 devourers would have been best, certainly not more than 9.

massive purple goop

The battle was hilarious. The devourers fought well enough, apparently not harmed by the known bugs, and instantly stacked their purple goop up to the limit of 9 on every Overkill mutalisk that appeared. Devourers are tough, and Overkill’s mutas had their attacks slowed, so the the devourers took a long time to die. But with only 4 mutalisks to deal damage, even though the damage per shot was 9+9 + 3+9 + 1+9 = 40 (spread over 3 enemies with mutalisk bounce) Overkill’s losses were minor.

The ultralisk cavern you can see in the picture was useless. Steamhammer never made an ultra. It shouldn’t have wanted to.

In the next version I’ve taken measures. Steamhammer tries to make more units, techs more moderately, and limits the number of devourers.

gas steal plans

I’ve been thinking about how to get Steamhammer to keep trying the gas steal, so the code doesn’t bitrot again. Writing separate gas steal openings for each race doesn’t sound like much fun, and also doesn’t gain the full advantage. I might do a little of that, though.

I decided to build it into the opponent modeling mechanism. I’m not sure about details, but the basic idea is that, against any opponent that is causing trouble, it will try stealing gas to see whether it works. It will record the gas steals in its game records. Over time, the opponent model could learn many things: 1. Which opponents fail to cope; steal gas and win. 2. What opponent builds it is effective to steal gas against. If you see 2 gates and zealots out already (whether or not you’re playing Wuli) then you have the opportunity but there’s little point. 3. How to follow up a gas steal. The point of stealing gas is to channel your opponent’s play into a direction that you can exploit. Then you have to exploit it!

I would also like the opponent model to handle scout timing, but I’m not sure whether I can get to that for the next version.

Gas steal, by the way, is more or less working in my development version. I still have bugs to fix and testing to do, but it’s basically back again. It took a lot of changes.

Steamhammer versus McRave and KillAll

I thought these 2 games showed interesting mistakes.

Steamhammer-McRave

This game on Circuit Breaker was kind of disorganized on both sides, but fun. Steamhammer played its usual low econ zergling pressure, and McRave opened with cyber core before second gate, which was slow enough to give the pressure a chance. After a few tries, Steamhammer killed enough probes to make up for its own weak economy, and the game was on.

Steamhammer fails to contain its opponent

The fight went back and forth, the sides seeming about equal in economic growth, tech progress, and missteps. It was fun to watch.

Steamhammer: It’s only an overlord. No need to keep it safe. And that? Oh, it’s only another overlord.
McRave: Huh? Why wouldn’t I awkwardly split my army?

Then dark templar came out, and Steamhammer fell over. Zerg did not understand.

Steamhammer: What danger? I don’t see any protoss units that I can’t fight.
McRave: Exactly.

Steamhammer-KillAll

This game was a win but... ugh. Only because KillAll went above and beyond to play worse.

KillAll did its thing and sunkened up for safety. Steamhammer understands in outline how to win these games: Place zerglings in a containing position so the enemy can’t expand or attack, make drones while teching, then win with mutalisks. But (as against ZZZKBot in AIIDE) Steamhammer did not execute well. It placed the zerglings in a position that contained nothing, and in fact left the barn door wide open. Steamhammer even stepped back to let enemies pass, in reflexive fear of the distant sunkens.

Steamhammer fails to contain its opponent

Below you can see that Steamhammer is ahead in economy, tech, and army—yet Steamhammer is in trouble because its force is out of position, standing outside an enemy base that it cannot threaten while its own base is under attack. Meanwhile, KillAll decided that its attackers should focus down the lair to the exclusion of all other targets, so that Steamhammer’s drones were able to clear the zerglings with no losses.

KillAll fails to attack its opponent

I can’t say it’s an undeserved win. The winner made smaller mistakes. Only not small mistakes.

Next: Thoughts on the gas steal.