archive by month
Skip to content

Steamhammer 1.2.3 uploaded

Steamhammer 1.2.3 is uploaded, playing zerg as Steamhammer and random as Randomhammer. The previous version 1.2.2 was clearly stronger than earlier versions, though it was overtaken by newcomers during its long life. If this version lives up to its test results then it will be stronger yet. For example, in my tests 1.2.3 zerg crushes #3 Killerbot by Marian Devecka like an egg.

The first version of Randomhammer came out 100 elo weaker than its parent UAlbertaBot, due to playing more varied and less aggressive openings. The test version running lately was maybe 50 elo stronger than UAlbertaBot on average (though it’s hard to estimate, because UAlbertaBot’s rating is unstable). And its openings have become a little more varied yet. New version 1.2.3 should be even stronger. So I think Steamhammer should be a reasonable starter bot no matter what race you have in mind.

Next up: The rest of the release tasks. Then I’ll bring up a public repository. After that I’ll finally be free to look into the new SparCraft.

  • the change list (blog post)
  • update Steamhammer’s web page
  • update the documentation
  • public repository

a few extra buildings never hurt anyone

I did get an “argh, how did that go wrong?” A new bug is affecting terran. I hadn’t seen it before, but suddenly, in game after game, BOSS started ordering up 2 spare barracks when the bot is playing a mech strategy with no barracks units. The BOSS goals look correct, so I must have changed something to tickle a bug. Argh, etc.

Look for the Steamhammer 1.2.3 release tomorrow. Surely I’ll be able to work around it by then, and surely nothing else critical will go wrong....

new Steamhammer 1.2.3 almost ready

The Steamhammer 1.2.3 release will be tomorrow unless a surprise comes up, where “surprise” means “argh, how did that go wrong?” Nothing is left but testing and minor tuning.

Even though it has only been a few days, I got a lot done. In some situations, the release version will play dramatically differently. Compared to the test version that’s live now as Randomhammer, it has these brand new improvements:

• I added a corsair-dark templar opening for PvZ. Steamhammer plays it weakly, but I set it to happen only 5% of the time. The bot won’t be worse overall, and it will add variety. Mostly I wanted to put an example out there as inspiration.

• Terran and protoss flying units usually go into a flying squad separate from the “main attack squad” on the ground. Zerg has worked that way since December. Each squad gets a detector, if one is available, just like zerg.

• A squad is only sent to fight enemy flyers if it has at least one unit that can shoot up, and to fight enemy ground only if it can shoot down. This should—not entirely fix, but mitigate the problem of dispatching ultra-ling to fight carriers.

• With that in place, overlords can be acceptable tactical targets. (They’ve always been micro targets, which is different. A tactical target is one that you send a whole squad after.)

• Targeting is improved in a number of ways (I mean micro targeting for individual units). I fixed a bug in calculating the attack range of a bunker and added the ranges of reavers and carriers. Fast units that can escape are less likely to become targets. Targeting of workers is tweaked in a couple cases.

• The zerg strategy boss understands how to react to enemy static defense, both in economy and unit mix. I cut a few zerg openings much shorter to give the new skill a chance to work. In some situations, it is awesomely effective.

This is just a sketch of the latest. Details on all changes will come with the release.

early returns from the Randomhammer test version

The test version of Randomhammer has done well over its first 2 days. Its elo has crept above Steamhammer’s, and having watched the games, I think this Randomhammer may truly be better as random than the older Steamhammer is as zerg, even though its terran is still weak. Anyway, the important conclusion is that I didn’t introduce any major weaknesses this time. There are some new weaknesses, but they are more than offset by new strengths.

The worst bug came in a game against Krasi0, when Randomhammer randomly became terran and decided on its vulture drop strategy. I would have liked to see that, but when it came time to add the control tower to the starport, no control tower started. The vultures waited in vain for the dropship. Randomhammer fell into a production freeze, which ended only after it timed out—it’s a new feature to prevent permanent freezes, but the timeout has to be long, so it doesn’t help that much. Terran addons are finicky because the production code is not robust enough. I’ll work on it.

Some problems that I worried about did not come to pass. My work to make the army less distractible has made it more distractible (it’s not an easy problem to solve), but the changes seem to help on average. The bot is less willing to concentrate its forces when it should, but it is more skilled at splitting its forces when it should, and it appears to be a net gain. It’s another issue to work on.

