archive by month
Skip to content

Steamhammer’s opponent model

In the tournament, the ranks are starting to resolve. Outside the collapse of McRave, I don’t see any big surprises. Locutus has played fewer games than other bots, so the top position is less clear than others. Steamhammer is likely to finish around rank #10-#12, in the range of past performances, so it is safely in despite my worries.

In development, resource tracking was soon working. When destroying an enemy base you normally get to see the resource counts, so used bases should be evaluated accurately.

I started writing a scout boss, then I got distracted by another project. I am refactoring gas steal into one skill in a skill system that retains data in the game records of the opponent model. You subclass a Skill object, fill in around 8 virtual methods of which most are simple, and you get opponent modeling that estimates when the skill is useful against whoever you’re playing now. Since it’s implemented in code, it’s highly flexible. You can choose what data to record, including measurements of how successful a skill was in the current game, and how to interpret the data.

The immediate effect I hope for is better gas steal decisions. Steamhammer’s new queen skills are also good candidates, because queens vary from useful to wasteful. Will a queen be good? How many queens? Will ensnare be good? Even tactical decisions like “play defensively until time t” should be possible, with t adjusted in real time as the opponent model watches the game unfold. I like the idea of learning to adapt tactical play to the opponent.

The game record file format will change. The format has to change soon anyway, because it doesn’t record all the information needed for some important strategy decisions. I designed it so that I can add new format game records without having to discard old ones.

SSCAIT 2019 underway

For anyone who hasn’t noticed yet, SSCAIT is underway and games are being played. 45 bots made it in after screening, which means 45 * 44 = 1980 games in the double round robin phase. So far, some bots have played up to 7 of their games, while some have yet to play any.

results so far
the stream
ranks and crosstable by MicroDK

Since comments are coming in about it anyway, here’s a post to attach them to. MarcoDBAA suggests Simplicity-ZNZZBot as a fun game (and I agree).

the Phlegethon build, another post that doesn’t matter

I’ve been exploring build orders in which zerg uses the extractor trick repeatedly to make its first two buildings at 10 supply before the overlord. I was looking for a build as finely tuned as the Styx opening, but for 3 hatcheries. Here is the best one I found. I call it the Phlegethon build, parallel to the Styx, and I compare it to a more standard 3 hatch ling build.

stepStyxPhlegethon3 hatch ling
15 x drone (9 total)4 x drone
2extractor trickoverlord
3spawning poolhatchery4 x drone (12 total)
4drone (9 total)extractor trickhatchery
5overlordoverlordspawning pool
63 x zerglingspawning pool3 x drone
74 x drone
8hatcheryhatchery
9extractorextractor
103 x zergling6 x zergling6 x zergling
11metabolic boostmetabolic boost
12zerglingszerglings

I inserted blank steps on the left and right to show how parallel the builds are. Phlegethon’s overlord before spawning pool gets the needed extra drones with minimal loss of time and pulls ahead in minerals compared to overlord after pool. It’s possible to make either 3 or 4 drones after the spawning pool; there is little difference in timings, but the 4 drone version is slightly superior in keeping down its larva count in the runout. The third hatchery starts slightly before the spawning pool finishes, and taking gas delays the first pair of zerglings by around 2 seconds. If for some reason you want zerglings right now instead of zergling speed later, I think it’s reasonable to insert as many as 5 pairs of zerglings before the extractor (but it delays speed a lot in return for getting zerglings a little earlier).

You could say that 4 pool is a one hatchery member of the Styx family. It ends up with 3 drones and produces zerglings constantly from 1 hatchery. Styx ends up with 7 drones and produces speed-upgraded zerglings constantly from 2 hatcheries starting from the 7th pair of zerglings. Phlegethon and 3 hatch ling both end up with 11 drones and produce constantly from 3 hatcheries. Each member of the family has one more hatchery than the last, so that it starts zergling production later but produces at a higher rate. All have a good drone count for constant production.

Now to compare them. Was my clever trickery worth it? The Styx timings are from the data for my post on timing the Styx build. The Phlegethon and 3 hatch ling timings are from single test runs with variants optimized the same way, no scouting and all hatcheries in the main.

itemStyxPhlegethon3 hatch ling
first lings326745804520
speed finishes595567696594

