archive by month
Skip to content

follow-the-leader doesn’t always work

Steamhammer divides its units into squads (like many bots), and gives each combat squad orders to try to reach a target position, such as an enemy base. The system is inherited from UAlbertaBot. A squad may have units all over the map, such as some at the front line and some just spawned, and units in different places face different situations. So Steamhammer divides a squad into clusters of units and tries to make appropriate decisions for each cluster, depending on whether enemy units are near and so on. The clustering has been in place since fall 2018; see Steamhammer 2.0 squad unit clustering for the description, which is still up to date in everything it says, though some details have changed behind the scenes.

I want Steamhammer’s clusters to join up when they can, so that the army fights together. So it uses a follow the leader rule: The frontmost cluster, the one closest to the target position, is the leader. Other clusters, if they are not distracted by enemies nearby, try to join up with nearby clusters that are more forward, and ultimately with the leader. In other words, clusters don’t independently seek out the target position; their first priority is to merge into a big scary army that will win. Compare Steamhammer’s tactical habits with, say, Dragon, which feels freer to scatter its units across the map.

Thinking about nydus canals, I noticed that following the leader doesn’t work in all cases.

sketch of situation with nydus canals and enemy attack

The enemy is attacking a base with a nydus. A squad is ordered to defend. Cluster 1 is closest, because it can jump through the nearby nydus to reach the base. Cluster 2 does not want to follow the leader; it wants to travel by ground, not by nydus, because that way is closer for it. Cluster 2, to follow its defense order, should attack (or at least threaten) the enemy from the rear.

Nydus canal is not the only way to break follow-the-leader. Imagine a target position with two separated entrances, like an edge base on Fighting Spirit. If two clusters find themselves at different entrances and want to attack, each should probably attack its own entrance.

I don’t know how I’ll end up fixing this. There is time to think about it. A related and more immediate issue is how to attack the same enemy position from two directions at once, which Steamhammer currently can’t do except by accident. I’ll solve that by analyzing which clusters are attacking the same enemy units and doing a joint combat sim, so that all attack together or all retreat.

AIST S4 prep

Today I received my acknowledgement that Steamhammer is registered for AIST S4. It will play, if the creek don’t rise.

I haven’t been posting about Steamhammer progress because I’m preparing (ssh! it’s a secret!) Secret Improvements. When the list of participants is announced, I expect I’ll make special arrangements for some of them. Steamhammer should be a moving target so that the same doesn’t happen to it.

The improvements I’ve made already are significant, and I’m finishing up another good one today. I’m hoping that, unlike the other two times Steamhammer participated (S1 and S2), it won’t be knocked out at the first opportunity and end up in last place, or tied for it, with 2 match losses. (In S3, the rival Microwave played instead and got the same result.) I don’t want to get used to being pushed over like a cardboard cutout.

I’m also hoping that by submission time at the ominous Ides of March, Steamhammer will have collected enough opening data that I can decide what to do about it next. I’m still forecasting that I’ll need a second collection phase to fill in gaps. Plus I’ll need a long-term plan to keep the data updated as Steamhammer’s skills progress.

practice games on SCHNAIL

Recently a not particularly skilled protoss played more than 20 practice games versus Steamhammer on SCHNAIL, winning 3 and losing the rest. I went through the games in sequence. Steamhammer put its variety of builds to good use, sometimes 4 pooling, sometimes busting with one or another kind of all-in, sometimes defending then countering, sometimes building up then rolling everything down with hive tech. I was mostly pleased, though tactical clumsiness was an issue. In the most spectacular game, protoss aggressively attacked, destroyed and held the zerg natural, built a gateway and nexus there and started mining the zerg’s minerals, and found and cleared the only other zerg expansion. Steamhammer held its main with sunkens and units, used an escaped drone to lay down another expansion that protoss did not find, teched to lurkers, pushed down its ramp to free its natural, defeated the dragoon army, and won with the one big counter. That must have been frustrating for the human player, who apparently did not have the multitasking ability to both micro the dragoons and get observers in time (a difficult skill to learn, if you ask me, because multitasking is not natural for humans). Yet game after game followed.

