archive by month
Skip to content

Steamhammer 1.2.1 docs, 1.2.2 plans

Documentation is written, a bit slowly, as usual. Updating for future versions will be quicker, also as usual. I am now allowed to touch the code again.

It’s short. Is it good? Will it help people get started (or decide whether to get started)? It’s only possible to write documentation if you know details, and it’s only possible to judge documentation if you don’t, so... I’m listening.

version 1.2.2

Version 1.2.1 seems to be 100 points weaker than 1.2, rather than 20 points stronger as I expected. Almost all the strength loss seems to be due to the single retreat-to-the-natural bug. Nevertheless, doing my best to follow the zero-one-infinity rule, I’ve identified a half-dozen quick fixes for version 1.2.2. Expect it in 2 days, plus or minus 1 day.

Steamhammer 1.2.1 early results

1. The feature of retreating to the natural base if it exists is buggy. Steamhammer always retreats to the natural, whether it has been taken or not, causing trouble especially in ZvZ games. This is hilarious, if “hilarious” means “it’s bad, but at least it’s easy to fix.” I added the feature at the last minute with only a brief test: Tally another loss for poor testing and inadequate commenting!

2. Meanwhile, units that retreat to recover from their damage still return to the main, not the natural. In general, the code has confusions between retreating the squad and retreating individual units to regenerate (which only applies to melee units, and only if configured). It doesn’t seem urgent to fix, though.

3. A unit which is inside the minimum range of a sieged tank refuses to retreat with its squad. It doesn't necessarily attack the tank, but it attacks something. This behavior has only triggered a couple times, but so far it looks like a successful improvement.

4. The system of pulling workers for defense is questionable. If it made correct decisions, it would be great. As it stands, it is sometimes good and sometimes bad, and I can’t judge whether it is worth it overall. It averages out pretty close to zero, maybe?

5. I thought the loss against Stone was due to a new weakness, but on a closer look I don’t see one. It’s the first loss against Stone since worker harass defense was implemented, so I’ll test more closely to make sure.

6. Speaking of worker harass, gas workers now defend themselves the same way as mineral workers. I don’t know whether this will turn out to be a win, because harassed gas workers get switched out; harassment can potentially disrupt gas mining. So far, this behavior has triggered against LetaBot, when it looked highly effective. But LetaBot is a lazy harasser, so the jury is still out.

7. Other surprise losses by Steamhammer were due to randomly choosing openings that the opponent countered. For example, in the first ever loss against protoss Lukas Moravec, Steamhammer went 5 pool, which was objectively poor against the 2 gate opening. Steamhammer nevertheless pulled ahead and was winning until it bungled its tech switch.

I’ll be inserting another bug-fix release to solve the retreat-to-natural bug before I get down to features.

Steamhammer 1.2.1 is out

Steamhammer 1.2.1 is out. All races should play more strongly. Steamhammer 1.2 kept up an average elo in the high 2200s, peaking over 2300. I think 1.2.1 is likely to average over 2300.

I was originally planning more improvements for protoss than for other races, but it turned out differently. Terran got the most improvements, and protoss the least. Terran needed them more. Version 1.2.2 is planned to focus more on features than on bugs, and will have some protoss features.

Web site update tomorrow, with source code.

I tried to make this change list more thorough and detailed than earlier ones, since more people are using Steamhammer code. It’s a nice long change list; I got a lot done this time.

config file

• Some options can be set differently for each race, to support playing random.

• New build order commands “go defensive” and “go aggressive”. Defensive means that your units stay at home for the time being; aggressive means that they seek out the enemy. The default is to be aggressive all the time, which is good for zerg. For terran, “go defensive” is good at the start of most openings. For protoss, I had the dark templar rush stay defensive (with its one zealot and one dragoon) until the dark templar start. If you don’t go aggressive in the build order, aggression automatically turns on when the opening build order is over. For now, the only way to stay defensive longer is to write a longer build order (or write code).

• New debug option drawUnitOrders. Besides unit orders, it draws on the screen what a research building is researching and what is going to come out of an egg, cocoon, or production building. I’ve been using the option often.

macro changes