Terran has a revamped tank opening that brings a stronger economy and includes a vulture and several marines in the early army. I think it should be more effective against most opponents: The marines and vulture should help early defense, and the stronger economy should mean that tank numbers build up faster. I was disappointed to find that the tank opening does not beat XIMP by Tomas Vajda, due to bad tactics. The mixed force arrives with 1 tank at the cannons and... sits there, unwilling to engage even though siege mode is finished. Only after more tanks arrive does Randomhammer siege down the cannons, and by then the carriers are nearly ready. Tanks are complicated.

Protoss still beats XIMP, now with dragoon-reaver instead of straight dragoons. A game with zerg versus XIMP hasn’t come up yet. I fixed the problem that caused Steamhammer to often skip spire against the carriers, so it should do better. I did not fix the problem that causes ultra-ling to seek out carriers and stand underneath them dying, though I have put infrastructure in place for the fix. After I get that one, surely XIMP will be toast.

Randomhammer test version uploaded

As promised yesterday, a test version of Randomhammer is uploaded to SSCAIT. The most important changes:

• Terran supports several new skills. Infantry play in particular is improved.

• Protoss supports more units that need special handling: Reavers, carriers, archons. The middle game has more transitions and makes use of the new units.

• Drop is supported, in a limited way. Terran and protoss have new drop builds. Terran plays vulture drop about 10% of the time. Protoss plays dark templar drop about 15% of the time.

• Zerg has a number of minor improvements, but benefits most from reworked openings in ZvP and ZvZ.

• For all races, some openings are chosen differently, or at different rates, depending on the map size.

• There are tactical and micro changes. The biggest is that targeting decisions are made in a more flexible way. In the long run, the extra flexibility will improve play, but the current implementation has drawbacks. I’m curious to see whether it does better or worse overall.

• The bot surrenders without waiting for you to finish off its last buildings.

technical difficulties, please stand by

After falling behind on my own, I was beset by technical difficulties and ended up having to restore stuff from backup. I hate that. I follow safe practices so I didn’t lose work, only time and motivation, but I still hate it. Now I feel Hopelessly Far Behind.

In other news, when Steamhammer was pushed down the ranking by McRave and Microwave, suddenly Steamhammer got many fewer games on the server. Apparently the second string is not nearly as interesting to vote for, or maybe people got bored since it has been over a month since the last update. Either way, it is kind of relaxing.

Nobody objected to my idea of uploading test versions to SSCAIT without doing the extra testing and documentation work of a proper release. I think I’ll add another wrinkle. Tomorrow I’ll upload Randomhammer only, not Steamhammer zerg, in the almost-ready development version. I figure that that way I can get it tested and I won’t be overwhelmed with games to watch, so I’ll get on faster with the last half-dozen items I have planned. We’ll see how it goes.

new configuration features coming in Steamhammer

For the upcoming Steamhammer version, I’ve added a set of configuration features that make the strategy mixes more expressive. A strategy mix is a set of openings with numeric weights, which Steamhammer chooses among randomly according to the weights.

1. In a strategy mix, you can specify different weights depending on the map size—actually the number of starting positions, from 2 to 8. A weight given as “Weight” is a default weight that applies to all map sizes. A weight given with a number, like “Weight2”, is specific to that map size and overrides the default weight. This line says that the 9PoolSpeed opening should be played more often on 2-player maps:

    { "Weight" : 5, "Strategy" : "9PoolSpeed", "Weight2" : 15 },

MicroDK wanted this feature, and now it is done.

2. You can use strategy mixes in the EnemySpecificStrategy section. In the current version, you can only specify fixed openings against specific opponents. The syntax is slightly different, to make it possible to play random: Instead of one list headed “StrategyMix”, you can write up to three lists headed “Terran”, “Protoss”, and “Zerg” for the race you end up as.

3. I added a new subsection StrategyCombos which defines strategy mixes that you can refer to by name. For example, Steamhammer knows the names of a bunch of zerg rushbots, and will follow the same strategy mix against all of them. So in the EnemySpecificStrategy section, it lists each one and tells it to follow the AntiRush strategy mix, which gives 6 alternate zerg openings, plus a protoss and a terran opening to defeat 4 pool and 5 pool.

