archive by month
Skip to content

Tscmoo and squad coherence

In my post about independent control for unit micro I mentioned that Tscmoo can “lose squad coherence” without explaining what that is. I meant that Tscmoo likes to spread its units out instead of keeping them in a bunch, and sometimes units that start out working together end up separated and unable to cooperate. Here are a couple games from today to illustrate. I think the behavior is especially clear with zerg, so these are games of Tscmoo zerg.

the good side

First a game to show what Tscmoo gains by scattering units over the map, Tscmoo zerg versus Wuli on Heartbreak Ridge. Tscmoo opened in a way that left itself vulnerable to Wuli’s zealot rush. When the first 4 zealots arrived, Tscmoo had 4 zerglings to try to keep its morphing natural alive. Wuli already had 2 more zealots on the way, so it was army supply 12 versus 2. It looked like the natural would fall for sure.

Well, the fight went on for a while, but Tscmoo’s basic method was to run away and lure zealots out of position, then mob any zealots that strayed and could be locally outnumbered. Wuli didn’t reinforce properly and let its units get distracted, so that its powerful army went on goose chases and accomplished little. In the picture, zealots are chasing a zergling away from the natural. Notice the yellow dots on the minimap; Tscmoo is scattered around.

Tscmoo leads goose chases

Eventually mutalisks came out and zerg won. Tscmoo prevailed because its willingness to run away in different directions confused Wuli, which did not know how to concentrate its forces on a vulnerable point like the natural hatchery. Goose chases confuse a lot of bots, including Steamhammer (so far), and they are responsible for a lot of Tscmoo’s resilience when facing defeat.

the bad side

The image I had in mind when I wrote “loses squad coherence” was a Tscmoo group coming under pressure and forced to retreat. Human players like to have lines of retreat if they are pressed back, so they can keep their units together. Tscmoo likes to form a giant concave and doesn’t seem to pay attention to lines of retreat. As the concave is forced farther back, different units may retreat through different exits so that what was once a group fighting together breaks up into subgroups that the enemy may be able to defeat in detail, or ignore and bypass. There is no longer one coherent squad.

The game Tscmoo zerg versus Krasi0 is not as clear an example as the last game, but it shows what I mean. Tscmoo went for a hydralisk all-in and laid on a punishing attack. The game was decided when Krasi0 held with strong tank placement. In the picture, Tscmoo’s retreating hydralisk group is forced off the central plateau on Jade and breaks up as I described above. The hydras took different exits and did not join up again.

Tscmoo’s forces retreat in different directions

Goose chases do not confuse Krasi0. Krasi0 goes for the throat.

impressive gas steal bug

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

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

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

Steamhammer-ICEbot impressive blunder

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

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

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

an unnoticed goliath attacks

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

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

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

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

McRave-Iron - narrowing the entrance

I thought this picture was funny. In a game yesterday against Iron, McRave fast expanded and walled off one of the bridges to its natural, but left the other bridge open. Vultures cannot pass the wall, but they happily took the other bridge and Iron won easily.

1 bridge blocked, 1 open

McRave seemed to mess up its build, getting dragoons too late. (The underlying mistake may have been taking gas at the natural instead of the main.) But the idea is sound. McRave is narrowing the entrance to its natural, making it easier to defend against vultures. A small number of dragoons can block a narrow entrance, either early in the game when there are only a few dragoons on the map, or later when the main army is away and the only dragoons around are those rallied from the gateways.

Its next game against Iron was on Roadrunner. McRave won using the same idea of narrowing the entrance.

buildings partly block the entrance

McRave’s dragoons beat Iron, so they played well by bot standards. But I see room for improvement. Vultures can pass either left or right of the upper gateway. I think the first 2 dragoons should plug the gaps so that vultures are physically blocked. Iron will lay mines to force its way in, and then the dragoons can retreat to the defense line McRave actually held, the gap between the lower gateway and the nexus. The farther away the vultures and their mines are kept from the probes, the better.

too many devourers

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

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

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

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

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

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

massive purple goop

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

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

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

gas steal plans

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

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

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

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

Steamhammer versus McRave and KillAll

I thought these 2 games showed interesting mistakes.

Steamhammer-McRave

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

Steamhammer fails to contain its opponent

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

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

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

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

Steamhammer-KillAll

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

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

Steamhammer fails to contain its opponent

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

KillAll fails to attack its opponent

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

Next: Thoughts on the gas steal.

Steamhammer-PurpleWave games