• Updated terran and protoss openings and production code.

• Terran and protoss build more workers.

• All races pay closer attention to the configured maximum number of workers per mineral patch. WorkerManager::getMaxWorkers() gives the largest number of workers that can efficiently mine your existing bases, based on the configured values and the resources at the bases.

• The scout defense worker (used only by terran, in the default configuration) is less likely to move out while carrying minerals. Losing minerals is bad luck.

• More idle workers are recognized and put to work.

• Choosing a new main base caused mostly minor but widespread confusion, now fixed. Various bits of code were unclear about the difference between the start location and the current main base. The most obvious effect was that the first expansion sought after a new main base was chosen was always the start location, which had usually just been destroyed and might still be occupied by the enemy.

• Protoss is less likely to overstep the time limit when its main fills up with buildings. The problem turned out to be fundamental to the building placer, and I resorted to cheap hacks. Someday I’ll spend a few weeks to write a proper building planner with more capability. For now I tightened up protoss building placement so that more buildings fit, spread pylons farther apart so they power a larger area, and taught the production manager not to retry the building placer on every frame after it fails once (which caused a huge slowdown). All 3 measures together are still not sufficient, so I may do more in the next version. One cause is that BOSS orders up more gateways than it needs; its production plans are not as efficient as promised.

• The zerg strategy boss discounts extractors at destroyed bases. It was a minor bug that I could fix in passing.

• Zerg doesn’t make double queen’s nests, a rare bug.

• Zerg will no longer order up a hive while overlord speed was still researching in the lair, causing production to pause until overlord speed finished.

• When zerg has extra larvas and minerals and is short of gas, it goes ahead and makes zerglings. Version 1.2 will often wait for gas, letting minerals build up and reducing total production. Steamhammer’s late game armies will tend to be larger.

micro and tactics changes

• Turned special vulture kiting back on. Vulture micro should be improved.

• Terran by default uses the scout defense feature, unlike protoss and zerg. Terran needs to take extra measures to protect SCVs that are constructing buildings.

• Terran loads and unloads bunkers as needed. It’s not very skilled at it, but it does the basic job. I added a new 8RaxDefense opening to illustrate it (and also to hold rushes for which the bot’s micro is too weak).

• Bunkers can be placed tight up against obstacles.

• Terran builds comsat stations and scans cloaked units (even if it doesn’t have anything around to fight them).

• When terran needs emergency detection, it builds 3 turrets, not 2 like before. It seemed necessary.

• Tanks unsiege to fight buildings, or to target enemy units that are too close for siege fire. Tank sieging behavior is still impressively stupid, but it’s a little less bad.

• Protoss is configured to retreat zealots and dark templar which are seriously hurt, hoping they can regenerate shields. (Zerg has retreated weakened zerglings for a long time.) See the RetreatMeleeUnitShields and RetreatMeleeUnitHP config options.

• When zerg sees vultures, it builds a sunken in its natural (unless it already has one). It’s a simple measure to reduce the harm of vulture raids. When Steamhammer accidentally places the sunken in a good spot, it holds out much better against Iron in particular. Future versions will put up stronger defenses.

• A zerg broodling attacks and does not retreat. It doesn’t live long, it can’t afford to waste time.

• For all races, a unit directly next to a sieged tank attacks and does not retreat. If it retreats, it will likely die to siege fire; better to do damage instead.

• Units retreat to the natural, not the main, if the natural has been taken. As suggested by MicroDK. It turned out to be only a couple lines of code, so I threw it in.

• Reavers are targeted with higher priority. It was an oversight.

• Gas workers now defend themselves against harassment, the same as mineral workers. It should reduce worker losses a little more.

• Bugs related to pulling workers for base defense are fixed. The main symptom was that workers at all bases froze in fear, even when another base entirely was under attack. The problem was that putting workers in a base defense squad did not change their job. I had assumed without checking that they would be given the job CombatWorker, but instead they kept the MineralWorker job, so the mineral worker self-defense code interfered. Now workers pulled for defense become combat workers, and WorkerManager is responsible for their combat orders; the squad knows not to issue orders of its own, and resets the workers to idle when they are released. I tried to make WorkerManager a trifle smarter about combat; we will see how that turned out. Finally, I adjusted the conditions under which workers are pulled and tried to make sure that they are never pulled across the map. Zergling rushes are defended again, if configured, and it is turned on by default although I’m not sure it’s a good idea—it sometimes helps and sometimes hurts. In any case, the worst misbehavior should be gone.