A strategy combo can be given anywhere that you can give a strategy name, including recursively in another strategy mix. (Suggestion: Do not make an infinite loop.) That way you can build strategy mixes piece by piece. Steamhammer does this for its 4 and 5 pool openings. It knows 3 variants, and it is tedious to write them all into each matchup’s strategy mix, so they are pulled out into a separate FastPool strategy mix in the StrategyCombos section:

    "FastPool" : {
        "Zerg" : [
            { "Weight" :  0, "Strategy" : "4PoolHard", "Weight2" :  5 },
            { "Weight" :  0, "Strategy" : "4PoolSoft", "Weight2" : 15 },
            { "Weight" : 80, "Strategy" : "5Pool" }
        ]
    },

Nested strategy mixes are resolved one at a time. If the outer strategy mix says to play FastPool 5% of the time, then that’s what happens (it may vary depending on the map size). Then FastPool says “oh, this is a 2-player map, I’ll play 5Pool 80% of the time and the others less often,” or it says “this is a 4-player map, I’ll always play 5Pool.”

an example

I made a strategy mix to try against Krasi0 which happens to use all the features. Maybe it will provide an edge over the default. Here’s how it stands today:

    "krasi0" : {
        "Zerg" : [
           { "Weight" :  3, "Strategy" : "FastPool" },
           { "Weight" : 17, "Strategy" : "9PoolSpeed" },
           { "Weight" : 15, "Strategy" : "ZvT_12Pool" },
           { "Weight" : 20, "Strategy" : "ZvT_2HatchMuta" },
           { "Weight" : 25, "Strategy" : "ZvT_3HatchMuta", "Weight2" : 0 },
           { "Weight" : 20, "Strategy" : "3HatchPoolMuta", "Weight2" : 0 }
        ],
        "Protoss" : [
           { "Weight" : 10, "Strategy" : "1ZealotCore" },
           { "Weight" :  5, "Strategy" : "DTRush" },
           { "Weight" : 25, "Strategy" : "DTDrop" },
           { "Weight" : 10, "Strategy" : "12Nexus" },
           { "Weight" : 50, "Strategy" : "13Nexus" }
        ]
    },

There are zerg and protoss entries. If Randomhammer rolls terran against Krasi0, it will fall back on its default strategy mix.

Krasi0’s favorite thing is to sit back and macro up, so I selected a mix of some fast openings (that stand a chance of busting early, or that may cause trouble if terran should lose and try another build), and some macro openings to try to keep up (including a greedy three hatchery before spawning pool build that Steamhammer doesn’t normally dare to play). I de-emphasized the middle range that seems to me less successful against Krasi0.

Also, the 3 hatchery openings do not happen on 2 player maps. That is because Steamhammer is likely to get a drone stuck behind map blocks, which is a sure loss against a strong opponent. A future version will understand the map blocks, and then I’ll change the weights.

release cycles

I’ve been thinking about release policies.

Eh, let’s try it. I think most people tinker with their bot for a while, then when they want to see how they’re doing they upload it and—see how they’re doing. It’s immediate and low-overhead. Good stuff.

Stamp a version number on it and throw it over the wall. Without thinking hard, I have fallen into an old-fashioned release cycle where I complete a bunch of work and hold a big release party. Releasing and documenting each version is overhead work, so I have incentive to stretch out the cycle to reduce overhead. It is not exactly Ideal Software Development Methodology.

My idea was that people would be unhappy if they saw advances on the server that they couldn’t get their hands on yet. I imagined, “Yo, hurry up and release already, I want that feature.” But is that true? I could switch to a compromise release cycle.

Kick development versions over to the server freely, and then when it looks done when poked with a fork, give it a version number and do the release work. On the downside, it seems more complicated for users. Official “stable” versions with updated documentation would only occasionally be running on the SSCAIT server, so what you see is not what you get. On the upside, there would be more variety for viewers (“look, it’s the bug of the week!”) and stable versions would be better tested.

It would affect how bots are updated in reaction to each other. My reaction cycle would be shorter, so new ways to beat Steamhammer might not survive as long. Equally, new Steamhammer behaviors would appear earlier on the server, so they might be countered sooner. Theoretically, it might speed up bot progress overall by some tiny amount.