“Somebody” voted in a bunch of Steamhammer versus PurpleWave games. PurpleWave played different openings. Past versions of PurpleWave dominated Steamhammer with the forge-expand opening, taking advantage of Steamhammer’s mistaken macro decisions and weak scouting and tendency to collapse tactically in a big fight. But this PurpleWave has been losing some; it has new weaknesses. So the games are not the best, but they are still interesting.

Some of the games were proxy 2 gates. There were wins and losses, but I found those games not as interesting.

on La Mancha

This is the Steamhammer-PurpleWave game that Nepeta cast last Sunday, so I won’t go into detail. PurpleWave suffered bugs that caused it to warp buildings near the zerg forces and pull probes for no reason, so it did not develop its usual big advantage. What I find interesting about the game is the turning point, when zerg pulled decisively ahead: It was when protoss attacked the zerg natural and dealt great damage, destroying the drones.

PurpleWave overcommits to the attack

The returning zerg army finally cleared the attack. The protoss army was trapped and could not retreat toward home. It should have “retreated” into the zerg main to try to deal more damage (and to pull the zerg army away from the front), but instead turned fatalistic and gave up without a fight. Meanwhile, zerg had many drones at other bases and quickly restored the losses, while the lost protoss army was not as easy to replace. The value of destroying drones depends not on the number of drones you kill, but on the number that survive somewhere....

on Icarus

This game was also a forge-expand, but the play was quite different. No obvious bugs bit. PurpleWave built 4 cannons, which is plenty for most circumstances... and Steamhammer busted them anyway.

Steamhammer busts the 4 cannons

Steamhammer killed probes too. Then I tore my hair out in frustration, because instead of pressing for the win, Steamhammer decided it was more important to simultaneously plant a spire, hatchery, evo chamber, and hydra den, and also grow its economy. Notice in the picture that, although Steamhammer has spent 4 drones on buildings, it is still ahead in workers—and PurpleWave has cautiously pulled probes for defense. The spire, by the way, was left unused until late. With 2 bases, PurpleWave eventually caught up from far behind and the game was on again.

Steamhammer puts the fight off until later

Fortunes turned again, like last time, when PurpleWave overpressed and lost too much army at Steamhammer’s natural. Seconds after this picture, protoss went from ahead in army size to well behind. Zerg quickly replaced drone losses and soon broke into the protoss natural in return.

Steamhammer is about to clear its natural

on Destination

PurpleWave went 2 gate zealots into expansion. Neither bot had much understanding of the situation. Steamhammer massed lings, an all-in play to smash the opponent. In practice it’s successful against most bots, but zerg ends up way behind in economy. Protoss can play defensively for a while and then win easily—that’s how Tyr protoss beats Steamhammer.

The game is not long or exciting. PurpleWave expanded in the face of the zerg swarm and did not have enough zealots. I include it to show how little bots understand strategy. In the picture, Steamhammer has half the workers of protoss. With any insight into the army-economy balance, you have to conclude that it is not a time for protoss to take a risk like expanding or moving out. The zealots again went fatalistic; as soon as they realized that they had lost, they stopped fighting and (unable to retreat far) were caught and died. You can also see that in the picture. Steamhammer has related weaknesses that are different but as severe.

PurpleWave takes a foolish risk and loses

PurpleWave might have had a chance if it retreated to the ramp and canceled the nexus. It was the best option, at least.

I expect that PurpleWave will fix its bugs before long and start winning again.

Next: More games, versus McRave and KillAll.

Steamhammer and stealing gas

Back in an early Steamhammer release, I tested stealing gas, concluded that it worked, and called it good. Since then I haven’t paid much attention.

Now I’m working through systematically to make sure that stealing gas always works when it should, and that it interacts correctly with scouting (which has grown more complicated since then). While I was looking away, the gas steal bitrotted as its surroundings changed and it did not keep up. For example, in testing with terran today I fixed a bug where the scout arrived at the enemy geyser, queued up a refinery on it... and then BuildingManager assigned a different worker to do the job, sending an SCV from the main. I even found and fixed a potential crashing bug, though it could only happen on very nonstandard maps.

Next: Steamhammer vs. PurpleWave games.

Steamhammer-tscmoo games

When I first promised Steamhammer-Tscmoo games, Steamhammer had been winning most games against Tscmoo terran, despite dangerously aggressive terran play. Some of the games were good. Since then, Tscmoo has been updated, and now most of the Tscmoo bots (all except protoss) are ranked just above Steamhammer. Games have gone both ways, but I think Tscmoo has the edge overall.

a September game