Looking at it from the human player’s viewpoint, protoss started with a not very convincing gateway and forge build with no cannons. After Steamhammer easily busted it a few times, protoss started experimenting with other plans. Some were defensive, like holding with cannons and trying to expand by shuttle. The more successful were aggressive, like the game above. Over the long sequence, I thought I could see the human player’s skills slowly sharpening, with more consistent macro and more appropriate strategies. Stronger players quickly notice Steamhammer’s weaknesses and exploit them, but this was a player who hadn’t reached that level of knowledge yet. It takes experience to build skills, you have to work through all the stages.

SCHNAIL is great for this, I conclude. If you can find a bot at your strength level or above, but not hopelessly above, and with some variety in its play, you may have a good practice partner. You can polish your basics and learn what kinds of plans work and try out new ideas. If you find yourself winning most games, then I guess either you’ve improved that much or else you’ve learned to exploit the bot’s weaknesses. I’d say if you want to keep improving, it has become time to look for your next opponent.

Randomhammer’s matchups

Here are Randomhammer’s win rates on BASIL. Randomhammer’s race is on the left, opponent race across the top. X means overall. Win rates are good for comparing matchups of a single bot, but because BASIL assigns different mixes of opponents to different bots, they can’t be compared across bots. You could compare across bots by computing elos per matchup.

vTvPvZvX
T31%27%54%39%
P58%51%75%63%
Z73%60%71%69%
X53%45%66%58%

Z is the best race, of course, since zerg is Steamhammer’s main race. The vZ matchups are the best versus any, because I understand better how to play against zerg and because I want Randomhammer to be a good test opponent. But PvZ is above every Z matchup and far above ZvP! No matter what race Randomhammer rolls, vP is its worst matchup.

protoss is easier

In 2016, I offered my opinion that zerg was the easiest race to code a good bot for. Later I started Steamhammer, and backed up my claim with results: A year after my post, Steamhammer was one of the strongest bots on the ladder, thanks to efficient build orders and adaptive midgame unit mixes, which were unusual at the time. (Today’s Steamhammer is far stronger than then in absolute terms, but does not rank as high because the rest of the community moved faster.)

Of course that doesn’t prove I was right; maybe I did a good job and made it look easy. While Steamhammer was on its rise, I made another post comparing average ratings, which offered some evidence that protoss is easier for most people. Which is the most common opinion.

Today we live in a different world. For a bot to count as “good” it must have more and sharper skills than then, and fewer bugs. And the zerg skills needed to win today are more difficult to code than those of 2016 and 2017. I again have results:

Randomhammer win rates by race

These are Randomhammer win rates on BASIL. Zerg wins over 65%, protoss wins up to 65%, and terran wins... around 40%. There is far more effort, there are far more lines of code behind zerg-specific skills than behind protoss skills, but protoss is nearly as strong. I put roughly similar effort into terran and protoss, but terran is far weaker. Today, a good bot is easier with protoss.

experience with SCHNAIL

I’ve been keeping an eye on SCHNAIL by Sonko for human-machine play. The interface is not pretty like BASIL, but it works. Few games are played, by comparison with SSCAIT and BASIL; on the days I counted games, between 64 and 111. Humans—it’s shocking but true—are somewhat slower than computers. A game on SCHNAIL can be “practice” or “ranked”, with different rules. Sonko was surprised early on that nearly all games were practice. I guess it makes sense while people are first trying out something new. Today most games are still practice games, but there is a good mix of ranked games too and most bots seem to have properly established ranks which are not very different from their ranks on BASIL. The ratings look different, though, since the midpoint is 1500 instead of 2000—and humans are better, so the bot ratings are mostly below 1500. The ratio of practice to ranked games varies depending on how popular the bot is to practice against: BananaBrain is popular and has 12% ranked games, while tscmoo is not and has 61% ranked. Some bots have few total games and no believable ranking, probably because they don’t work reliably, and probably should be removed from the rankings.