The whole process would be more freeform and unpredictable, or in other words, modern. Even freer policies are possible, but I want to keep stable reference versions so that people aren’t tempted to fork broken unfinished code. And I have to minimize work; updating documentation as I go can cause extra work if I end up redesigning a feature that I document before it is tested enough.

What do you think?

next Steamhammer version coming soon

I planned the next Steamhammer version (1.2.3) for the end of this month, but it is going to be late. I have added a bunch of features, and there are still a few more features that I want to cram in. Then I’ll need at least another day for testing, because a lot of new stuff is poorly tested and I would rather avoid a meltdown.

There will be new config options, more stuff for each race, more flexible tactics and targeting, and surrendering when hope is lost. “Farewell, cruel world!”

The version after (1.2.4) will be a bug fix version. I already have a mighty list of bugs and flaws to fix, and 1.2.3 will probably add more.

most skills are hard

I think most Brood War skills are hard to implement well. Every skill I add seems to give me some difficulty or other.

stim

Krasi0 noted that most bots which use stim tend to overstim so that the medics are constantly low on energy. That didn’t seem all so hard to avoid, I thought when I first considered it. Add up the total medic energy, and stim more freely when you have more medics or they have more total energy. Well, it can make sense to stim when you have no medics at all. And how many marines do you want to stim when one zergling runs in as a scout? Hmm, it’s tricky....

The right way to make the decision is to weigh the cost and benefit. The cost is 10 hit points per unit stimmed over the time period until the damage is healed, plus the medic energy to heal it—something like that. The benefit is faster movement and faster shooting until the stim ends, whose value depends on the whole situation. Both cost and benefit should take into account what you expect to happen next (“better save some energy for the next fight”). Tricky is not the word, it’s infeasible to do it optimally! Tradeoffs must be made.

For now, I followed a simple plan not far from my first thought. Steamhammer adds up the medic energy, counts down the amount used by each unit stimmed, and stims more conservatively when it is gone. It overstims, like most bots, but at least not to the point that it runs down its hit points.

Even with poor decisions, stim makes Steamhammer’s infantry stronger. It’s a net gain.

merging an archon

Stim is hard for gameplay reasons. Merging an archon is hard simply because it’s unreliable. Sometimes the two high templar you’ve ordered to merge end up circling around each other and never get together. Sometimes they start to approach each other, run into obstacles, and give up. If you try again, they are likely to run into the same obstacles and give up again, so you have to move them somewhere else first—but where?

Steamhammer doesn’t support psionic storm yet, so I don’t have to worry about the tradeoff between keeping high templar and making archons. I added a micro manager for high templar, with the sole job of merging archons. After high templar learn how to storm, maybe the strategy manager should decide when to merge high templar.

It took me hours to get archons to merge reliably. At least, I hope, mostly reliably. I check templar->getLastCommand(), templar->getLastCommandFrame(), and templar->getOrder() in different combinations to recognize different cases. I picked a point next to a corner of the main nexus as a gathering place for high templar that get stuck and need to be told to move first. Of the high templar ready to merge, I find the closest pair and merge only them, then call it a day for that frame. The combination of measures seemed to be enough.

In one test game, an archon merged at the gathering point and between two other high templar. The archon could not escape because it was trapped among buildings and high templar, and the high templar could not merge because an archon was between them. I didn’t fix this case, I arranged for it to be rare enough that I hope it doesn’t hurt much. Meanwhile, there are failure modes that I didn’t run into in tests....

many ways to beat Steamhammer

Steamhammer’s elo stabilized over 2300 before the last mini-tournament. It is clearly the strongest version yet. Randomhammer’s elo rose to around 2100, as I forecast. All races are stronger than before.

Then Steamhammer’s elo crashed during the tournament. 5 Pool had just learned how to beat it, and Tscmoo protoss finally settled on its winning opening too. Also of course it was playing a larger proportion of games against Iron and Krasi0, and against Killerbot by Marian Devecka, which this Steamhammer scores about 50% against.

After the tournament, with 5 Pool disabled, Steamhammer’s elo still hasn’t recovered. It hovers around 2200. Tscmoo protoss hasn’t forgotten its winning opening. Also the zergs Ailien and Microwave have improved to beat it more often, getting better air defense and reducing their strategy mistakes. Even lower-ranked protoss Lukas Moravec has been winning games with its zealot rush, stealing gas in some games. Steamhammer doesn’t work around the BWAPI geyser bug and its game plan is derailed by a gas steal. I think Steamhammer’s #3 rank (since lost) and its status as the handle of a fork with many tines made it a target, and since it has plain weaknesses, people have figured out how to exploit them. Or maybe they’re trying to reprioritize my to-do list, “This is the important weakness, please help.” :-)