In this game on Roadrunner Steamhammer played a 3 hatch lurker build that was a direct counter to Tscmoo’s fast academy. If zerg had played accurately, it would have been an easy win. As it was, zerg was unclear on the concept of defense and narrowly held by accidentally making just enough zerglings in a hardscrabble game. If Steamhammer had played a mutalisk opening, it would have lost, because the muta openings make fewer lings. Here Tscmoo’s last attack has broken through and the small terran force is frying drones—most of the drones in the picture died.

Steamhammer loses drones

But lurkers were already out, and Steamhammer broke the attack with a hammer blow and then turned the hammer outward.

Tscmoo loses everything

a recent game

Lately, Tscmoo terran has been playing sequences of tricky tech switches. Tscmoo played random on Destination in this game and got terran. It’s a 2 player map, and terran started with a barracks on 6 hidden in the corner of the zerg natural out of sight of the scouting drone, an early proxy that could be deadly. Luckily, Steamhammer tries to be ready for anything against a random player, and it opened with a safe overpool. Tscmoo in turn scouted Steamhammer’s safe opening and opted not to train marines right away (they would have died uselessly), but to move on to the next tech.

Early zerglings still did not spot the barracks. Tscmoo made marines in time for Steamhammer’s expansion; it may be a coincidence, but maybe Tscmoo is smart enough to know the timing. In any case, as you can see from the unit counts, zerg was more than prepared.

Steamhammer finds the barracks

Most of Steamhammer’s lings went to the terran main, as you can see in the minimap above. Tscmoo has strong worker defense, and the fight was not entirely one-sided. And of course Tscmoo had been preparing its next tech, vultures. When they were done, the vultures chased the lings out. Steamhammer knew what was coming, though, and put down a sunken in its main for safety, and one in the natural a little later when the natural finished. The vultures also did not achieve much.

Meanwhile, Tscmoo started a starport, the next tech switch. Steamhammer saw that too and put down a hydra den while trying to catch up in workers; despite killing a few SCVs, zerg was behind because it had made too many combat units. But instead of putting on wraith pressure, Tscmoo made an extreme move while waiting for wraith cloak research to finish: It added a tank (without siege) and pulled almost all its SCVs across the map for an all-in attack.

Tscmoo pulls SCVs

Steamhammer knew how to defend this one. Zerg made an emergency switch to mass lings with a few hydras, and with the help of the sunken the attack was beaten back with heavy losses. Zerg went from behind to ahead, plus Steamhammer started a spire and was able to safely return to droning up. Zerg had wasted money on lurker research, but it no longer mattered.

Tscmoo finally pulled the wraith switch, but the long delay meant that Steamhammer was again ready. The first wraith was able to kill a couple drones before scourge hatched. The wraith instantly cloaked when it saw the danger, but cloak is no use when you have chosen to fly right next to an overlord.

Steamhammer realized, more slowly than it should have, that mutas were the right choice, and brought pressure back to the terran. Tscmoo switched again, to valkyries for air defense, but zerg scourged most of them and terran could not hold the line long enough to build a stable force. (If it had, Steamhammer was still ahead and I think it would have switched to hydras and won anyway. It knows how.) Here scourge are intercepting the first valkyrie—by coincidence, the scourge were waiting by the starport (someday I’ll add code to do that on purpose).

scourging a valkyrie

I think Tscmoo showed greater ability, but it took big risks which did not pay off in this game. The SCV pull in particular was not a smart plan. Even so, you can see how easily zerg could have made a mistake and lost; Tscmoo earned its high place in the ranking.

Here’s a human game with a similar sequence of terran tricks: July vs Firebathero from 21 September, on the map Hitchhiker. Firebathero’s sequence of bunker to vultures to wraiths is 100% standard. July was ready and had some zerg tricks in response. Even if you don’t have much Starcraft expertise, it should be easy to see that this game is on a way higher level than the bot game.

Steamhammer’s devourers are almost OK now

A quick note: I finally got devourers working sort of OK in the development Steamhammer. They are no longer horrible and useless as in the live version. Of course this means that I instantly get new items on my to-do list, like “teach other units to target enemies that carry acid spores” and “teach FAP about the effects of acid spores.” One step at a time!

As a side effect, corsairs and valkyries are also better. The corsair-dark templar opening is improved to the point that it is... not good, but within shouting distance of acceptable. The work was a combination of bug fixes, improved tactics, and adding a new MicroAirToAir unit controller for the air-to-air splash units.

AIIDE 2017 AILien does not learn