The standard 3 hatch ling build is superior in every way that matters. Phlegethon gets its second hatchery faster, but is slower in every other respect; the margins are not large, but they are definite. I draw lessons: 1. Standard builds are standard for a reason. Somebody considered all these possibilities years ago. 2. If you’re aiming for a given drone count, get as many as possible up front. The early drone catches the minerals.

I’ll graph the production curves another time. The 3 hatchery builds produce zerglings 1.5 times as fast as Styx, so they will surpass it after a while despite starting later. Whether that is better or worse in the game will depend on what the opponent is doing. We can expect that later members of the family will have decreasing results as they take ever longer to catch up. Also an over-large zergling army gains in strength less than it gains in numbers, because zerglings don’t have range and the ones in back can’t fight.

So—can anyone find a better build that has the same goal of constant speedling production from 3 hatcheries, or is 3 hatch ling optimal? There is reason to suspect that the Styx build is optimal for its goal. I don’t know any better way to prove it than exhaustive search.

blocking expansions

Today I wrote about a dozen new burrow openings (mostly easy variations of existing openings). If burrow has many uses, there should be many timings to get it at. I also made a first pass at resource tracking, so that Steamhammer can finally stop expanding to bases which are mined out—and also as an input for strategy decisions. The last seen mineral amounts are a starting point to estimate the enemy’s total minerals mined, which is valuable for figuring out what they’re doing. It worked on the first try for minerals; vespene geysers are more complicated. I figure that just after a tournament deadline is the ideal time to add new basic infrastructure.

blocking an expansion

What is the ideal place for one of your units—a spider mine or a burrowed zergling or a pylon or e-bay in blocking position—to block an expansion? Steamhammer uses the center of the resource depot location, and as far as I’ve seen so do all other bots. But play a game against the built-in AI and burrow a unit there: It cheats and knows about the burrowed unit, and simply offsets its resource depot to avoid it. Krasi0 also has the skill to offset its resource depot, it just has to scan first. Mining is less efficient, but the base does go up.

Maybe the ideal place is one that forces the opponent to offset its building as far as possible from the right location. If the minerals are in a line to (say) the north of the base location, then let your blocker overlap the southernmost row of tiles where the resource depot should go. That forces a displaced resource depot as far from the minerals as possible. Similarly for the geyser. In a circular base layout, as found in the center of some maps, one or two burrowed units could block the entire circle.

I’ve seen pros place blocking buildings off-center like that to dissuade the opponent from displacing their resource depot. A bot could do a search to find the placement that forces the depot as far as possible from minerals and gas. The answer is different for a spider mine or burrowed zergling than for a building.

There are other considerations. The blocking unit provides vision; maybe you can place it so that it sees everything that comes down the enemy ramp. For a pylon, maybe you want to put it as near the natural choke as possible so that you have a better chance to send units in to defend it, or to use it to power a gateway or shield battery that might be out of enemy sight. That kind of thing.

Eh, not a big issue for any bot. But it reminds me how complicated the game is. In the long run, we have to seek methods that can weigh many considerations—and nothing stops us from seeking the methods now.

Steamhammer 2.4.2 change list

Steamhammer 2.4.2 is available as source from Steamhammer’s web page. The documentation is updated too. As far as game play goes, it is identical to version 2.4.1 in the SSCAIT annual tournament. The main difference is that Steamhammer can automatically recognize when it is running under SCHNAIL and treat its opponent as a human.

I hope SCHNAIL testers will let me know how it goes, so I can adjust the behavior against human players.

Here is what’s new.

configuration

  "Skills" :
  {
    "SCHNAILMeansHuman"       : true,
    "HumanOpponent"           : false,
    "SurrenderWhenHopeIsLost" : true,

    "ScoutHarassEnemy"   : false,
    "AutoGasSteal"       : true,
    "RandomGasStealRate" : 0.0,

    "Burrow"             : true,
    "MaxQueens"          : 1,
    "MaxInfestedTerrans" : 0
  },

• The SurrenderWhenHopeIsLost, ScoutHarassEnemy, AutoGasSteal and RandomGasStealRate items are moved from the Strategy section to the Skills section of the configuration file.

• An internal flag Config::Skills::UnderSCHNAIL is added. It does not appear in the configuration file but is set by code. It is true when Steamhammer detects SCHNAIL’s schnail.env file in the read directory. Code can use this to do something different when running under SCHNAIL; it may be useful someday.