• Base defense against air attack now accounts for turrets, cannons, and spore colonies. Fewer defenders are called home if there is static defense to help. (Base defense against ground attack already accounted for static defense.)

• Steamhammer used to go on the attack when its supply went over 170, and revert to normal behavior when its supply fell below 170. When production was high enough it worked well, but other times it caused loops: “Attack! Oh, retreat. Attack! Oh, retreat....” I added hysteresis. Now it starts the attack when supply reaches 195, and does not stop until it falls below 160.

code fixes

• Some cleanups in CombatCommander.

• UAlbertaBot often uses double instead of int where it calls unit->getDistance(), which returns int. It’s not a bug, but it causes unnecessary computation. I fixed some of them, but not all.

ProductionManager works around a BOSS bug in ordering up comsat stations. If you add a second CC and want a total of 2 comsats when you already have 1, BOSS sometimes orders up 2 new comsats instead of 2 comsats total.

• Removed unused code from CombatCommander, RangedManager and MeleeManager.

• Fixed a sneaky crashing bug in StrategyBossZerg::checkGroundDefenses(), the last known crashing bug.

simple SSCAIT rating statistics

I pulled down a rating table from today and calculated a few simple statistics.

countmean elomedian elo
terran2419651884
protoss1820072050
zerg1620132017
random419011909

1. Terran is the most popular.