SCHNAIL supports 22 maps, at least notionally: The 15 SSCAIT maps (including Electric Circuit, which is disabled on SSCAIT) plus a handful of newer maps. I was not able to find any successful games on the maps Tres Pass or Core Breach. Perhaps they use features from Broodwar Remastered? Or do so few bots support them that none has succeeded there yet? The bot upload page comes with checkboxes so you can specify which maps the bot can play on. I didn’t realize at first that the checkboxes scrolled; a more rectangular arrangement would be easier to use. Anyway, my uploads are set to play on all maps except the two broken ones and Electric Circuit, where they run into pathing trouble.

In a practice game you choose your opponent; in a ranked game, SCHNAIL makes the match, trying to choose a bot near the human’s strength when it can. I thought there was an element of randomness in the ranked matchmaking, but if so apparently it is not a large element. I often see streaks where the human is matched against the same bot repeatedly. It makes a difference, too; humans learn fast and adapt their play to what they are facing, and I sometimes see the same pattern in ranked games as in practice games, where the human loses several times and then figures out how to win.

Steamhammer has only a handful of games since it was updated; most days it does not play at all. Nevertheless, some of the games are ranked games, and its rating has climbed. In ranked games SCHNAIL is still matching Steamhammer against players below its current strength, and its rank will likely keep climbing for a while.

The weaknesses I see in Steamhammer’s play versus humans are about the same as the ones I see in its games against other bots. But humans pick up on weaknesses more easily, and exploit them more consistently, so the weaknesses look bigger. It’s useful, actually. I have changed some priorities after seeing games. One protoss at first struggled against Steamhammer’s macro, but after a few games realized: Put a little pressure on, and then Steamhammer can’t defend its expansions, hydras don’t think they can get there. A couple more games, and it was: Cannon the expo while zerg can’t respond, then maybe take it for protoss. Bots aren’t that smart!

Randomhammer was indeed a newer version than Steamhammer at first, explaining why it was rated a little higher. Since then I’ve updated them both, of course. I had to ask to be given control of Randomhammer, but it was no trouble. Randomhammer has no games since it was updated. Human players may be different, but BASIL provides the best available forecast: The win rate graph shows protoss not far below zerg, with terran stuck in the mud far behind. I think the big difference must make terran less fun to play against.

Crazyhammer is a just-for-fun Steamhammer zerg configuration that I uploaded to SCHNAIL yesterday. It is set to choose randomly from its library of over 200 zerg openings, paying no attention to the matchup or the map or anything. I set it to practice-only, since it is in no way competitive. Play a game and be surprised; Crazyhammer might accidentally play something sensible, or it might play a protoss build like 4 hatches before lair against your zerg.

Will it be ordinary 2 hatch muta—or queen rush, or 5 hatches before pool, or 7 pool hydra rush, or...? Chooses utterly at random from a huge library of sensible and insane builds. For weirdness!

As a taste, there are 2 builds starting with 4 pool, 3 with 5 pool, 5 with 6 pool, 8 with 7 pool, 4 with 8 pool, and 18 builds with 9 pool. If I counted right. At the opposite end of the macro spectrum, there are 4 builds with 5 hatcheries before pool, 1 with 4 hatcheries before pool, and 11 with the more reasonable 3 hatcheries before pool. The bulk of the options lie between the extremes. Most of the openings counter something and make sense in some situation, however rare, but a few are pure nonsense thrown in for the hell of it. The two-base ultralisk rush has no known use, and the 7 pool mutalisk rush might beat you if you are a sworn pacifist. Some of the ideas I have never seen anywhere, from bot or human. I hope players will enjoy sampling a little of the prodigious variety.