• A flag SCHNAILMeansHuman is added. If UnderSCHNAIL and SCHNAILMeansHuman are both true, then Steamhammer overrides the configured value of the HumanOpponent flag and sets it to true.

In other words, if you set SCHNAILMeansHuman to true, then whenever Steamhammer is running under SCHNAIL, it will assume that its opponent is a human. That should almost always be what you want. If it’s not what you want, you can turn off SCHNAILMeansHuman and set the HumanOpponent flag by hand.

• Steamhammer messages “gl hf” at the start of the game if it thinks the opponent is human. It actually wishes the human to have bad luck and suffer torment (BLAST), but it doesn’t mind lying. The real purpose of the message is so you can tell whether the HumanOpponent flag is turned on when it should be.

• The game message was formerly messed up. I think I finally fixed it.

• In the IO section of the config file, I separated Config::IO::PreparedDataDirectory (bwapi-data/AI/om/ for prepared opponent model files) from Config::IO::StaticDirectory (bwapi-data/AI/) for reasons of what I prefer to call clarity. The change doesn’t affect anything but a name in the code.

Steamhammer 2.4.1 change list

Steamhammer 2.4.1 is the version for the SSCAIT 2019 tournament. Version 2.4.2 with source release should follow shortly with only one significant change, SCHNAIL recognition.

For the tournament, I replaced the SSCAIT learning data with data from BASIL, because BASIL has more games that are recent. There are downsides; it could be that it was a mistake. I made a small number of hand edits to the learning data. For example, for StyxZ, I deleted games from before Styx was updated and suddenly became strong. I edited data for 7 opponents in total, usually just altering one game record.

First an explanation of my supposed Killer Feature, then the change list proper.

the Killer Feature

The “Killer Feature,” which is no more deadly than your average killer app, is to burrow zerglings at bases that the opponent is likely to want to take soon. CherryPi did this a couple of years ago, and I was surprised that bots which know how to cope with spider mines laid to block base locations were often unprepared for burrowed zerglings doing the same thing. Two years later, bots which remain unprepared may get into trouble. Burrow has many many uses, and Steamhammer will take advantage of more of them in the future; in choosing a burrow skill, I am looking ahead. There are 3 parts to the system.

The strategy boss by default researches burrow after Steamhammer takes its third base. If the opening build takes three or more bases, it starts the research shortly after the opening. This is late enough in the game that the research is not a major expense, but it does lose the opportunity to exploit burrow early on.

The 9PoolHatchBurrow opening researches burrow much earlier. It is for use against opponents which may be vulnerable. 9PoolHatchBurrow is a variant of the Styx opening which collects 200 gas instead of 100 and researches burrow immediately after zergling speed, trading some of the zergling punch for the burrow ability. The two upgrades finish at almost the same time, because burrow (1200 frames) doesn’t take as long as speed (1500 frames). The aim is to get burrow early while pressuring with zerglings, and try to burrow a zergling in the enemy’s natural to delay or displace the expansion and mess up the enemy’s build. Burrow normally finishes before the enemy has scan or observers, so even an opponent which knows how to react may be delayed.

I tweaked the learning data so that this build will be given a try against a few opponents.

The Watch squads are for scouting and base denial. The design attempts to gain the most impact with the least investment. The combat commander creates from 0 to 4 Watch squads (depending on Steamhammer’s ground strength and other factors) of 1 zergling each, and assigns the squads to watch the bases closest by ground to the enemy main. It may also assign overlords to watch further bases, but usually by the time there are overlords to spare, it is not safe to assign them. A Watch squad behaves like any other squad, except that if a squad member finds itself at the order position and is able to burrow, it does. (It’s literally a few lines of code.) Once at least one zergling is under the ground, the combat commander attempts to keep the most important Watch squad on station despite any reverses, because to disband it would throw away the investment.

When Steamhammer decides to expand to a base, any Watch squad stationed there is disbanded immediately. The zergling unburrows and joins the ground army long before the drone trundles in to make the hatchery. The disbanding is 1 line of code in a condition in the combat commander, and the unburrowing and leaving is standard behavior that was written into the squad long ago. The whole Watch implementation is as simple as I could make it.

I’m eager to see how the Watch implementation works in practice. When Steamhammer faces a full range of opponents, the results of a new feature are always more complicated than I see in my testing.

configuration