2. The fact that the mean is higher than the median for terran implies that a few terran bots stand out (like #1 Iron and #2 Krasi0), but most terran bots are weaker. Terran seems more difficult than protoss or zerg.

3. The higher median for protoss over zerg suggests that protoss may be easier to get strong with (contrary to my opinion).

4. Random struggles, as you might expect, but still has a higher median elo than terran.

If you look over the colors on the rating table, you’ll see that terran bunches up toward the bottom and zerg bunches more toward the middle, while protoss is spread throughout. In the upper part of the table, protoss and zerg seem pretty equally represented, though. There is not much difference between them.

Also, 62 bots is a lot!

bugs that do not go quietly

I recently fixed 2 bugs that then turned around and bit me.

I fixed a bug that caused Steamhammer to make double queen’s nests in around 1 game out of 150. It was a simple missing condition. But I made a typo in the fix: Parentheses in a function call swallowed up the next condition in the if. In any safe language it would have failed to typecheck, but in any case, the result was that Steamhammer made 3 or more queen’s nests in every game. I think C++ was laughing at me—”Nyah nyah! I’m too sharp a knife for you!”

I also tracked down and fixed the last known crashing bug, a subtle oversight in the strategy boss that causes crashes in around 1% of games. I brought up a game for a first test of the fix and... crash! Somehow I replaced a rare crash with a frequent crash, and even though I only touched a little code, I haven’t found it yet.

Well, it probably won’t take long—though who knows? After that I have 2 other critical bugs, and then 1.2.1 will be ready.

By the way, Steamhammer does suffer from one other crash besides the “last known” crashing bug. In rare cases, it crashes on startup. But the crash happens before any Steamhammer code executes, so there’s not much I can do about it without taking a long detour.

Microwave

The long-awaited Microwave by MicroDK was uploaded today. Congratulations to MicroDK on an outstanding start, 11-4 as I write including a win over #1 Iron.

One of Microwave’s favorite moves seems to be walking a line of sunkens toward its ramp. It’s kind of cute, and I imagine it’s effective against many bots.

Though Microwave is a fork of Steamhammer 1.0, it seems to borrow some behaviors from later Steamhammer versions too. I noticed that it made 2 evolution chambers but only used 1 of them, a UAlbertaBot limitation. I mentioned the fix to that problem in a comment to AIL, but let me bring it out front: In ProductionManager::getProducer(), add the lines

		if (unit->isUpgrading())   { continue; }
		if (unit->isResearching()) { continue; }

alongside the similar checks.

It also seemed to stumble into bunker range. Steamhammer 1.1 and later do that less often because they understand the range of a bunker. I don’t think of it as a bug fix; it swaps one poor behavior for another that is usually less bad. In Squad::needsToRegroup() where it calculates range, I changed the call to

          int range = UnitUtil::GetAttackRangeAssumingUpgrades(eui.second.type, u->getType());

which I rewrote to pessimistically assume that enemy units have their range upgrades. It also adds in the range bonus of a bunker. UAlbertaBot originally ignores both. Someday I’ll detect these silent upgrades and whether the bunker is loaded, but not yet.

corsair-dark templar

There are two ways to make headway: You can execute your plan better, or you can execute a better plan. In bot development, I think it’s right to spend most effort on polishing what is already done, or adjusting your plan detail by detail. No matter what plan you follow, you’ll meet a huge number of bugs and weaknesses, and they have to be taken one at a time. All the roads are long.

But tscmoo has fun trying out different plans altogether, and tscmoo is a frequent tournament winner. Isn’t there a connection? When you try something new, your opponents will not be ready for it. And we know of strong plans which no bot tries.

Corsair-dark templar is an example. Sair-DT is for protoss versus zerg: Corsairs chase away or kill overlords in an area, and then the dark templar have free rein. I wouldn’t say that sair-DT is a strategy; it is a class of tactical plans which can be fit into a strategy.

I sometimes see bots with corsair skills clear an area of overlords, but the bots do not seem to realize the opportunity. There is a reason they don’t, of course; sair-DT play requires coordination. The corsairs and the dark templar must be ready at the same time to attack the same location, and they have to work together.

But defending against sair-DT also requires coordination, and bots are liable to be poor at it. Think of what Steamhammer does: It makes hydras and individually chases after each corsair that enters its base, scattering its forces. 4 dark templar, even if detected, could kill the scattered hydras one at a time and slip away safely because the pressure on the corsairs is released. Each unit supports the others; it’s not easy to implement, but by the same token it is not easy to defend against.

Here is a common pattern in human games. Zerg owns the natural and main of some start location. Corsairs are flying about, so zerg makes hydras for defense and holds them in front of the natural and collects overlords there. The hydras defend both bases by ground and defend the overlords, while the overlords detect any DTs that try to sneak past. There is still one weak point. Protoss sends corsairs through the main while at the same time dropping DTs from a shuttle in a far corner. When the sairs see that the defenses are weak enough, the dark templar move in and snipe any drones that don’t escape fast enough, then go to work on buildings. Zerg rushes to defend and will try to scourge the shuttle; if the shuttle lives, the DTs will load back up and get away free, counting their loot. I find it hard to imagine any current zerg bot defending well against such a sophisticated attack.

It was tempting, but I decided not to implement sair-DT myself, because it is too far off my path. Anybody could fork Steamhammer and get coding. Or if you have a protoss bot that already knows corsair skills....

resilience in the face of stupidity

Steamhammer 1.1.1 has a lot of resilience improvements over version 1.0. It can rebuild from scratch in a new base after its main is destroyed, for example. I thought that disaster resilience added little to the bot’s strength. In Starcraft, surviving a near-death experience usually means that death is still near.

But lately I notice that Steamhammer 1.1.1 is more consistent than earlier versions. It is rarely upset by much weaker bots, saving many elo points. Unlike in the tournament (version 0.2), most of its upsets are at the hands of opponents which are at least average in skill—and Steamhammer retains its knack of occasionally upsetting stronger opponents.

This game Steamhammer-UPStarcraftAI (elo 2303 versus 1825, compared to the average of 2000) was extremely badly played by both sides. Don’t watch this if you have sensitive eyes, it will hurt! Terran UPStarcraftAI blocked some of its own forces behind its mineral line and was unable to concentrate its strength, while Steamhammer made awful attacks and frittered its mutalisks away, then was unable to defend its natural and lost it. UPStarcraftAI did not know how to proceed and left its victorious army standing idle, and Steamhammer tried to help by suiciding drones and moving zerglings back and forth through the marine formation without fighting (it couldn’t decide which base to retreat to).

Steamhammer didn’t recover neatly, but it did recover. It cleared the idle terrans, built too many drones and took the map while getting upgrades, and finally realized that maybe an army would be useful after all and went ultra-ling, after which (despite some more bad play) the outcome was clear.

Another awful recent game is Steamhammer-DAIDOES (elo 1778), where Steamhammer lost its main but managed to power through its own stupidity—which included stopping at zergling tech level because of a stuck drone—and barely win after mining out.

Resilience against near-fatal disasters is good. Skill in one dimension can rescue blunders in another. The games saved are the ones that would have cost the most elo points—because against a stronger opponent, the game is not saved.

configure Randomhammer differently for each race

I added a feature to make random play more configurable. Steamhammer 1.2 (which is identical to Randomhammer 1.2) has configuration lines to set the maximum number of workers per mineral patch before a base is “full”.

"Terran_WorkersPerPatch"    : 2.8,
"Protoss_WorkersPerPatch"   : 2.6,
"Zerg_WorkersPerPatch"      : 1.8,

For the next version I simplified it (and decreased the numbers, they were too high; someday I’ll do mineral locking and maybe drop this).

"WorkersPerPatch"           : { "Zerg" : 1.6, "Protoss" : 2.3, "Terran" : 2.6 },

And I allow the same syntax for several other config options in the Micro and Macro sections.

"RetreatMeleeUnitHP"        : { "Zerg" : 8 },
"RegroupRadius"             : 600,
"UnitNearEnemyRadius"       : 600,
"ScoutDefenseRadius"        : { "Terran" : 400 }

You can specify an integer to get the same value for all races, or break out different values for each race. If you leave out a race, it defaults to 0. Here I want terran to pull an SCV to defend itself against the enemy scout (within a radius of 400 pixels) to protect its SCVs while they are building; the other races don’t have that problem and keep mining as much as possible (ScoutDefenseRadius 0 means “don’t bother”).

Flash versus Soulkey

If you watch only one pro game this month, I recommend Flash versus Soulkey (the last game in the cast, starting at about 2:07:20 into the video), played today. It is a TvZ with continuous excellent play on both sides, continuing into the late game with all bases taken.

The game is the deciding ace game of the grand final match of the Afreeca Team Battle tournament, a team tournament. The player who wins the game brings tournament victory to his team, so they gave it their all.

Flash is the world #1 TvZ player, and Soulkey has become a top ZvT expert; the game was on a higher level than an ordinary pro game. It is interesting partly because it is standard: Both players followed mainline strategy, Flash going 5 barracks +1 into late game mech switch and Soulkey going 3 hatchery mutalisk into lurkers, then defilers and finally ultralisks. The mainline strategy represents the best known play, and both players kicked it up a notch with sharp attacks and precise defenses.

It was a great game that fans will remember, and there’s a lot to learn from it. From the point of view of a bot author, it is depressing how much game knowledge and skill are visible.

Update: It amused me to collect some quotes from the Teamliquid thread. The first 4 quotes are from before the game finished.

“Really impressive to see Soulkey hold his own against Flash in a macro game.” — ZiggyPG
“This is a GREAT game.” — [[Starlight]]
“hes matching Flash move for move and looking ...good” — Probemicro
“That was some sick moves” — psd
“GG that was an amazing game” — CakeSauc3
“WORTH THE SORE THROAT” — LittLeLives
“I suggest you watch the game, it was incredible” — Piste
“Just incredible level of play in my opinion.” — Netto.
“That ace match was the most beautiful game I’ve seen in a very very long time” — jamesuh

Randomhammer early returns

Steamhammer 1.2 should play zerg a smidgeon stronger than 1.1.1, because of a few fixes. But I doubt the difference is noticeable. I didn’t fix anything important to strength.

After 2 days, Randomhammer’s rating has settled near 2050, a little above the average rating and 200 points below Steamhammer. The bot’s protoss and terran came out far weaker than its zerg. I’ve been looking at the games and thinking about why.

The building placement slowdown bug turns out to be critical for protoss. Randomhammer protoss has reached winning games against tough opponents like LetaBot and Killerbot by Marian Devecka, but tough opponents do not roll over and die, they fight stubbornly. Randomhammer fills up its main with widely-spaced buildings, the building placer slows to a crawl, and the bot busts the time limit and kicks out a loss.

Indecisive army movement is also critical for protoss. It’s harmful for zerg, but deadly for protoss, because the bulky protoss army spreads across the map, and one dragoon or another will happen to see something unimportant that distracts the attention of the whole army. The correct fix is to replace the targeting priority system, a job that needs a lot of detail work. I may try a cheaper fix instead.

Incompetence with terran seems harder to improve. Terran needs a lot of skills to play well, including adaptation skills. I did find the reason behind some strange play when going siege tanks, and fixed it.

Randomhammer beats Steamhammer on average, because Steamhammer’s openings are weaker versus random. When you don’t know what you’ll face, you have to play a general-purpose build. For example, when Randomhammer rolls zerg, it usually plays an optimized anti-zerg opening while Steamhammer is stuck with a tamer 9 pool or overpool. Steamhammer does not have a pro’s ability to play a general-purpose opening as sharply as a specialized one.

As a result, having Randomhammer in the pool of opponents decreases Steamhammer’s equilibrium elo, especially if people think the matchup is interesting and vote for it. Well, difficult opponents make good inspiration—all the better if I can supply the difficult opponent myself.

changes to plans for the next versions

Critical problems are a good excuse to rework my plans. Of course the real reason is that no plan survives contact with the calendar—it has been two days already, it’s time to change it up. The schedule must be rendered meaningless!

I decided to split versions again, so I can make the most important fixes up front and see the results sooner. The fixes now planned for 1.2.1 should delight protoss and leave terran and zerg smiling too. I don’t want to go too deeply into protoss and terran skills, though, because they’ll distract me from my main goals.

  1. 1.2.1 - fix critical bugs, add critical skills
  2. 1.2.2 - further skills
  3. 1.2.3 - other lingering bugs

Steamhammer 1.1.1 retrospective

Now that Steamhammer 1.2 is out, I want to think back over the lessons of version 1.1.1.

Steamhammer 1.1.1 was shockingly successful. The high end of my expectation was that it might reach an elo a little over 2200, and that seemed unlikely. In fact it had a final elo of 2285 and maintained a position as the #3 bot on SSCAIT, behind only Iron and Krasi0. Even when it hit a losing streak (which I helped along by voting for lower-rated opponents that were likely to beat it), it quickly bounced back. What did I accidentally do right?

Compare Steamhammer to AILien. They’re about the same age and both are descended from UAlbertaBot. We’ve helped each other out with bug fixes and ideas. AILien is ahead of Steamhammer in most zerg skills: It has better scouting, better tactical decisions, better building placement, better worker defense, better overlord safety, better cooperation of mobile units with sunkens—I have a lot to do to catch up with it, if I ever can. And yet Steamhammer is stronger by 100 elo, a large difference. What’s going on?

I didn’t expect it and I can’t explain it. Some of the bugs introduced in this version seem devastating, but they turned out to hurt results only against a small number of opponents. All I can do is explain my choices and conclude that somehow they were good choices.

1. Play efficient openings. Steamhammer’s builds are not all perfectly tight, but they’re pretty good and they put pressure on the enemy. I haven’t seen such good builds from any automatic code, whether BOSS or AILien or Steamhammer’s own strategy boss or any other bot. Handmade is still better—so far!

2. Keep the pressure on. Steamhammer plays the full range from fast rushes to economy-heavy openings, but it prefers low-economy pressure builds. I thought: Bots are good at attack and poor at defense, so keep attacking! AILien prefers a strong economy; it’s not a mistake, but it may be less effective at exploiting weaknesses in other bots.

3. Stay strategically crisp. Zerg larva management means that zerg can switch its unit mix suddenly to push the opponent off balance. I took the attitude: Don’t adapt to the situation, drive the situation so that the opponent has to adapt. That’s why Steamhammer makes explicit unit mix and tech target decisions. I directly coded in bias and hysteresis, so that it doesn’t change its mind lightly:

bool StrategyBossZerg::vProtossDenOverSpire()
{
	// Bias.
	int denScore   = 3;
	int spireScore = 0;

	// Hysteresis. Make it bigger than the bias.
	if (_techTarget == TechTarget::Hydralisks) { denScore   += 13; };
	if (_techTarget == TechTarget::Mutalisks)  { spireScore +=  9; };
	...

4. Fix bugs and stay resilient. As it stands, at least half of Steamhammer’s lost games show severe bugs—maybe not game-losing bugs, but deeply harmful bugs that destroy resilience and take away opportunities to come back. The bugs I fixed between version 1.0 and 1.1.1 likely made a big contribution to Steamhammer’s strength.

Are these the real reasons? Well, I already said that I don’t know. If you’ve watched the games, what do you think?

Tomorrow: Early returns from Randomhammer.

Steamhammer 1.2 and Randomhammer

Steamhammer 1.2 is out. Headline feature: It plays random (like UAlbertaBot). Steamhammer continues to play as zerg, and Randomhammer is the same code playing random. In its first game, thanks to the voting system, Randomhammer played Steamhammer. Randomhammer rolled protoss, opened 10-12 gate, and won easily.

Randomhammer’s elo is likely to end up lower, since zerg is way more polished. But the protoss is not bad, and it will be a good test. Terran and protoss hit bugs more often than zerg.

The change list is not long.

  • In the configuration file, you specify the target number of workers per mineral patch separately for each race, as a floating point number. I set it to 1.8 for zerg, down from 2.
  • New middle game production code, with longer tech paths than UAlbertaBot.
  • Openings.
    • 4 terran openings and 7 protoss openings, with random choice.
    • Terran and protoss openings use the OpeningGroup feature to share middle game production code.
    • Fixed a bug that prevented “2 x dark templar” from working due to the space character in “dark templar”.
    • Zerg’s 9 pool speed opening is updated to fix a mistake introduced in 1.1.1.
  • Worker defense: Attack stuck as well as non-moving enemies. (An unnoticeable tweak—for now.)
  • Emergency cloaked unit defense: Fixed a bug that caused the queue to explode.
  • Terran resumes construction after a building SCV is lost. (UAlbertaBot leaves the incomplete building there forever.)
  • Small updates to the zerg strategy boss.
    • Fixed a potential crashing bug.
    • Fixed a bug that could explode the queue when there were fewer than 3 drones.
    • Fixed a bug that could cause double ultralisk caverns.
    • Minor adjustments to the heuristics.

It was not hard to get protoss to play a decent game, but terran is tough. In my tests, Steamhammer 1.2 terran scores much worse than zerg or protoss. In a random-on-random test with a development version versus UAlbertaBot, Steamhammer protoss scored 8-1 and terran scored 1-7 (there were no mirror matchups). Another example: Against Stone, Steamhammer protoss survived on the first try. Terran did not, because Stone gangs up on building SCVs. Resuming buildings which lose their building SCVs was a necessary skill to give Steamhammer terran any chance at all; it can survive Stone occasionally. Terrans that beat Stone reliably have 2 other skills that I did not implement, replacing the building SCV when it gets hurt and pulling SCVs to drive the attackers off.

UAlbertaBot’s building placer started to show problems in longer games. UAlbertaBot plays rushes and doesn’t see many long games. The building placer wants to build everything in the main; when the main fills up, placement slows down drastically and may overstep the time limit.

I made a forge fast expand opening for protoss, but I have reservations because of other limitations of the building placer. In Steamhammer, you can ask for buildings to be made in the natural, and it works. The building placer knows to leave the nexus spot open. But it doesn’t know the plan, and may place the pylon in a spot without room for a forge, 2 cannons, and a gateway. If there’s no room, the build freezes and the bot will lose. I worked around it for now by inefficiently building extra pylons in the main for the gateway and everything after. Even so, it fails sometimes on SSCAIT maps when it can’t place the forge. Someday I’ll drop the building placer for a building planner, but that will probably be a long time from now.

version 1.2.1

I didn’t get everything done that I wanted, so I’m changing my plans for future versions. 1.2.1 will be mainly a feature version. Here are the features I hope to add, in order of priority.

  1. loading and unloading for terran bunkers
  2. simple measures so zerg can better survive vulture attacks
  3. basic drop skills for terran and protoss
  4. reavers
  5. psionic storm
  6. stim for marines
  7. mixed strategies versus specific opponents when playing random
  8. generalize certain zerg smarts so that terran and protoss can benefit

It seems to me the best tradeoff between getting key skills and getting finished. I’m leaving out a bunch of other basic skills: Overlord hunting (needed for wraith and corsair play versus zerg), mine laying, keeping medics close to marines, carriers, picking up dropped units....

There are also critical problems I want to fix. Others are likely to come up.

  • the bot falsely believes that mining SCVs block the comsat from being added
  • aimless play when the army gets distracted by units all around

version 1.2.2

Then the following version, 1.2.2, becomes the cleanup bugfix version. There are 2 bugs that pass invalid parameters to Micro::SmartMove(), at least 3 bugs that cause expansions to fail to be made, and 2 bugs that cause workers to go idle unnecessarily. I hope to stomp at least 5 of those 7, plus of course anything that turns up from playing random on the server.

version 1.3

Version 1.3 will be my start on mutalisk skills.

Steamhammer 1.2 to be followed by 1.2.1

Steamhammer 1.2 is taking longer than I expected. It may end up being a few days later than promised. It’s not as fun to work on protoss and terran, and I’ve been putting less effort in.

I have given it a workable set of a half-dozen protoss openings to play in a different mix versus each race. There are still a couple of critical bugs (why can’t it make a photon cannon?). The terran openings are giving me more trouble. UAlbertaBot turns out to be short of terran skills. It doesn’t know how to stim marines, so bio builds are weak, and it doesn’t know where to lay spider mines, so mech builds are weak. (There’s a routine to lay mines, but it is never called.) And I’m not excited about adding the skills. The terran openings will not keep up with the other races.

BOSS truly does work much better for protoss than for zerg. Steamhammer’s protoss play using BOSS with simple goals shows better macro than Steamhammer’s old BOSS versions did with carefully-chosen goals.

UAlbertaBot does include a protoss drop skill, which in a test almost worked. It built a shuttle and flew it in a cautious path along the edge of the map to the enemy base—all it forgot was to load zealots first. If I don’t run into any surprise trouble, I’ll get it working for protoss and terran and include a drop opening or two. With XelnagaII disabled, no bot currently plays dark templar drop, and that’s a shame.

Also, Steamhammer 1.1.1 is showing some severe bugs that sabotage its play, especially in long games. So before I get into the 1.3 series, I’m planning a bug fix version 1.2.1 that fixes the worst bugs and restores good macro in long games. That includes protoss and terran bugs that may come up in version 1.2.

Steamhammer’s unbelievable winning streak

OK, this is officially Too Much. Steamhammer hit a string of good luck and its elo went over 2300—it should be about as high as this version gets. After its first loss to Steamhammer, Krasi0’s opening learning is still struggling to find the answer (which is: go back to the default build and win almost all games). After many losses against Iron, Steamhammer scored back-to-back wins, which can only be called luck. The wins came with opposite opening styles. One game was 9 pool speed. Steamhammer transitioned to mutalisks, which fought well enough to stop serious drone loss from the vultures. Iron built mass turrets but was unable to cope on the open map, and ultralisks eventually put in the final word. The other was 3 hatch muta. In the second game, the mutalisks were early and numerous and cut down Iron where it stood. A bunker and a couple rings of turrets are not enough; this mainstream opening is a flat-out counter to Iron’s build. If zerg took a little more care in defense, Iron would stand no chance against the 3 hatchery mutalisks.

Steamhammer also scored two fluke wins over LetaBot versions when LetaBot crashed while far ahead. Skynet by Andrew Smith finally put an end to the incredible winning streak—with a dark templar rush! Ha ha! Skynet played it well, killing spotting overlords with a dragoon and taking full advantage of Steamhammer’s blindness to its build.