Meanwhile, I’ve been spending most of my effort on skills for protoss and terran. The next Steamhammer will come with protoss DT drop and terran vulture drop, but no zerg drops. Overlords are more complicated, and I decided to save it for later. (Getting drop to work at all needed a mess of code changes across classes: CombatCommander, Squad, SquadOrder, MicroManager, other micro classes, StrategyManager—and that is accepting the limitation of dropping a fixed set of units, once, from one dropship or shuttle, and then transitioning out.) Terran will track its use of scan and have more infantry skills and smarter tanks, protoss will support more unit types and use them, both will have more transitions and other improvements. Also I’m making micro changes for all races which add flexibility but require tuning, so there may be new micro weaknesses until I figure out what works.

I hope to get in zerg specific improvements to overcome the biggest weaknesses. I know what to do, but the list is long and I’m not sure how far I’ll get. Anyway, the bottom line: I can’t promise that the next version will be stronger. What I know for sure is that it will be more interesting.

And I can’t wait to get back to zerg.

a new UAlbertaBot bug fix

The bot bftjoe by Joseph Huang fixes a bug in UAlbertaBot that I did not catch.

bool UnitUtil::CanAttack(BWAPI::Unit attacker, BWAPI::Unit target)
{
    return GetWeapon(attacker, target) != BWAPI::UnitTypes::None;
}

Easy to type, easy to read past... and totally wrong. Unit type None is 228, which does not match the value of any weapon type, so it will always return true. “All ints are the same type, right?” Bjarne Stroustrup: “Uh, sure.”

bool UnitUtil::CanAttack(BWAPI::Unit attacker, BWAPI::Unit target)
{
    return GetWeapon(attacker, target) != BWAPI::WeaponTypes::None;
}

In UAlbertaBot, CanAttack() is used only in the tank manager, so the damage, er, fallout, er... severity is limited. Steamhammer additionally uses the function in controlling lurkers, which it does not build by default because its control is so poor. So the next Steamhammer version should be a little less clumsy with tanks and lurkers. Still pretty clumsy, though; the clumsiness runs deep.

Tomorrow: The newly uploaded Krasi0 seems to be playing new builds.

Steamhammer will drop

It’s decided. The next Steamhammer version will support drop. Dave Churchill had already implemented most of the skill: Choosing a transport for the job, sending it on a sneaky path around the edge of the map, and unloading it near the enemy’s mineral line. The remaining bits are proving surprisingly tricky: Choosing units to load, keeping them together until everything is ready, loading them up (seems like a key step), and not doing anything too ridiculous after they land (“oh no it’s scary here, let’s skip this job and go home”). Even so, I expect to get it working reasonably well by tomorrow, the day after at worst.

It’s limited. It only supports 1 transport, and after dropping it does not know how to reset itself for a second drop. Better make the one try count! I wrote a dark templar drop build for protoss. I’ll try to add a terran drop build, though it won’t be as dangerous. If I feel ambitious I’ll do the bit of extra work for a lurker drop too.

It’s a good start. Fancier versions can come along later.

Update: The first time I got a dark templar drop to land in a terran base, the dark templar said “Uh oh, our own base is under attack. We must ignore the enemy in front of us and walk across the whole map to defend!” Not doing anything too ridiculous after they land is a vital skill....

Steamhammer-Microwave razor close game

SSCAIT’s mini-tournament is not quite finished as I write.

The irritating news of the tournament: Steamhammer played 2 tournament games versus XIMP by Tomas Vajda, plus one game shortly before the tourney, on the same map (Benzene) with the same starting positions (protoss on the left, zerg on the right). Just how random is it? The 3 games were nearly identical, down to individual army movements, and Steamhammer lost, as it should have, because it doesn’t understand map blocks and couldn’t finish its opening build. Sometimes luck hits like a truck.