• I added a new configuration section Skills which is intended to separate out some items from the long Strategy section. For now, it has Burrow, MaxQueens and MaxInfestedTerrans items. Later I’ll move some items over from Strategy.

For this SSCAIT, Burrow is true, MaxQueens is 1, and MaxInfestedTerrans is 0. The strategy boss is willing to make up to 2 queens, but I decided that the second one probably costs more than it is worth for now. Steamhammer has a bug in the production system that prevents it from making infested terrans, so it’s better not to try.

infrastructure

UnitInfo keeps track of whether a terran building was lifted when it was last seen. For some reason I resisted doing this earlier, but it’s important information. The first use is in squad targeting, when checking whether an enemy building is a good target for a given squad.

• Another use of the terran lifted building info is a new skill: If all known enemy buildings are lifted and all known enemy units are air units, Steamhammer will only include anti-air units in its unit mix. It sounds obvious, but ultra-ling is a potent way to finish off a zerg or protoss which has only air units left, and is only weak versus terran that has lifted buildings. This skill is intended to solve a rare difficulty in finishing off a terran—I have seen it happen in only 2 games.

• Don’t try to expand to a base which is known to be blocked by an enemy building or burrowed unit. There’s no point in sending a drone to build on top of a spider mine which has been scouted. This also, of course, checks whether the building is lifted.

• Efficiency fix: Use base->getTileDistance() precalculated ground distances in some places instead of recalculating the distances.

Config::Debug::DrawMapDistances now draws tile distances from its current main base rather than from its starting base. You can see what Steamhammer considers to be its current main base, which may change during the game.

• I removed the unfinished and unused Region and Regions classes. I had forgotten they were there.

zerg

Research Burrow, if enabled in the configuration, usually just after the third base is taken. The strategy boss will delay the research for some emergencies or if the economy doesn’t justify it.

The Watch squad scouts and denies bases. It is implemented for zerg only. Other races don’t have enough cheap units to dedicate some to sitting around, and are better off with the Recon squad alone.

A critical bug in upgrade checking could cause production freezes. Ouch. Fixed.

• In ZvZ, get +1 melee attack instead of +1 ground carapace as the first ground upgrade. It’s cheaper, and it’s what humans usually do. I think the theory is that killing drones faster is more important than a small edge in resisting mutalisk bounce attacks.

openings

The 9PoolHatchBurrow opening is added. See above.

• Minor tweak to ZvP_3BaseSpire+Den. It gets 1 more drone.

Steamhammer and next steps

Last night I dreamed that my hatcheries came under air attack by fire-breathing dragons. I had to defeat them with scourge. Did you know that dragons are as tough as battlecruisers or carriers? Six scourge each, it takes a lot of gas to shoot them down!

Meanwhile, Steamhammer is ready for SSCAIT, and has been for a few days. I have been running tests, finding that all is good enough, and refusing to make other fixes or changes. SCHNAIL recently added a file so that bots can recognize when they are running under it, and I even skipped checking for that to reduce the small risk. The Killer Feature works as intended and causes headaches for some opponents, though by no means all. I expect it will be good for several wins, and certain amount of “Ah, now I have to be ready for THAT?” Whatever makes Steamhammer’s play more complex and interesting is worth having.

Immediate plans: Steamhammer 2.4.1 change list shortly after SSCAIT submission closes. Then Steamhammer 2.4.2 a little after with one more change, SCHNAIL recognition so that running under SCHNAIL automatically turns on the HumanOpponent flag. I’ll release source for the 2.4.2 version.

What should I do next? Here are the fixes that would make the biggest difference in the short run:

• Overlords, surprisingly, are not handed out for free. Keep them safe.
• Don’t transfer drones by the dozen through the enemy army.
• Correct gross weaknesses in defense.

The development plan calls for strategy adaptation work. Next steps I could take toward that include:

Improved scouting.
Production goals.
• Opening timing for decision making.

Then there’s the fun stuff. I wrote down about a dozen different tactical tricks suitable for zerg (and a few more that only other races can play), ranging from proxy hatchery to stop lurkers. Three of them are played by current bots, one other in past years by a long-defunct bot, so there is opportunity to surprise opponents. I imagine a bag-of-tricks meta-skill that combines information to decide when to try a trick: Map analysis (“aha, the main has a back door”), cost estimates and success rates, the game situation, and opponent model data. Of course it would record results in the opponent model, so it could learn how to exploit different opponents. That would be cool in itself, and it would also provide a way for forks to customize their behavior.