AILien’s learning turned out to be non-existent in the AIIDE 2017 version. It writes files but does not read them back in.

Here is AILien’s recorded data from AIIDE 2017 for the opponent XIMP.

lingScore=24.4783
hydraScore=-4762.48
lurkerScore=0
mutaScore=-904.381
ultraScore=-1757.08
guardScore=0
macroHeavyness=0
supplyISawAir=149
strategy=17
victory=false

The first six lines are information about what units to make, as updated during the game. macroHeavyness and supplyISawAir are updated but I didn’t find any sign that they are used for anything; I think they were used in a former version. strategy likely used to be an index into the unused GameCommander::strategyMap, but no matter what it originally was, now it is a constant. And victory is the result of the most recent game. As I said at the start, the information is written out but is never read back in.

Next: Those tscmoo games I promised last month.

AIIDE 2017 what AIUR learned

Here is what AIUR learned about each opponent over the course of the tournament. I did this mostly because it’s easy; I already had the script from last year. But it’s also informative—AIUR’s reactions tell us how each bot played, and may tell bot authors what they need to work on.

The data is generated from files in AIUR’s final read directory. AIUR recorded 111 games against some opponents even though the tournament officially ran for 110 rounds; that is presumably because the tournament did run longer but was cut back to a multiple of 10 rounds for fairness (since there are 10 maps). On the other hand, AIUR’s total game count according to itself is 2938 and according to the tournament results is 2965, so it may have been unable to record some games (it is listed with 53 crashes, so that’s not a surprise). First an overall view, totalling the data for all opponents. We can see that all 6 of AIUR’s strategies (“moods” it calls them) were widely valuable: Every strategy has win rate over 50% on some map size. AIUR’s overall win rate in the tournament was 50.46%.

overall234total
 nwinsnwinsnwinsnwins
cheese15955%5937%16144%37947%
rush13466%8755%18550%40656%
aggressive10756%10843%15530%37041%
fast expo6945%8433%19751%35046%
macro4628%6952%21137%32639%
defensive35260%18558%57055%110757%
total86757%59249%147948%293850%
  • 2, 3, 4 - map size, the number of starting positions
  • n - games recorded
  • wins - winning percentage over those games
  • cheese - cannon rush
  • rush - dark templar rush
  • aggressive - fast 4 zealot drop
  • fast expo - nexus first
  • macro - aim for a strong middle game army
  • defensive - be safe against rushes (not entirely successful)
#1 zzzkbot234total
 nwinsnwinsnwinsnwins
cheese1612%10%40%2110%
rush50%10%10%70%
aggressive30%10%50%90%
fast expo40%10%50%100%
macro30%20%30%80%
defensive30%1631%3724%5625%
total346%2223%5516%11114%

AIUR struggled against the tournament leader but was not entirely helpless. Its cannon rush had a chance on 2 player maps and its anti-rush strategy on the others. We see how AIUR gains by taking the map size into account.

#2 purplewave234total
 nwinsnwinsnwinsnwins
cheese10%10%20%40%
rush2879%333%4055%7163%
aggressive10%333%10%520%
fast expo10%1136%1060%2245%
macro10%20%10%40%
defensive10%10%10%30%
total3367%2129%5551%10951%

AIUR upset #2 PurpleWave, a surprising outcome. The DT rush and the fast expand were both somewhat successful—rather unrelated strategies.

#3 iron234total
 nwinsnwinsnwinsnwins
cheese50%10%70%130%
rush50%20%70%140%
aggressive30%20%120%170%
fast expo80%147%90%313%
macro60%10%100%170%
defensive50%20%100%170%
total320%225%550%1091%

Learning can’t help if nothing you try wins....

#4 cpac234total
 nwinsnwinsnwinsnwins
cheese10%10%10%30%
rush40%00%20%60%
aggressive20%10%10%40%
fast expo10%10%10%30%
macro20%333%20%714%
defensive2438%1669%4850%8850%
total3426%2255%5544%11141%

Cpac was configured to play 5 pool against AIUR. It worked, but AIUR was able to compensate to an extent by playing its anti-rush build.

#5 microwave234total
 nwinsnwinsnwinsnwins
cheese20%20%40%80%
rush10%10%40%60%
aggressive2020%1513%110%4613%
fast expo10%20%60%90%
macro10%10%40%60%
defensive10%10%2612%2811%
total2615%229%555%1039%

Microwave was successful but showed a little vulnerability to surprise zealots dropped in its main. I suspect it’s a tactical reaction issue.

#6 cherrypi234total
 nwinsnwinsnwinsnwins