Crazyhammer has been chosen for 1 game so far, a ZvZ where it went with a perfectly sober 10 pool, scouted the wrong way so that it failed to react to the enemy, and lost easily. Not crazy enough.

Steamhammer versus cannon rushes

In its earliest days, Steamhammer had some trouble with cannon rushes due to bugs that you might imagine are unrelated. See Steamhammer’s funniest bug from January 2017, when it was only a month old. Back then it had no learning, and I manually configured it to play 9 pool versus cannon rushers and other cheese bots. Once the basics of scouting and so on were straightened out, it worked fine at the time, except against AIUR by Florian Richoux, which alongside other builds sometimes does sneaky cannon rushes (still among the best cannon rushes by any bot, in my opinion).

When I added learning, Steamhammer became able to recognize the cannon bots and react on its own. No more manual configuration. It still countered with 9 pool, which is simple and reliable. When Juno by Yuanheng Zhu came on the scene, it caused little new trouble. Only AIUR, with its unpredictable builds, occasionally won by cannon rush. The other cannon bots were predictable and easy to stop.

Today it is different. Krasi0P switches between cannon contain to lock you into your base, and defensive cannons. MadMix can execute an impressive variety of offensive cannon builds: In your base, in your natural, outside your natural; containing or directly attacking without trying to contain; with forge in base or forge up front. The 9 pool still stops them all, provided the cannons have been spotted, but since the enemy build is unpredictable, Steamhammer doesn’t know when to play it. Well, it could play 9 pool every game, except that it doesn’t have the skills to adapt its play when it sees that the enemy has done something else. If there were about 16 of me, I might be able to work on everything at once....

The current Steamhammer has many different reactions to help it cope with cannon rushes. And it can still lose.

• If the enemy is predicted to proxy cannons, choose 9 pool or a similar anti-cheese build. That takes care of bots with only 1 build, and bots that play the cannon rush too consistently after it wins.

• Scout the main base and areas near the natural with an overlord. How this happens depends on game events, but typically the second overlord starts the work; it may be replaced by a later overlord if the second is called away to join units. With Steamhammer’s current skills, scouting the cannons early is crucial to reacting well. This scouting may in practice be the most valuable skill on the list—although objectively it’s often better to send the overlord to scout the enemy.

• Recognize all nearby cannons, out to beyond the natural, as rushes. Early Steamhammer versions only noticed cannons in the zerg base, because that was all it faced back then.

• Recognize a forward forge as an incoming cannon rush. There is no other reason to build a forge near the enemy base. (Now we get to see if any bots make a pylon and start the forge when it is in vision, then cancel it, to spoof a cannon rush. Would Steamhammer overreact?)

• If a forge or unfinished cannons are near the mineral line, pull drones to attack. Steamhammer doesn’t pull drones far, though. I haven’t felt inspired to do the calculation of when workers reach the cannons versus when the cannons complete.

• If cannons are scouted before the spawning pool has been placed, start the pool ASAP, canceling stuff if necessary. This is often objectively an overreaction, but with Steamhammer’s skills it’s usually a good decision in practice.

• If a cannon appears near a zerg base, any base at any time during the game, place exactly one sunken to prevent the cannons from pushing closer. All bots that use cannons offensively also like to cannon push—except Steamhammer protoss, which prefers to add a gateway. MadMix can sometimes push cannons around the single sunken and reach a vulnerable point in the zerg base, so the defense is not airtight.

• Send a drone to a hidden base location if possible, and the next time we want to expand, expand to that base. If the scout drone is out scouting, it will be the one assigned. If we’re contained we’ll be able to produce units outside the containment, and if the main base is killed by cannons, we’ll have a distant base that protoss will have to find and deal with separately.

• Don’t assign units to the defense squad to kill cannons, assign units to an attack squad to go kill the enemy base. So far, I have seen no cannon bots defend the main with cannons—and, well, Steamhammer’s hidden base is hidden.