Looking over the possible next steps, I see some overlap. Overlord safety, drone transfers, and improved scouting all benefit from pathfinding skills. Pathfinding is basic and can improve all movement decisions, so sooner is better. Path analysis skills are useful for many of the tricks. Also overlords are good for scouting, so overlord safety and scouting are closely related. I think I will add pathfinding and overlord skills soon.

prep for the SSCAIT annual tournament

I’ve disabled Randomhammer on SSCAIT in preparation for the tournament. It’s less than a week away.

For Steamhammer, I am trying to overcome my usual deadline intolerance. I fixed one critical bug, and now I am concentrating all my effort on my Killer Feature. Whether it will kill anything is an open question, but it will be fun, and above all it should be finished and tested and tuned by the deadline. I’ll be satisfied if it can catch out a few strong opponents.

As usual, the big improvements promise to arrive after the tournament. I am adding, or on the verge of adding, basic skills that promise stronger play, and it is impossible to exploit new skills fully in a short time. I expect to soon have the infrastructure needed to add nydus canal support, though I don’t know whether I’ll actually add it soon. Nydus canals make island bases much more useful. I am very tempted to delay strategy adaptation work to add a bag-of-tricks meta-skill that knows how to select from a bag of tactical ideas to pose problems to different opponents. I know a lot of tricks that promise to be effective in specific situations.

In the arena of unimportant abilities, it’s tempting to fill out the queen skills. Steamhammer is capable of controlling a fleet of queens simultaneously without blowing out the per-frame time limit, but they tend to all simultaneously broodling the same target. Queens tend to carelessly fly into danger and die, and at the same time do not know how to fly around freely and seek their own targets—they wait for targets to wander into range. A bug in the production system prevents Steamhammer from producing infested terrans, but I’m not fixing the bug yet because it doesn’t have the skill to control them properly. Infested terrans are powerful but must be used carefully, for example dropped from overlords or coordinated with defilers. That’s something I may work on gradually over the next year.

Upcoming: I want to time a few other openings the same way I timed the Styx opening, to compare them. I think it will be enlightening. And I still hope to get back to the AIIDE tournaments and do more analysis; we’ll see if I can pull it off.

timing the Styx build and variants

Here’s a table of variants of the Styx build. The left one, 7 drone hatchery first, is the original; the other 3 are natural variations. The story from Dan Gant is that an entire population of machine learning agents all converged on the original build, so according to those agents, it’s the best choice. I won’t accept their opinion without checking. Steamhammer, of course, includes all 4 of these builds, and has additional decorations beside.

step7 drone
hatch 1st
7 drone
gas 1st
8 drone
hatch 1st
8 drone
gas 1st
15 x drone (9 total)
2spawning pool
3drone (back to 9 total)
4extractor trick (10th drone)
5overlord
63 x zergling
7hatcheryextractorhatcheryextractor
8extractorhatcheryextractorhatchery
94 x zergling2 x zergling4 x zergling2 x zergling
10metabolic boost (zergling speed)
11keep making zerglings

The 4 variants differ in 2 features. Feature 1: The 8 drone variants, on the right of the table, throw in an extractor trick (step 4) to get an additional drone, leaving the zerg with 8 drones mining at the end of the build rather than 7. Feature 2: You’re making both a hatchery and an extractor, and you can make them in either order (steps 7 and 8). Hatchery first means the hatchery finishes a little earlier and may be able to raise the zergling count a little. There are also timing effects because of the different number of zerglings made (step 9) before starting zergling speed (step 10).

The machine learning agents concluded that the leftmost build is best. My intuition is that the rightmost build is best: The extra drone from the extractor trick doesn’t help at first, but provides more flexibility in the long run (in case you don’t win outright). Getting gas before hatchery barely delays the hatchery, because the extractor does not finish before the hatchery starts, but gets zergling speed significantly earlier, which I feel outweighs the couple extra zerglings you may gain by getting hatchery first.

I’m not trusting my intuition without checking, either. This post is about measurements. I can measure timings. I can’t measure which variant is objectively stronger, because it depends on the skill of the player. PerfectBot is not available to tell us. Are you better at taking advantage of zergling numbers, or zergling speed?