cheese10%10%10%30%
rush10%10%10%30%
aggressive20%20%10%50%
fast expo20%10%10%40%
macro20%10%911%128%
defensive264%1612%4212%8410%
total343%229%5511%1118%


#7 mcrave234total
 nwinsnwinsnwinsnwins
cheese26100%560%4562%7675%
rush367%967%450%1662%
aggressive10%450%10%633%
fast expo10%250%250%540%
macro10%10%10%30%
defensive10%10%20%40%
total3385%2255%5556%11065%

AIUR upset McRave with its cannon rush, and the dark templar rush did well too. AIUR executes the best cannon rush of any bot, in my opinion. It is a sign that McRave’s play was not robust enough against tricks.

#8 arrakhammer234total
 nwinsnwinsnwinsnwins
cheese20%20%30%70%
rush10%10%40%60%
aggressive10%560%30%933%
fast expo10%10%20%40%
macro00%1250%3837%5040%
defensive2966%10%425%3459%
total3456%2241%5428%11039%


#9 tyr234total
 nwinsnwinsnwinsnwins
cheese667%10%10%850%
rush20100%10%20%2387%
aggressive333%1020%10%1421%
fast expo10%729%4935%5733%
macro10%10%10%30%
defensive250%20%10%520%
total3379%2218%5531%11043%

The DT rush won 100% of the time on 2 player maps and was tried only a few times on larger maps, losing. Was it only unlucky on the 3 and 4 player maps, or is there a real difference? With only 3 games total, we can’t tell from the numbers. It is a weakness of AIUR’s learning: It’s slow because there is so much to learn. The flip side of the slowness is that, over a long tournament, it learns a lot.

#10 steamhammer234total
 nwinsnwinsnwinsnwins
cheese20%10%10%40%
rush250%10%20%520%
aggressive10%10%10%30%
fast expo10%10%10%30%
macro00%10%10%20%
defensive2781%1788%4967%9375%
total3370%2268%5560%11065%

I was surprised to see Steamhammer upset by AIUR. I had thought that AIUR was a solved problem. On SSCAIT too, Steamhammer started to show losses against AIUR in September for the first time in months. I may have introduced a weakness in some recent version and AIUR’s learning took that long to find it on SSCAIT. In AIIDE, the tournament was easily long enough.

#11 ailien234total
 nwinsnwinsnwinsnwins
cheese10%10%10%30%
rush30%10%20%60%
aggressive10%20%10%40%
fast expo10%250%00%333%
macro450%875%10%1362%
defensive2458%888%4937%8148%
total3447%2264%5433%11044%


#12 letabot234total
 nwinsnwinsnwinsnwins
cheese743%10%20%1030%
rush333%1354%4340%5942%
aggressive540%10%10%729%
fast expo1346%333%10%1741%
macro10%10%633%825%
defensive10%333%10%520%
total3040%2241%5435%10638%

I suspect that fast expo was the best strategy on 4 player maps, but how was AIUR to know? A weakness of AIUR’s epsilon-greedy learning, compared to UCB, is that it doesn’t realize that a less-explored option is more likely to be misevaluated.

#13 ximp234total
 nwinsnwinsnwinsnwins
cheese3435%00%10%3534%
rush00%00%10%10%
aggressive00%138%522%653%
fast expo00%90%00%90%
macro00%00%10%10%
defensive00%00%00%00%
total3435%225%552%11113%


#14 ualbertabot234total
 nwinsnwinsnwinsnwins
cheese00%00%1100%1100%
rush00%00%00%00%
aggressive00%00%1100%1100%
fast expo00%00%00%00%
macro00%00%00%00%
defensive3432%215%5227%10724%
total3432%215%5430%10926%

What’s up with all those zeroes? AIUR is coded to try each strategy once before it starts making decisions, and that did not happen here. It turns out that AIUR has pre-learned data for Skynet, XIMP, and UAlbertaBot, so its learning in those cases looks different.

#16 icebot234total
 nwinsnwinsnwinsnwins
cheese10%20%10%40%
rush10%250%333%633%
aggressive3100%367%450%1070%
fast expo14100%367%4493%6193%
macro475%250%10%757%
defensive989%1080%250%2181%
total3288%2264%5582%10980%


#17 skynet234total
 nwinsnwinsnwinsnwins
cheese1392%00%00%1392%
rush2195%2190%5188%9390%
aggressive00%00%00%00%
fast expo00%1100%00%1100%
macro00%00%00%00%
defensive00%00%450%450%
total3494%2291%5585%11189%