• If the enemy has no known mobile anti-air units, send overlords to watch over vacant bases on the map. This is also an anti-cannon skill! Steamhammer has lost games after killing the enemy main by not noticing that protoss had another base—zerg units gather to kill the cannons, the last known enemy buildings, which may take a long time and let the enemy recover.

• When there are cannons on the map, prefer hydralisks over zerglings. They’re more efficient versus mass cannons. Steamhammer is slow to switch, though, and often overproduces zerglings regardless.

That is a lot of skills! And they work fairly well and win most cannon rush games. How does Steamhammer still lose games? Mainly by blundering into cannons. Drones leaving the base to build don’t notice the cannons and die. Drones trying to transfer to the outside base do notice the cannons and mostly stay out of range, but clog up movement for other units. Safe movement is not perfect and loses some. Attacking is sloppy and loses more. Defense has a horrible bug which sends warriors through the cannons without fighting. I’ve concluded that threat-aware pathfinding is necessary, and that it has to be hooked into production so that Steamhammer doesn’t do things like make more drones in the main than it can support—it has to know whether it can transfer them out before it decides to produce them.

In other words, the losses are due to bugs that you might imagine are unrelated. If only there were 16 of me!

the Steamhammer-Krasi0P match

Yesterday’s loser’s round match KrasioP-Steamhammer ended up with the result I expected, but not in the way I expected. Krasi0P has two builds, cannons in base and proxy cannons. Steamhammer can easily beat either one if it correctly predicts it, but it is poor at predicting. The wins tend to go in streaks, Steamhammer loses a bunch in a row then wins a bunch in a row, because both bots are somewhat slow at reacting when the opponent’s build switches. And Steamhammer’s recent games against Krasi0P, the 2 games in the SSCAIT round robin, were losses. So most likely the losing streak would continue.

1-1 after the first 2 games was good. In the last game, my initial diagnosis was the same as the commentator’s: Steamhammer was going to play 1 hatch muta, an excellent choice that should win. I was suddenly looking forward to a surprise match victory. But when I saw the second hatchery start, I knew something had gone wrong. Steamhammer ended up playing a nonsense build that countered nothing, a sure loss. After seeing the cannons it should have turned a few planned zergling pairs into drones; that part looked OK. I’m not sure what failed, but my best guess is that something caused Steamhammer to break out of its opening build and fall back on the strategy boss, which is buried up to its neck in ZvP weaknesses (it’s Steamhammer’s weakest matchup). Those mistakes look like strategy boss mistakes. But nothing I saw in the game should have caused it to break out of the opening. It may be a bug I haven’t seen before.

In any case, the fixes in version 3.3.6 made Steamhammer substantially stronger against Krasi0P (and many other opponents). Steamhammer will look impressive if it ever gets into a tournament with all the major bugs fixed before instead of after....

Really next, no really, this time I mean it: Steamhammer’s experience versus cannon rushes.

new bot Boris

Yay, we got a new bot!

Zerg bot Boris gives its author as “Airstrike” Ivanov, and says “first attempt at a bot! Isn’t very smart at the moment.” Boris was made from scratch and its repo is open, and the author’s profile says “Wannabe programmer! Amateur game developer.”

Boris’s build seems to vary slightly from game to game, but it always starts with 9 pool, usually adds a second hatchery, and sometimes makes a third hatchery (I’ve only seen it do that when it is about to be attacked). All hatcheries are in base; it does not expand. It also never takes gas. It doesn’t have any kind of combat evaluation; units go find the enemy base and attack willy-nilly. The micro is not much, and if the initial zerglings make no impression then the enemy will swallow the followup zerglings, arriving 2 by 2, with no effort. In fact, as I write Boris has lost every game on BASIL (0-21) and its wins on SSCAIT (3-6) are all against opponents that failed to play.