All tests were run on the map Heartbreak Ridge. I didn’t use Steamhammer’s existing builds, but wrote special ones to reduce variance. Each build calls for exactly 40 pairs of zerglings. There is no drone scouting. The second hatchery goes in the main base because long drone movements will vary more. Overlords were inserted by Steamhammer’s usual method, which is heuristic but consistent. Zerglings stayed put and did no fighting so that overlords were made at predictable points; I disabled the Recon squad and convinced the opponent to also stay home. Building placement is different between the 2 starting bases on the map, so I only timed games from the 9 o’clock base. Zerglings gathering around the main hatchery interfered with drone movement when placing buildings and caused variations in the timings, so I had them gather at a distance. I recorded data for 5 runs of each build.

Zergling speed timing: The frame when metabolic boost finished upgrading. The gas-first builds get zergling speed over 330 frames faster, around 14 seconds at 24 frames per second. That’s a long time during a game, but don’t forget that it is only a window of opportunity. If there is any advantage to be gained by a gas-first build, it must be gained during that interval. With hatchery first, the extractor trick to gain the 8th drone causes a 100 frame or 4 second delay, which is much more than I expected. With gas first, the extractor trick causes no measurable delay. Now that’s interesting.

buildmedianlowhigh
7 drone hatchery595559416003
7 drone gas562155915659
8 drone hatchery605560546092
8 drone gas562155945633

Zergling timing. For each build, I took the run with the median timing of zergling speed from above, and put only that data into these charts. The initial 6 zerglings happen after the extractor trick and before the hatchery/extractor decision, so only the 7 drone/8 drone division between the builds is meaningful. The numbers say there may be added variance in the extractor trick causing some delay on average, but no necessary delay. The 8th zergling (the fourth pair) comes after the hatchery and extractor and before zergling speed. For the hatchery first builds, zergling speed finishes after 22 or 24 zerglings have been produced. For the gas first builds, after 16 or 18 zerglings.

This scatter chart shows how similar the four variants are. The x axis is time, y is the zergling count. Blue is the original 7 drone hatchery first build. The other colors are visible a bit around the edges of the blue. The initial 6 zerglings appear at the lower left in a column. There are visible gaps where overlords are made.

scatter chart with very little scatter

Here is a more useful visualization. I subtracted the blue timings from each build and plotted the residuals. A point above the horizontal zero line means that that build was later than the 7 drone hatchery first build to reach that specific zergling count. A point below the line means it was earlier. The vertical axis gives the frame difference. 40 points are plotted for each build, one point for each zergling pair from 1 to 40.

scatter chart with very little scatter

The original blue build is quite good at pumping out lings. It is ahead of the others at more timings than not. But every build is ahead at some timings. The regular spikes are related to overlord spawning. If you are fighting hard you will not need to make overlords, and the results may be different. You can think of each timing when a build is ahead as a window of opportunity, and compare the zergling count windows to the zergling speed window of 14 seconds for the gas-first variants.

Extra minerals. The 7 drone variants are just about perfectly tuned to balance mineral income and larva production from 2 hatcheries. After starting 40 pairs of zerglings, less than 50 minerals are on hand and the larva count is 0 or 1. That means that the 8 drone variants cannot gain an edge in zergling production, even in the long run. Instead, the 8th drone allows flexibility in case the build does damage but does not win outright; the player has more resources to switch into another line.

After starting 40 pairs of zerglings, the 8 drone variants have banked about 400 minerals. Normally, you’d prefer to spend them before getting that far. One idea is to spend the minerals on a sunken—perhaps an offensive sunken against zerg. Another is to add a third hatchery, pause zerglings briefly to make a few drones to keep the hatchery fed, and go back into zergling production at a higher rate. Another is to put the 8th drone on gas and prepare to suddenly switch into a tech build.

a couple games to distract you while I work

I have to write some code to analyze the Styx opening and its variants. Don’t get bored though, here are a couple Steamhammer games to tide you over.

When Locutus plays its dragoon unit mix, it knocks over Steamhammer with no apparent effort. In Steamhammer-Locutus on Heartbreak Ridge it instead chose a zealot-archon unit mix, and brought about a tempestuous brawl. Something similar happened in one AIIDE game.

In Steamhammer-Ecgberht on Fighting Spirit, Steamhammer was clumsy and fell into a losing position. But Ecgberht was not faultless either, and Steamhammer held and started to fight back. Watch the adventures of the zerg queen.