#18 killall234total
 nwinsnwinsnwinsnwins
cheese10%30%10%50%
rush10%20%10%40%
aggressive10%20%10%40%
fast expo10%30%10%50%
macro00%20%250%425%
defensive3080%1070%4976%8976%
total3471%2232%5569%11162%


#19 megabot234total
 nwinsnwinsnwinsnwins
cheese367%10%20%633%
rush20%1436%50%2124%
aggressive667%425%40%1436%
fast expo250%10%40%714%
macro10%10%3625%3824%
defensive1776%10%20%2065%
total3165%2227%5317%10633%


#20 xelnaga234total
 nwinsnwinsnwinsnwins
cheese9100%683%10%1688%
rush19100%475%10%2492%
aggressive10%333%10%520%
fast expo10%475%10%650%
macro20%250%5036%5435%
defensive250%367%10%650%
total3485%2268%5533%11156%

Against Xelnaga, AIUR found solutions on 2 and 3 player maps but not on 4 player maps. Is it another case of underexploration?

#21 overkill234total
 nwinsnwinsnwinsnwins
cheese10%10%367%540%
rush250%00%00%250%
aggressive8100%4100%786%1995%
fast expo367%3100%7100%1392%
macro475%367%1292%1984%
defensive1493%11100%2696%5196%
total3284%2291%5593%10990%


#22 juno234total
 nwinsnwinsnwinsnwins
cheese50%1436%3315%5219%
rush30%10%10%50%
aggressive20%10%20%50%
fast expo20%10%1612%1911%
macro10%10%10%30%
defensive1921%425%20%2520%
total3212%2227%5513%10916%

Juno’s cannon contain upset AIUR. Learning didn’t help much, because the problem wasn’t in any of the strategies, it was in AIUR’s poor reactions to cannons appearing in front of its base. It is amusing to watch 2 bots cannon each other when sometimes both get cannons up.

#23 garmbot234total
 nwinsnwinsnwinsnwins
cheese10%10%10%30%
rush250%10%00%333%
aggressive1794%17100%367%3795%
fast expo00%10%2383%2479%
macro00%10%10%20%
defensive580%10%2781%3379%
total2584%2277%5578%10279%


#24 myscbot234total
 nwinsnwinsnwinsnwins
cheese10%10%250%425%
rush20%367%250%743%
aggressive333%2100%978%1471%
fast expo10%250%10%425%
macro450%4100%367%1173%
defensive2361%10100%3879%7176%
total3450%2286%5575%11169%


#25 hannesbredberg234total
 nwinsnwinsnwinsnwins
cheese580%3100%367%1182%
rush250%3100%250%771%
aggressive250%250%20%633%
fast expo8100%3100%989%2095%
macro250%4100%1191%1788%
defensive15100%7100%28100%50100%
total3488%2295%5589%11190%


#26 sling234total
 nwinsnwinsnwinsnwins
cheese250%10%333%633%
rush250%00%10%333%
aggressive12100%00%2396%3597%
fast expo10%5100%10%771%
macro367%580%1275%2075%
defensive580%11100%1580%3187%
total2580%2291%5580%10282%

Here is another possible case of insufficient exploration. The 4 zealot drop won 100% of the time on 2 player maps and 96% of the time on 4 player maps, but was never tried on 3 player maps (I guess due to a crash, since AIUR tries to play each strategy once). It’s not a severe problem, though, because 3 player maps did have 2 strategies that scored 100%.

#27 forcebot234total
 nwinsnwinsnwinsnwins
cheese10%10%10%30%
rush00%10%10%20%
aggressive367%20%10%633%
fast expo00%10%10%20%
macro00%978%367%1275%
defensive29100%875%4894%8594%
total3394%2259%5585%11083%


#28 ziabot234total
 nwinsnwinsnwinsnwins
cheese12100%786%3686%5589%
rush10%1100%475%667%
aggressive6100%888%683%2090%
fast expo10%10%20%40%
macro30%10%10%50%
defensive667%475%683%1675%
total2976%2277%5580%10678%

Next: AILien’s learning.

Overkill’s games

In September I looked into the source of Overkill AIIDE 2017. It has much more extensive and ambitious learning than Overkill 2016. But at the time, no replays were available, so I didn’t know how well the learning worked.

Overkill 2017 has 2 kinds of learning. One is online opening learning, which of 3 openings to play against each opponent. This is the same simple method as many other bots. The other is strategy learning, what to build/research/etc. next; I think this learning is offline, done ahead of time. The graph of win rate over time shows a modest increase in score throughout the tournament, consistent with the opening learning. The modest increase was enough to pull Overkill ahead of 5 different opponents that started out better.