In short, what we have here is a basic bot. It can play a complete game, but does not yet have much in the way of winning skills. It is a vehicle for something more interesting; it has gotten out of the driveway and onto the road, and has not yet driven anywhere. The path to make a top bot is long and steep, but the way to a bot that can win some games is not long at all. It’s in sight just down the street, getting out of the driveway was the hard part! Boris can probably start to win games with no more than a few bug fixes or refinements. I read the micro code that decides on targets, and I think it can be simplified and improved, and that that is probably all it will take to start winning. Keep at it!

funny fast burrow game

Randomhammer protoss has been rolling up opponents with its dragoon build, thanks to improved macro. Though there’s plenty of room to improve it further. Randomhammer terran looks as erratic as ever, sometimes wiping out zergs with efficient marine attacks but more often goofing around. Overall, a worthwhile update for the short time I spent on it.

I thought this game was funny: Steamhammer-Krasi0 on Empire of the Sun. Krasi0 opened with risky aggressive 2 barracks in the middle. Steamhammer, purely by chance, decided to play a build that it does not understand how to exploit properly, 9 pool speed burrow. Different burrow tricks are possible, but the main idea behind getting burrow so early is to run lings into the enemy main and use them to cause confusion and delay, harassing and then burrowing whenever in danger. This game did not go that way. Burrow finished just as marines entered the zerg main with murder in their eyes, and the rest was inevitable. It looked as if it had been custom crafted.

Steamhammer on SCHNAIL

I have felt fully busy with Steamhammer, with No Time For Anything Else, so I have been ignoring SCHNAIL. Besides, until I updated to BWAPI 4.4.0 I could not upload a new version anyway. Today I apparently felt less busy, because I logged in there for the first time since early days.

I updated Steamhammer on SCHAIL from version 2.4.1 (dating from late 2019) to the current version 3.4.1. The current version is far stronger against other bots, and it should be much stronger against humans too—though I imagine that some of the new danger-avoiding behaviors that are effective against other bots can be exploited by devious humans. The older version already had a HumanOpponent flag which is supposed to be set automatically when running under SCHNAIL. I have never verified that it works as planned. Maybe I should do that soon....

Unsurprisingly, the old Steamhammer ranks much lower versus humans than the current Steamhammer ranks versus bots. What did surprise me is that Randomhammer ranked higher than Steamhammer proper. Ever since Randomhammer was first uploaded to SSCAIT in 2017, I have never seen Randomhammer above Steamhammer. Steamhammer’s zerg is much stronger than its alternate races. It’s hard to believe that humans are worse than bots against random opponents, so maybe this is a newer version of Randomhammer? I’ll check that out too.

I watched a few replays. It was delightful to see some of the bot exploits that people attempted. Especially when they didn’t work.

Still next: Steamhammer’s experience versus cannon rushes.

Steamhammer 3.4.1 uploaded

As promised, I’ve uploaded Steamhammer 3.4.1 which has fixes that primarily benefit terran and protoss. I anticipate that protoss will be significantly stronger, terran a bit stronger, and zerg minutely better. For the debug display this time, I turned on drawing of worker info. Among other things, each worker is drawn with a letter representing its task, M for mining minerals, G for gas, B for constructing a building, and others (11 codes in all; the most obscure is Q for a worker which was posted to a location and tasked to build there).

I wanted to handle one more bug, a longstanding problem with terran addons, but I decided that the fix was too involved. This is enough for now. Next I’ll switch to prep for AIST.

expansions

Expansion timings changed for terran and protoss. There is a hard-coded list of timings to take bases. It bears little resemblance to good play, but I adjusted it to be less ridiculous (you may slightly lower the volume of your laughter). The new list, which is the same for terran and protoss in all matchups even though that’s silly, calls for a faster natural, slower later bases, and more total bases in the late game.

A bug caused terran and protoss to “expand to the main base” when contained, especially by cannons. A command center or nexus, or sometimes more than one, would be built in the main, where it stood for the rest of the game as a monument to the value of wasting resources. It happened often to terran, occasionally to protoss. I fixed one cause. I did not verify that there are no other causes....