Steamhammer scouting thoughts

Good scouting is a prerequisite for strategy adaptation, and right now Steamhammer’s scouting skills are mediocre.

The ScoutManager controls early game scouting. In the original UAlbertaBot, the scout manager controls the worker scout. Steamhammer extends it to also control one overlord—and that’s all. It coordinates the two units to scout efficiently, but it can’t make use of the zerg’s second overlord, much less any other unit. Furthermore, the scouting paths don’t extract as much information as possible. When the scouting overlord arrives, it sits in one place and has no chance to see buildings started far away. The scouting worker does explore the base, but doesn’t evade defenders and often gets stuck on buildings. The enemy natural is scouted incidentally, if at all.

Steamhammer scouts in the middle game with its Recon squad, a small group of combat units that visit empty bases to see if perhaps they are no longer empty. The squad attacks any undefended buildings or weak enemies that it happens across, and the behavior of zipping across the map in every direction incidentally finds and interferes with a lot of enemy activity that would otherwise go unnoticed: Enemy scouts, abandoned proxy buildings, worker transfers, isolated reinforcements.... The Recon squad is effective, it doesn’t need any changes for now. But it should not be the only form of middle game scouting.

Steamhammer does no deliberate scouting of known enemy bases (after the early game scout), or of possible enemy movements (ever). It sees the enemy move out because its army is normally trying to push forward as far as it can, and it learns what is in the enemy base when an attack reaches that far (or occasionally when it parasites a unit that returns home).

There is a connection with overlord safety. Steamhammer does not know that most maps provide overlord posts where a correctly positioned overlord can safely watch passing enemies. Wraiths or corsairs spoil the party, but until then overlords can ordinarily see when the natural is taken, and see enemy units move out, and spot them as they pass key points, without danger and often without being seen in return. I don’t know of any bot that takes proper advantage of overlord posts.

what do do?

Some bots have a thing like a scout squad: If you want to look around the map, throw whatever units you prefer into the squad, and the squad coordinates them. That’s a step up in generality from Steamhammer’s scout manager.

The scout squad has decisions: Run around the map, or post units at key locations, or some of both? Just look, or harass or fight when it makes sense? If planning to fight like the Recon squad, how big should the groups be? For example, when a pro scouts with scourge, they commonly send 2 scourge, and if a corsair shows up, the scourge have a point to make. The simple scheme of dispatching individual units around the map doesn’t do everything you’d like.

I’m thinking of implementing scouting with 2 squads plus a scout boss that can hand off scouting goals to other squads.

The Recon squad would be little changed from now.

The Watch squad would be responsible for watching over key points with more or less stationary units. It might post single zerglings in likely enemy expansions, or set units to oversee choke points. Like the Recon squad, it would feel free to fight when it saw an advantage—you want to expand here? Fine, see if your probe can beat my zergling. The Recon squad would only visit bases that are not being watched. The size of the Watch squad might be 1 zergling early, and it might replace the Recon squad entirely later in the game. Steamhammer already has some code for the Watch squad, but it’s not in a usable state.

The Scout Boss would maintain goals: A set of things that we’d like to find out if we can, with priorities. At the start of the game, the goals would be to explore starting bases to find the enemy. When the enemy is found, some goals disappear and new goals appear to seek out what the enemy is doing. Later in the game the set of goals could become extensive—we saw a zealot at (x, y), is it still there? Ideally, in Candide’s best of all possible worlds, the Scout Boss should be smart enough to tell when it is worthwhile to sacrifice a unit for more information: How big is the enemy army? Run one zergling in. How many barracks are in that base? Sacrifice an overlord to find out.

A Scout squad can ask the Scout Boss for its goals. So can other squads. When Steamhammer’s mutalisks back away from an over-strong enemy force, they assume that the force will stay there and they remain backed away, wasting time doing nothing. The Scout Boss will want to know where that force goes, and can prompt the mutalisks to return and look. Or the Scourge squad can accept scout goals, and the Scourge squad has the knowledge that scourge should commonly fly around in pairs—or in triples if expecting scouts, something a general scout squad should not have to understand. (2 scourge kill most flyers, but a scout needs 3.)

Anyway, that’s the line I’m thinking along. Maybe I’ll start on it in January.

Soon: Analysis of the Styx opening and variations.