Here is Overkill’s tournament history. I believe these tournaments represent 3 different versions of Overkill. The 2017 version played only in AIIDE 2017.

tournament#%
CIG 2015381%
AIIDE 2015381%
CIG 2016 qualifier471%
CIG 2016 final551%
AIIDE 2016762%
CIG 2017760%
AIIDE 20172133%

It’s safe to say that the learning was not successful.

What did the games look like? In every game I looked at, Overkill played sunken defense and then seemed hesitant and uncertain what to do next. It researched tech that it did not use, or did not use until much later; it made scourge when the opponent had shown no sign of air units; it added more hatcheries than its income could feed. The sunken defense worked especially poorly when the opponent went air. The basic mistakes caused weak results. I don’t know the training procedure; I can only guess that maybe the neural networks were not trained enough, or were trained on crummy data, or were misled by bugs. Or something.

Oh well. :-( Learning is hard.

Overkill-McRave is one of Overkill’s better games. #21 Overkill scored 50% against #7 McRave, which you could count as an upset. Overkill-IceBot is a more typical game with some OK action. Overkill-Juno is a sad, sad game that ran the full hour due to suicidal play by both sides.

Next: Catalog of bots which wrote learning files.

looking at cpac

Cpac is a Steamhammer fork, so it’s easier for me to evaluate. On the other hand, the code has been reformatted, so a diff only says “everything’s different.”

Overall, cpac is very similar to Steamhammer, but corrects critical weaknesses. I think the author chose accurately which weaknesses were important to correct, and cpac should play clearly better than Steamhammer in many situations. It implements a number of ideas that I thought of or planned, always in a completely different way than I would have. It also removes some, but not all, code to support terran and protoss.

The most interesting changes are to the strategy.

strategy changes

The headline change is that, when cpac is out of book, it chooses the next unit to build using a neural network which was learned offline. It replaces Steamhammer’s long list of strategy rules with 2 calls, to extract the features of the game situation and feed them through the network to choose the next unit to make. Well, it makes an exception of the opponent is rushing; then it chooses an emergency unit by a set of emergency rules.

BuildOrder & StrategyBossZerg::freshProductionPlan()
{
	_latestBuildOrder.clearAll();
	updateGameState();
	// We always want at least 9 drones and a spawning pool.
	if (rebuildCriticalLosses())
	{
		return _latestBuildOrder;
	}
	ExtractFeature();
	predictUnit();

	return _latestBuildOrder;
}

According to the readme file, it was trained against the dataset of the paper A Dataset for StarCraft AI & an Example of Armies Clustering. The data comes from replays of expert human games. The network can choose a unit of one of 8 types, and the drone is not included. (Whether to make a drone or something else is the most important zerg macro decision, if you ask me.)

I suspect that the readme may not give the full picture. In games where cpac gets zealot rushed, I notice that it plays sunken defense into lurkers, which works against bots but does not happen in expert human play. I think either the database includes some extra data to cover that case, or else there is an exception that I didn’t notice which applies different rules.

Cpac is able to recover from some setbacks after the opening by applying emergency rules. Other mishaps leave it helpless. For example, in this horrible game versus Overkill, cpac lost most of its drones and never rebuilt beyond 9, because if you have 9 drones it’s “not an emergency.” In general, cpac’s play becomes blander and more predictable as the game continues.

Here’s a funny game against HannesBredberg showing good and bad unit mix decisions.

tactical and micro changes

I don’t think I found all the tactical and micro changes. Here are a few of the things I did find.

Cpac adds a new file MicroFlyers which is responsible for mutalisks and scourge. Among other things, it greatly improves on Steamhammer’s scourge micro and helps mutalisks fly around cannons.

Cpac hardcodes mutalisk targets for specific maps in StateManager. The idea seems to be that if the opponent is protoss and has cannoned up one base, the mutas should fly specific paths to find other bases that may be undefended. It fixes a critical Steamhammer weakness (“Cannons! My way is blocked, I can’t get past them!”) in a quick and dirty way.

Cpac can position sunkens toward the enemy, a longstanding Steamhammer weakness that most forks fix on their own. (I’m waiting for the future building placement planner.)

the openings

Cpac plays fixed openings against 9 opponents. Some of the openings are general purpose, and some (you can tell by the names alone) are custom tailored.

  • UAlbertaBot - OverpoolSpeedDave
  • Steamhammer - 5PoolHard
  • Aiur - 5PoolHard
  • Ximp - 2HatchMutaXimp
  • Skynet - 5PoolHard
  • MegaBot - 5PoolHard
  • Microwave - ZvZ_Overpool9Gas
  • ZZZKBot - 9PoolSpeedExpo
  • McRave - 2HatchMutaMcRave

The ZZZKBot setting backfired when ZZZKBot did not play as expected. The other settings successfully exploited weaknesses. The prepared openings made a major contribution to cpac’s #4 finish. Opponent modeling, I can’t possibly forget, is critical for long tournaments.

Against other opponents, cpac played randomly chosen openings in the Steamhammer style. Cpac trimmed out weaker openings, but otherwise made not too many changes to the random weights and the build orders—except that against terran it chose a 1 hatch lurker opening 90% of the time, instead of occasionally.

Cpac also includes special case strategy code that specifically recognizes UAlbertaBot’s marine rush and zealot rush.

bool StateManager::beingZealotRushed()
{
	auto enemyName = BWAPI::Broodwar->enemy()->getName();
	if (enemyName == "UAlbertaBot")
	{
...

conclusion

Cpac is the highest-placing bot with a fancy machine learning feature. ZZZKBot and PurpleWave have, as far as I know, only simple learning. And... I think it’s a reminder of how hard it is to get machine learning to work well in Starcraft. I’m not convinced that the network adds much to cpac’s skill.

If you ask me, network trained on human games is not appropriate for a bot. When you train a system to copy human play without understanding it, it doesn’t matter what the game is—the system will learn a shallow imitation of human play, not the real thing. It will make a lot of mistakes. AlphaGo trained on human games only as a speedup trick; the real smarts came from the followup training by self-play, which forces the system to understand its own moves in relation to its abilities.

If you also train the network to play only part of the game, only choosing from among 8 combat units and skipping over drones and buildings and research, then its understanding of what it is doing must be paper thin.

Most of cpac’s skill, I think, came from fixing important Steamhammer weaknesses and from manual special case coding and configuration for maps and opponents.

By the way, cpac comes with an MIT license, so its code is legally available to copy. To comply with the license is simple.

Next: Overkill.

CherryPi’s games

I watched some CherryPi games to see how it plays.

versus terran

CherryPi scored 92% against the 4 terrans. How did that happen?

Well, only 2 of the terrans are strong by CherryPi’s standard, and it pre-learned openings against both of them. Against #3 Iron, CherryPi played a mass zergling opening. In games where Iron did not wall, game over. What made it work is that, if Iron did build a wall, CherryPi understood when the wall was open or closed. That’s good cleverness. The zerglings formed a concave so they themselves were safe from the defenders behind the wall and nothing of Iron’s could sneak through, then when the barracks lifted to open the wall, rushed in and rampaged. Against #12 LetaBot, CherryPi played the same zergling opening and won by sheer persistence in attacking.

Both Iron and LetaBot could have won with little risk by playing more cautiously.

Against the weaker terrans, #16 IceBot and #25 HannesBredberg, CherryPi’s learning quickly found winning builds. Against IceBot it settled on a slow-moving mutalisk build with too many hatcheries, powering drones while IceBot delayed moving out. It’s the only case I found where CherryPi tries to win eventually instead of quickly. The games are consistent wins but are not impressive. Against HannesBredberg it was the mass lings again.

the learning sequence

Except against the 5 opponents for which it pre-learned openings, CherryPi opened the first game versus each opponent with 4 pool. It succeeded against refreshingly few of them. If that didn’t work, it tried another opening, and another, and so on. Most of the openings are of the low econ “I’ll just run you over in 6 minutes” kind.

CherryPi apparently tries all its openings without worrying whether they are appropriate to the matchup. It tried a lurker opening in this game versus Microwave. It made no sense to me, but maybe some zerg bots are vulnerable to lurkers.

CherryPi’s favorite unit is the zergling. Occasionally mutalisks or lurkers do something essential, but most of the time, early game or late, it wants to win with lings.

the Steamhammer family

#10 Steamhammer upset #6 CherryPi 72-32. The random openings worked as intended and baffled CherryPi’s learning. CherryPi has openings that could have won the majority of games (it won 7 of the first 10), but it could not find them (it won 3 of the last 10). It could not hear the learning signal over the noise.

Steamhammer forks cpac, Microwave, and Arrakhammer also had plus scores versus CherryPi. I doubt they were all for the same reason.

Next: Cpac.