• A bit of code requires terran and protoss to take the natural as the second base. I added an exception: If Steamhammer no longer owns its starting base, the constraint is released. This only happens in rare emergencies, but when it does happen, it could make a big difference.

BOSS

BOSS limited refinery buildings to 3, affecting terran and protoss (zerg does not use BOSS for its production). The result was that, if the game went on long, Steamhammer would take 6 bases and only 3 gas, and as the geysers ran dry it would become severely short of vespene and throttle back production, and struggle to win a won game. This game versus Iron is an example. The limit mostly affected protoss, since terran rarely plays well enough to get that far. I changed the limit from 3 to 6. It was a hardcoded constant in DFBB_BuildOrderSmartSearch::calculateSearchSettings(), so this was a one-character change that took me 10 minutes to find. It is as big a change as I am willing to make in BOSS, which is on the jettison list.

3 was probably adequate for UAlbertaBot back in the day. I hope the increase never causes the search to blow up; it was fine in my tests, but I’m not sure I understand the ramifications.

micro

Improved behavior for units that refuse to retreat. When a cluster of friendly units is predicted to lose a battle and ordered to retreat, there are a few special cases where units keep attacking anyway. One is broodlings; a broodling does not want to waste its brief life. A more important case is a dark templar when no DTs have yet been killed; the DT is probably undetected and in any case has been safe so far, so it does not benefit from retreating.

Formerly, the non-retreat was implemented by giving the non-retreating unit the order to attack move to its own location, so that it could find a nearby enemy and keep up the attack. That caused micro bobbles when the unit stopped what it was doing, thought about it for a moment, then possibly chose a new target, or possibly went into a long reverie. I changed it so that if the unit already had an order to attack a given enemy, it kept the order, and otherwise it was given a new order to attack move to the squad order location. As a result, an initial attack by dark templar is far more incisive than before—it is night and day, formerly the DTs might vibrate uselessly as their “attack where you are” orders kept switching to new locations every time they tried to advance. This is the most important fix in this Steamhammer update.

• I added an experimental change to the dark templar exception: A dark templar will also refuse to retreat whenever it believes itself undetected. It’s experimental because it will cause misbehavior when a non-retreating DT advances into detection range, and perhaps takes hits, before retreating again, and then repeats the behavior. I’m hoping it will be a net win.

terran

• Tanks no longer falsely believe that they can target undetected units. Oops.

• I refactored the tank micro code for clarity and efficiency. Instead of taking a negligible amount of cpu time, it takes a less than negligible amount.

• Terran is limited to 1 starport at most, by a special case check in the production manager. Pointy-haired BOSS enjoys ordering unnecessary production buildings. The change saves a little gas, but mostly saves room in the main base so that buildings are less likely to spill across the map. Limits for barracks and factories would have been more valuable but trickier.

protoss

• Limit gateways a little more flexibly. BOSS loves gateways above all other buildings and will not stop adding more. Formerly, Steamhammer artificially limited itself to 10 gateways, a workaround originally borrowed from Locutus. An improvement, but it built too many gateways, then grew its economy, then had too few. I changed it to allow up to 4 gateways per base with an upper limit of 12 gateways. In my tests it is usually better, never worse, and still crude and wrong. It should hold until I can fire BOSS.

Try to use all the gateways, at least in the “dragoons” opening group. This is the more important fix. If there are more gateways, request more production. Formerly, protoss would often use only 6 of its 10 gateways. No evil is more heinous.

• It turns out that a unit mix of dark templar and dragoons is gas-heavy and may leave minerals unused. Who knew? I added zealots to production in the “dark templar” opening group, again trying to use all gateways.

zerg

• The scourge limit wasn’t working as intended because I changed the wrong number. Fixed.

• I made a change in production that I hope will reduce cases where a creep colony is left unmorphed to a sunken. Later I’ll leave creeps deliberately unmorphed until they are needed, but I still want the current case to work.