The interesting news of the tournament: Tscmoo protoss is doing surprisingly well, including against opponents that it has a mixed record against. Did its opening learning, which was reset in December, finally gather enough data to make good decisions? We’ve seen before that Tscmoo brings its best against strong opponents. What’s behind that?

A razor close game between Steamhammer and Microwave on Python: Steamhammer opened with overpool into fast spire, while Microwave went overpool with zergling speed and mass lings, leading to a later spire. Steamhammer made 2 sunkens with its spire. When Microwave’s zergling numbers grew large enough, it defeated Steamhammer’s lings and pushed in; the sunkens and 2 fresh zerglings were barely enough to hold them off. When its faster second hatchery came online, Microwave attacked again; the second wave killed the sunkens and a couple of drones, but the first mutas cleaned up. The third wave left 2 Steamhammer drones alive, and by then Microwave’s spire was up too, and soon Microwave destroyed Steamhammer’s spire. Steamhammer scourged an overlord, which delayed Microwave just enough. Here Microwave is adding drones when it should be replenishing its army.

Steamhammer’s spire is destroyed

If you make too many drones in ZvZ, you die. Microwave was behind in air power and did not keep the pressure on. Steamhammer killed another overlord, outmicroed the scourge...

Steamhammer outmicroes scourge

... and brought down the excessive number of drones while defeating mutalisks that spawned one at a time. Microwave helped by transferring drones from its natural to the main where the mutas were. Microwave might have held if it had gotten up a spore colony in time, but it was too late.

Steamhammer clears drones and mutas

Steamhammer is #1

Oops, Steamhammer became the #1 bot on the SSCAIT ranking.

detail of SSCAIT rating list

It pulled ahead of Krasi0 by a hair. I don’t expect it to stay #1 for long. It still can’t beat Iron or Krasi0 more than occasionally. Iron has lost rating points lately because Igor Dimitrijevic is putting it through a strategy change, and it will take time to tune up Iron’s new play. As that proceeds, Iron will work to claw back its first place. In the meantime, apparently Steamhammer has been defeating lower-ranked bots about as reliably as Krasi0 does.

I have to give in and admit that Steamhammer is no longer merely a threat to the top bots, it is a top bot itself, even if it struggles head-to-head against the very best. Well, I predicted all along that bug fix release 1.2.2 would restore the strength of 1.2 and then some, after the dip caused by bugs in version 1.2.1.

Meanwhile, Randomhammer has been getting fewer games and its rating has not stabilized yet. I’m expecting it to reach about 2100, maybe a little more. The bug fixes should make all races stronger.

Moral: Experience shows that feature releases are sometimes stronger and sometimes weaker, but bug fix releases are always stronger. Fix more bugs!

a new secret weapon in ZvZ

Yesterday I watched a pro ZvZ game from 2010 where the winner played an opening I had not seen before. “Hmm, does that have good timings against overpool?” I thought. It seems to be a rare opening and is not documented on Liquipedia, but I coded up a version and tested it out. The scores are Steamhammer 1.2.2 set to play one fixed opening, versus each opponent.

victimscoreversion
Ailien13-2uploaded 4 April
Killerbot14-1SSCAIT 2016
Microwave14-10.15, uploaded 5 April
Steamhammer11-41.2.2, latest release with 11 ZvZ openings
Zia15-0uploaded 7 September

Holy Saint Isidore, Batman! Bots are not prepared for this!

Killerbot scored 1 win when Steamhammer made a tactical mistake of a kind that I intend to fix in the upcoming version. Microwave was able to exploit a risk inherent to the opening—once. Zia tried its builds one after another and lost with all of them. Ailien’s machine learning came the closest to finding an answer; it tried different tacks, and a few of the games were fierce. By the end of the match it seemed to be grasping at straws: Do hydras work? No! Do lurkers work? No! Every fixed opening has counterbuilds, and a human player who knew what was coming would find it easy to beat. It is possible that the counterbuilds are outside Ailien’s gamut, or take over 15 games to find. The release version of Steamhammer itself put up the strongest fight but was forced down.

Of course Steamhammer does not play fixed openings outside of tests like this. I think that adding the new opening to its repertoire is likely to make Steamhammer impervious for a long time to machine learning attacks on its openings.

I’ll be holding my secret weapon in reserve until version 1.2.3 comes out. Everything will be published then, but I also enjoy springing surprises. This will change the meta, and I would like to be 2 steps ahead.