archive by month
Skip to content

zergs versus Krasi0

These two games were played a few days ago, after Krasio was updated. Krasio apparently forgets its learned data on update, and against some opponents takes a few games to remember how to win again.

Steamhammer-Krasio

In Steamhammer-Krasio on Moon Glaive, Steamhammer started aggressively with overpool (overlord on 9 drones then spawning pool), and the early zerglings prompted Krasio to play defensively with a bunker at its ramp. But sneaky sneaky Steamhammer made few lings and instead added a second hatchery and teched to lurkers. Despite some clumsy zerg play, the lurkers delayed terran from expanding until around 11 minutes into the game. In the picture, lurkers are about to deny Krasio’s attempt to take its natural.

lurkers deny expansion

Krasio did at last successfully double-expand, but by then zerg was ahead and was soon able to destroy the terran third.

breaking a terran base

The next terran expansion was too far away to defend, and the rest of the game was zerg all the way.

Microwave-Krasio

Microwave-Krasio on Icarus, Microwave opened with a hatchery on 12 and went for mutalisks. The early mutas made more losses than gains, but notice the strong zerg economy. Microwave did not fall behind in supply for the whole game—a sign that Krasio was doing something wrong strategically, since the terran unit control was clearly superior.

probe defeat

In the middle game Microwave switched to ground units, overrunning Krasio’s third base in the lower left. For the late game it suddenly switched back into mutalisks and amassed a sky-darkening cloud. Mutas erased Krasio’s second attempt at a third base, in the bottom right, and then it was too late for terran.

probe defeat

comparison

Despite the different unit mixes and play styles, the games are strategically similar. In both, Krasio did not play its best opening and fell behind early. The zergs were able to roll up outlying bases with relative ease because terran did not have the mobility to defend them, and then were so far ahead that they could win by brute force.

Krasio wins when it starts well, of course, and it usually starts well once it has a little experience. The top zergs have gained enough skill to be a threat, though. Both have adequate macro and know how to choose a poorly defended expansion to attack, skills that many bots lack. In the last 7 days, BASIL gives Steamhammer 4-4 versus Krasio, and Microwave 2-5.

When you can’t defend your own expansions, you need to keep your opponent off-balance instead. It’s an advanced skill, and even Krasio does not have it. Against the lurkers, terran could have tried vultures, or drops, or perhaps wraiths—harassment that lurkers will be poor at responding to. Against the mutalisks, terran had enough valkyries to be safe, but seemed to deploy only 1 or 2 at a time in any given fight. Also, since terran was behind, the goliaths were not the best unit choice because they slowed down army movements. Without them, a larger marine and medic army would have been able to maneuver rapidly in defense, or cross the map to threaten zerg bases. I think bots are starting to play well enough that this kind of strategy knowledge will help.

let me help you with that

This Steamhammer version is showing clear superiority over the previous one. I expected a small improvement that was hard to be sure of, but got an improvement that’s easy to see. Nevertheless, there is one new misbehavior: It takes bases in a poor order on some maps. On Heartbreak Ridge it takes the center base far too early, among other expansion order mistakes. Using the resource tracking info threw the base scoring out of whack, and my attempts to whack it back into whack were not enough. I have to hit it harder.

A funny picture:

probe defeat

Krasio is taking its third base as it should, and mining out the blocking minerals at a good timing so that it can transfer SCVs along the back path. Steamhammer has 2 drones in view. The drone on the right also wants to take the base, and is just noticing the command center in its way; it will give up and return home. The drone on the left knows, “We’re about to take this base, so I’d better clear this path that’s near it.” The SCV and drone are cooperating to mine out the stacked minerals, entirely to Krasio’s benefit.

Steamhammer stands at an advantage in this position, but ended up losing, most importantly because it took bases in the wrong order. Terran pushed out, and by the time zerg gained the strength to break the attack—which it did—the center base had already fallen. Many bots expand unsafely to that center base.

a Steamhammer versus PurpleTickles game

PurpleTickles of Dan Gant’s purple family is a bot that plays exclusively worker rush builds. It’s not highly ranked; it is #50 on BASIL, well below average. Steamhammer’s score against it is 29-1 on BASIL, and the rest of the BASIL top 10 have similar scores. But I thought this one Steamhammer-PurpleTickles game was fun and instructive.

Steamhammer’s counter to worker rush is spawning pool at 9 drones (sometimes less if drones are lost) followed by creep colony. The intention is that when the spawning pool finishes, the combination of zerglings and a morphing sunken colony will be insuperable. If the sunken completes, zerg is safe against almost any number of workers, so the opponent must prevent that at all costs.

Tickles selected a late worker rush this game, starting its attack when it had 8 probes. It left 1 probe mining and attacked with 7. The late rushes are more effective against Steamhammer, and I assume that Tickles has figured that out (it has won 1 game, after all). At the time of the picture, 1 further probe has been manufactured and is now crossing the map to join the attack.

probe rush!

Tickles does not have perfect worker micro, but it does know how to coordinate its probes so they attack together. Steamhammer has inferior worker micro, because each drone defends itself individually and the drones don’t work together. Its forces can be defeated “in detail,” as the military jargon goes. Also Steamhammer has sent a drone to scout, a questionable decision, so its mining workers barely outnumber the attackers. In general, when Tickles attacks the mineral line from one end, it is very successful in killing drones. When it approaches from a different direction, the probes do not coordinate as nicely and Steamhammer has less trouble. Tickles is not smart enough to figure out the right angle of attack, so the outcome of the battle can depend on the orientation of the mineral line relative to the base entrance.

probe victory?

The probes destroyed all mining drones with 5 surviving attackers (and 1 probe still mining at home). Steamhammer gave priority to zerglings, so 2 pairs of zerglings are about to hatch, but there is no money to morph the sunken. Vanquishing 4 zerglings with 5 probes is a tall order, but protoss is still mining and it’s definitely worth a try.

probe defeat

Well, the probes didn’t stand a chance, though it’s hard to tell with the overlord blocking the view. They held their ground and fought instead of trying to maneuver, a fatal mistake. Steamhammer’s scouting drone canceled its mission and returned immediately to mine, so zerg did not find the protoss base yet. The 4 victorious zerglings aimed for the wrong base at first, and also returned home to clear followup probes, but they were able to win by themselves after these little delays.

I see lessons in the game. 1. Coordinated micro is a key skill. PurpleTickles has it. 2. Steamhammer covered for its lack of that skill with a belt-and-suspenders strategy. It works. In games where the sunken starts to morph, PurpleTickles must stop it with the probes, but then mining continues and zerglings win anyway. One skill can often substitute for another. 3. When you have an advantage, try to fight head on, as Tickles did probe versus drone. A probe is a stronger fighting unit than a drone. When you have a disadvantage, go guerilla. Probes are not bad at fighting zerglings, but they have to avoid head-to-head combat, unlike Tickles. A probe can attack at will as long as it is taking only shield damage, then run away; protoss shields regenerate faster than zerglings heal. Use drills (the minerals are right there), or maneuver to separate one zergling and gang up on it. If the purple probe-versus-zergling micro were as superior as the probe-versus-drone micro, the probes might well have won.

I’m pretty sure it’s possible to defeat Steamhammer most of the time with a worker rush, though no bot has shown it yet. As in this game, gather your attacking workers at one end of Steamhammer’s mineral line and coordinate them to defeat the uncoordinated mining drones, sweeping down to the other end of the mineral line. I believe it can be done more efficiently than in this game, and if it’s quick enough then after wiping the drones there should be no minerals for zerglings, or to morph the sunken—Steamhammer tries to replace drones and doesn’t save up for future needs.

If some bot proves my theory, then I’ll have to update Steamhammer’s worker defense.

next for Steamhammer: a scout boss

The major feature for Steamhammer 3.1 will be a new scout boss which will take care of scouting, detection, and providing vision. It’s next because it meets 2 needs: First, scouting must be improved for strategy adaption. You can only predict the opponent’s moves from what you have seen, and the current scouting does not see enough. As one example, the initial scouting overlord hovers in a fixed position over the enemy base, and some protoss bots are smart enough to hide buildings from it. Second, a major weakness in current Steamhammer is that it loses overlords at a high rate. Today, overlords for different purposes are controlled by different code, and only some of the code knows about avoiding dangers. An overlord being sent to watch over a distant base goes there in a straight line, and then so does its replacement and so on, and sometimes an overlord is unassigned from a task and simply stops in a random location. With unified control, overlords will both see more and expose themselves to fewer risks.

The scout boss will also simplify the codebase. It will centralize the functions of the current scout manager and the overlord squad, and of scattered code that controls squad detectors. I expect the 3.1 version to have less total code even though it will be more capable. It will definitely have simpler interfaces with the rest of the program, I have already implemented most of that aspect.

The current scout manager that handles early game scouting knows how to control one worker and one overlord, and that’s all. The scout boss will take command of all flying detectors (including overlords) and floating buildings (I want to add this feature soon), plus whatever units you assign to it. In the opening it will automatically send the second overlord to scout a different base. If you do BBS in the center of the map, you’ll be able to scout with both SCVs to find the enemy faster, as Liquipedia recommends. Many bots already have these skills, Steamhammer has lagged behind.

3.1 should not take as long as 3.0. Unless I fall to temptation and add more features.

sudden Steamhammer 3.0.2

Another day, another fatal bug. I just replaced Steamhammer 3.0.1 with 3.0.2 to fix an infinite recursion that caused a stack overflow. It could happen if Steamhammer was facing a random opponent, depending on the order in which enemy unit types were encountered. Gotta love conditions like that. That’s 2 bugs down, who’s keeping score?

Source is updated too. Only a few lines changed.

Steamhammer 3.0.1 source

Source code for Steamhammer 3.0.1 is now up on Steamhammer’s web page. It will take a little longer to update the documentation, since I made a passel of changes to the configuration stuff.

Part of putting up a new version is calculating the win rate for the previous version. Based on that, the SSCAIT 2019 tournament version 2.4.1 (which plays the same as version 2.4.2) was the strongest relative to the field since version 2.3 from summer 2019. Both are unequalled in Steamhammer history since version 1.2 from early days. In absolute terms, the latest version is of course the strongest.

ack, Steamhammer 3.0.1

First deadly bug eradicated! Only n more to go!

Steamhammer 3.0 has a crashing bug. It’s a null pointer dereference that can happen on startup when the gas steal skill analyzes past game records. Fixed, now I’m on Steamhammer 3.0.1. Next please!

Steamhammer 3.0 change list

I’ve uploaded Steamhammer 3.0 to SSCAIT. Expect source tomorrow. Here’s the change list. Some items I already wrote up, so I only link to the posts here.

There’s a ton of new stuff. This is an infrastructure version, aiming to set the stage for future progress. The new features mean there is a high risk of arthropod vermin. If the new bugs are not too deadly, I expect this version to be only slightly stronger than the current Steamhammer 2.4.2 (which plays identically to the SSCAIT tournament version). Watchers may not be able to tell the difference, except when there is more than one queen on the screen, when it will be obvious. I expect only occasional proxy openings.

skill kit

The skill kit makes it possible to extend the opponent model with any kind of game data, so that in principle Steamhammer can adapt any aspect of its play to the opponent based on experience. To implement a new skill under the skill kit, write a subclass of the abstract class Skill. You need to set a name for the subclass (_name) and implement methods enabled() (should the skill be loaded for this game?), update() (which may carry out the actual skill, or may only collect information), and putData() and getData() (write or parse your data for the game record). You also have to implement feasible() (check quickly, is it possible to execute the skill?), good() (is it a good idea to execute the skill?), and execute() (carry out the skill when feasible and good), but if you prefer you can let update() do all the work, just have feasible() return false, and supply trivial implementations for the others.

• There is a new game record format that records modestly different information about each game, and includes skill kit data. Steamhammer can read records in the old format or the new format, so existing data can be kept.

• The updated gas steal skill uses the skill kit and knows a lot more about Starcraft than the original gas steal skill.

• There is a new enemy unit timing skill. All it does it record data.

• Base ID numbers from the map analysis are now constant across games, so that the numbers can be stored in the opponent model and used to remember the initial base positions.

proxy skills

Steamhammer now has basic proxy skills so that you can write a wide variety of proxy openings. There are new macro locations such as @ enemy natural and new things that you can do with macro locations, like send workers there ahead of time.

It is also possible to use the skill kit to write more sophisticated proxy openings which make dynamic decisions.

production

Fixed: A bug caused distant buildings to start later than necessary because of an error in figuring out when to send the worker.

• Improvements to the handling of production jams: Don’t declare a jam when we are out of resources. Don’t declare a jam when we are maxed on supply. Also, clearing a jam correctly resets the timer so we don’t loop on declaring production jams. The changes correct occasional minor problems, nothing serious.

• If a worker sent to build gets locked down or maelstromed, we immediately assign a new worker. For some reason, Steamhammer used to assign new workers only for stasis.

• If we’re protoss, and we’re constructing a building with a worker from the same base as the building, it’s OK to assign a worker that is carrying minerals or gas. It will barely delay our income. Terran and zerg continue to insist on builders with empty hands.

• Some production code is slightly simplified.

other infrastructure

Mine out blocking minerals on maps that have blocking mineral patches. In the SSCAIT map set, that is Destination and Heartbreak Ridge. WorkerManager sends a worker to mine out the minerals once there are 2 bases and at least 18 workers total. The implementation is not complete and works only for mineral patches with 0 minerals; it doesn’t work on maps where blocking minerals actually contain minerals (mostly quite old maps).

Resource tracking: Keep track of the remaining minerals and gas on the map, as information allows. Since writing those two posts, I extended the code to also keep track of whether a mineral patch is mined out; formerly, the code could not tell the difference between a 0 amount mineral patch and a mineral patch that no longer existed (it’s used in mining out blocking minerals).

• Decide on the value of taking a base, possibly a base that is partially mined out, based in part on the remaining count of mineral patches and the remaining total resources. To get this tuned right I had to retune other aspects of expansion decisions too, or else it would take center bases too soon.

The internal The system to simplify information access is extensively reworked and lets you reach much more information.

Maintain global unit counts every frame. I removed the old UnitUtil::GetAllUnitCount() and UnitUtil::GetCompletedUnitCount() calls. The information is used so often that it’s better to compute the numbers once and for all each frame.

Infer the existence of enemy buildings that we haven’t seen if the buildings are prerequisites of things we have seen. When we see a dark templar, we know there is a templar archives, among other buildings.

Accurately predict enemy building completion times in the UnitInfo system that tracks enemy units. Steamhammer now knows when enemy static defense that it saw under construction will complete, and uses the information in combat simulation (it formerly used a gross approximation that sometimes caused misbehavior). The info is not yet used in recognizing the enemy plan, but it will be valuable when it is. The info also affects squad targeting sometimes.

• A proxy enemy supply depot, engineering bay, or pylon by itself is not an emergency and doesn’t cause the enemy plan to be recognized as Proxy. Don’t overreact.

InformationManager::enemyGasTiming() remembers the time that the enemy first visibly used gas. For example, if we see a vulture, then we know there’s a factory, so we know that the enemy has spent some vespene. It’s one piece of data that goes into deciding whether to steal gas: It’s recorded in the new format game records, and the gas steal skill looks at the numbers from games with no gas steal to get an idea of the enemy’s usual behavior and decide whether stealing gas now will interfere with it.

• A minor improvement to UnitUtil::EnemyDetectorInRange(), which tries to judge whether a cloaked unit of ours is detected by the enemy: Now it knows that a blinded detector can no longer detect.

• I fixed a bug in InformationManager that could cause it to believe that a destroyed pylon existed for 1 extra frame, a bug with no detectable consequences. There should be a Rammstein song about that.

• I removed the WorkerData::depots data structure and its updating code, which was not only unused, but unusable because it was incorrect. I also removed the MacroAct::_race value, which is redundant and was used only for error checks that have never failed in Steamhammer’s life and would be easy to debug if they did.

• I removed various unnecessary includes.

configuration

New macro location @ gas only makes it possible to take a gas-only base (with no minerals) on those rare maps that have them. The zerg strategy boss knows how to do this and will automatically do it sometimes. This is on top of the new macro locations for proxies.

• I removed the macro location @ macro in favor of @ main, which so far means the same thing. Though I’m thinking of splitting them again in the next version, when they may no longer mean the same....

• Added configuration option Config::Debug::DrawResourceAmounts which draws Steamhammer’s idea of the remaining minerals or gas in each mineral patch or geyser—the amount and, if it’s not current, the frame it was last observed. It’s turned on in the uploaded instance, so you’ll see it on the SSCAIT stream. Also Config::Debug::DrawTerrainHeights which draws a number for the terrain height at each tile, with doodad terrain levels in purple.

• Changed the configuration option Config::Debug::DrawWorkerInfo to draw the worker’s job code on each worker and target lines to show where the worker is going. Formerly it drew the worker jobs in a column, which was hard to relate to the game situation. Updated Config::Debug::DrawStrategyBossInfo to add the target queen count to its display of information.

• Renamed configuration option Config::Skills::AutoGasSteal to Config::Skills::GasSteal; it sets whether the gas steal skill is enabled. Renamed Config::Debug::DrawUnitTargetInfo to Config::Debug::DrawUnitTargets because it is shorter.

• Removed configuration options Config::Debug::DrawResourceInfo which was confusing, Config::Skills::RandomGasStealRate which appears to have never been used by any fork, Config::Debug::DrawMouseCursorPosition which I don’t find value in, and Config::Debug::DrawBOSSStateInfo which is not very informative even when using BOSS.

squads

Fixed reaver stuttering, which was caused by a bug. Reavers are slow enough without spending half their movement time stopped.

InformationManager::getNearbyForce() uses the predicted completion time for enemy buildings. This is how the info gets into combat sim.

• The recon squad: Don’t form it before 6 minutes into the game. Formerly the squad was constituted whenever there were “enough” units, which could cause a zergling rush to be weakened by diverting some lings to reconnaissance.

The watch squad: Even if a watch squad zergling is the last zergling on the map, it will remain on station. Formerly, in an emergency it would rejoin the main army, where it did no good and no longer guarded its base from being taken by the enemy. More importantly, stay above ground when detected and endangered. IceBot dealt successfully with the burrowed zerglings: When the SCV could not start construction, it scanned and attacked. The zergling was forced to the surface but instantly reburrowed again and soon died. Oops.

• Squad targeting in the cleanup phase of the game: Don’t send a squad after enemy units that the squad can’t attack. This prevents some cases of zerglings following a floating ebay and the like. There are advantages to following, but I hope this way Steamhammer will be less often distracted from finishing the game.

• Be willing to pull workers a longer distance versus an enemy proxy than versus zerglings. Keeping the workers near their minerals saved many games against zergling attacks, but prevented the workers from engaging proxy buildings. That’s fixed.

• I made changes to try to retreat behind static defense instead of retreating to around static defense, but it didn’t work. Also unsuccessful were changes to cluster regrouping to get late-arriving units to join the fight as they should. The changes are still in the code, though; they’re no worse.

queens

• The maximum count of queens is configured to 6. The previous Steamhammer was already able to handle that, but I didn’t have time to test it before the tournament so I kept it configured to 1 queen max. When 2 or more queens are near each other, they fly in wacky looping patterns to keep away from each other so that they don’t all engage the same target at the same time. That’s a pre-existing behavior, but with 1 queen you don’t get to see it.

• Queens are better at avoiding danger. I widened the safety margin by 1 tile, which made a bigger difference than I expected. Also, queens now recognize science vessels and dark archons as dangers and try to stay away from them.

• I fixed a bug (introduced in tournament version 2.4.1 in December) that made queens less likely to succeed in infesting a command center. Moving around was taking priority over infesting.

• The strategy boss knows how to make higher numbers of queens. It decides how many, and what research to do in the queen’s nest, by looking at enemy unit counts. It used to get the queen energy upgrade too early; now it only gets the energy upgrade if there are many queens to benefit from it, or if the economy is so booming that the expense is negligible.

• The top priority broodling target is a nuking ghost. That brings queens in line with other attacking units.

• Be willing to broodling a less important enemy unit if the enemy doesn’t seem to have any of the most important ones. For example, if you make a lot of tanks Steamhammer may make queens to broodling them. Later in the game, if there are no tanks to be found the queens will be happy to broodling goliaths instead; formerly it would insist on tanks no matter what. Broodling becomes more valuable.

• If there is high total queen energy (because there are a lot of queens), be more willing to use ensnare and parasite instead of broodling when more than one spell is available. Formerly the broodling > ensnare > parasite hierarchy was more rigid. The more flexible queen behavior is better.

• Steamhammer is able to make infested terrans. I fixed the production system bug that prevented it. It uses them very weakly, so I set it to make only 1 at a time and leave time between them.

zerg

Emergency reaction: If too many drones are lost, or a hatchery is lost, break out of the opening. Steamhammer as zerg is too inclined to stick to its opening when it is busted.

Fixed a bug in spellcaster micro that could cause a queen or defiler to go idle. That was painful when it happened; a potentially valuable unit would stop on the map and do nothing for the rest of its life.

Lurker micro improvement: A lurker will not unburrow if an unseen or undetected enemy is thought to be in range to attack it. Formerly, a lurker with no target would unburrow immediately to seek a target, then die to the bunker it could not see at the top of the ramp, or to an untargetable dark templar that was standing next to it. The ramp misbehavior especially caused a lot of unnecessary lurker losses (we saw an example of the same misbehavior from PurpleSwarm in a recent broadcast), but the DT misbehavior is also a key blunder in some games. There is a bug that will still cause a bad unburrow below a ramp sometimes, but at least it’s less common.

• In ZvZ, be less eager to make a defensive evolution chamber right away. Steamhammer has made a lot of unnecessary evos.

• In ZvT and ZvZ, when adding spore colonies, place the first spore in the location closest to the enemy, considering Steamhammer’s main base, natural, and any proxy it may have. (In ZvP, the first spore goes into the natural as DT defense.) There were cases where Steamhammer would place the spore in its main when the natural was closer to the enemy base, and it became impossible to protect the natural from wraiths. At least force them to fly around to a more distant target!

• Drones may burrow for safety when an irradiated unit comes near. This protects them against the eraser trick and other irradiate hazards. I expect that by the time irradiate is researched, burrow will usually be available.

• If the opening book says it wants a hatchery (and no drones have been lost), trust it and make the hatchery. This is to accomodate rare openings which deliberately make hatcheries early. Formerly a safety rule might fire and say “No, you don’t need that hatchery yet.”

• The unit mix versus battlecruisers is adjusted slightly. I hope it will perform better against MadMix’s battlecruisers.

• Don’t make more devourers than needed to counter enemy air. There was already an overall max devourer limit, and a limit depending on how many mutalisks there are. I hope that now, with all factors accounted for, Steamhammer will finally stop overdoing it.

• If Steamhammer is maxed and rich, get overlord sight range.

• Plaguing a cloaked ghost gets a high value, even compared to plague on other cloaked units. It’s to help defend against nukes. Steamhammer really, really does not want to get nuked.

openings

A lot of new openings mysteriously appeared. Where do they come from?

Cadenzie versus Locutus 5 game showmatch

Thanks to SCHNAIL we’re starting to see bot matches against strong human players. Today I write about the Cadenzie (Z) 5 game match versus Locutus from last Tuesday. It comes with an interview on Making Computer Do Things. Watch the games first if you’re interested.

Cadenzie is not a top pro; to me her play looks a little slow and awkward compared to the best. But she is very strong, and when the match was announced, I expected her to win every game. In the event, she scored 3-2. I thought all the games were one-sided: Either zerg won fairly easily, or else Locutus collected enough dragoons and was able to overpower her hydralisks with superhuman dragoon micro. In the game where Locutus chose to go zealots instead, the zealots looked wimpy; Steamhammer has had the same experience.

I also felt that the first game was the only one that Cadenzie played with 100% seriousness (and she said as much in the interview). She played a well-rehearsed build with mass hydras and drop. Locutus (lacking PurpleWave’s strategy skills) did not understand how to read her build in order to cut corners in the opening, and it fell behind (slightly behind in bot terms, “massively” behind according to Cadenzie—the distance varies by skill level!). When hydras collected outside its natural, Locutus trickled units out through the narrow opening in its wall and let them be picked off, falling further behind. The front gateway fell, and then overlord speed finished. She’d gotten overlord drop first, and she picked up hydras and put them in the protoss main, where they cleaned up with little effort. I judged that she could as easily have skipped drop and powered through the front door.

I thought the most interesting answer in the interview was “I played in a tournament before where there was a team melee relay style with a mix of progamers and beginner level players and they would take turns every 2 minutes, in a way it was most similar to that.” In other words, Locutus was extremely good at some aspects of the game, and extremely weak at others. That is similar to other games where computer programs were good enough to play humans and not good enough to win every time; for example, chess programs in the old days were superhuman at tactics and weak at strategy in a very similar way.

She repeatedly emphasized that bots need to adapt more to what they scout. I think that’s the main takeaway.

Compare Artosis versus top bots on Twitch: Notice how often Artosis says “In this build, when I see such-and-such, I do so-and-so.” Human players have extensive knowledge of how to play in specific situations, and no bot comes close. SAIDA may come closest, with its one all-purpose build and numerous reactions, but its understanding is shallow by comparison. PurpleWave I think has the greatest strategy knowledge of any bot, but it has a weak understanding of tactics. Locutus relies on its strong micro and aggressive tactics, which cover for the weaknesses in other aspects. Bots not only know less, they don’t integrate their knowledge into a theory of how the game works—they don’t understand what they know, so they a weak at drawing inferences and their adaptation ability is shallow. See for example the Artosis game versus Killerbot by Marian Devecka, where Artosis was able to guess that a third zerg base at an early timing was likely, and scouted for it specifically. In other games, he did not spend effort scouting for expansions he did not see as likely.

By the way, the last game is the best, Artosis vs McRave starting at ~2 hours in.

Filling the knowledge gap I believe will require machine learning. Writing rules and reactions by hand will take a day or two less than forever, and search will not solve all problems if it has only handmade evaluations to rely on. For Steamhammer, I’ve figured out a way to put together familiar algorithms that will execute fast, and I expect it will also learn fast (from little data) and be reasonably accurate (not amazing like deep learning, but adequate). It’s part of my strategy adaptation goal. If it works as well as I hope, I WILL CRUSH YOU PUNY MORTALS BENEATH MY STEEL THUMB BWAHAHAHAHA, or something like that. Actually the first application will be nothing more than an evaluation function to choose openings and strategies, valuable but extracting only a little of the potential, and if it’s successful then after I explain how it works everyone else will get ahead of me again. That will be good too.

Steamhammer 3.0’s new gas steal

Steamhammer’s existing gas steal skill works by UCB, like the opening selection of many bots. It has a bias toward not stealing gas, but the basic behavior is that it will steal gas if that wins more games than not stealing, or if it hasn’t tried a gas steal in a while and it’s time to give it another spin. It pays no attention to what the opponent is doing, so it will try silly things like stealing gas while under zergling attack from a 4 pool. The silly decisions hurt.

Steamhammer 3.0 will have a completely recoded gas steal skill using the skill kit, and it will be much fancier. In fact it got too complicated; today I finished rewriting it to simplify the rules. I’ll upload 3.0 as soon as it passes tests.

The skill records three values for each game: The frame a gas steal was decided on (0 if never), the frame when the refinery building was started, and the lifetime of the refinery (when did the opponent clear the gas steal?). Also newly recorded in the game record is the frame when the enemy was first observed to have spent gas on a unit or building.

All this information, plus a few other items like the recognized enemy strategy, goes into the gas steal decision. The outline is that various checks are made first to see whether stealing gas makes sense (“no, this enemy doesn’t take gas for a long time anyway”). If so, attempt a gas steal randomly with a certain probability until we’ve accumulated 5 games of experience with it. Once the data is in hand, adjust the probability up or down depending on the amount of evidence, with fudge factors to try to take certain strategic points into account (“versus 2 barracks? are you sure about this?”).

It’s still crude compared to the analysis I’d like to do. The ideal would be to figure out the effect of stealing gas on the enemy’s strategy and play, infer the best time to attempt it, and send a worker then to threaten it. But it should avoid many of the blunders that the current method makes.

Next: The Cadenzie-Locutus match.

LetaBot in AIST S3

AIST S3 completed. Round up the usual suspects, you can see the results for yourself. There are replays for all the games, but no video so far. The replays are labeled “Round 1” through “Round 14”; you can read the round numbers (I would have called them match numbers) from the bracket diagram. I like seeing all the results at once, but if you prefer to follow the tournament without spoilers, you could download the replays at the top of the page, scroll down no farther than the picture of the initial bracket to match up replays with the tournament structure, and watch the replays by round number.

I was especially interested to see LetaBot by Martin Rooijackers. LetaBot, it seems to me, is strategically strong but suffers from many bugs. Its standard game plan is a classic terran strategy, defend while building up a large army, then bury the opponent in an avalanche of units. LetaBot knows a variety of specific defenses against different cheeses, and has reactions to enemy moves that threaten its game plan, so I think its potential is high. This version is updated to BWAPI 4.4.0, so possibly it has more updates besides. Martin Rooijackers long ago promised a stronger version with bug fixes.

Versus Dragon: I especially wanted to see this match because of the players’ opposite game plans. Dragon plays an early attack and harassment style. In game 1 of the best of 3, at about 2:35 into the game, Dragon sent its first 2 marines and 5 SCVs to breathe some fire. LetaBot luckily scouted in the right direction and timing to spot the force as it left Dragon’s base, and LetaBot had a bunker on its ramp in plenty of time. Fireproof. Dragon sent the SCVs home right away, but inexplicably continued to produce marines that it posted outside LetaBot’s natural. LetaBot appeared to read the situation and react; it made vultures and goliaths—a strong force when the enemy has fallen behind early—batted aside the marines, and continued straight on to Dragon’s base. Dragon had been preparing medics and tanks behind the scene for its next wave of aggression, leaving itself open to LetaBot’s timing, though LetaBot was well ahead even without that opening. Luck plus skill, 1-0.

In the second game, LetaBot crashed on startup. 1-1

In the third game, Dragon tried the same plan again. LetaBot did not get the lucky scout, but cross positions favored defense. Dragon seemed indecisive, sending SCVs forward and back before attacking with 7. LetaBot floated its barracks after 1 marine, Dragon’s SCVs defeated the marine and moved into LetaBot’s base, some blocking while one built a bunker for the following marines. LetaBot pulled SCVs to defend, and with more it easily won the worker fight, but the bunker completed. LetaBot pulled SCVs out as far as the center of the map to keep marines away from the bunker, but eventually retreated and let 2 marines enter. But the timing was OK, another SCV pull past the loaded bunker kept further marines away while a tank came out and kicked over the bunker; not perfect defense but more than good enough. Fire resistant. Dragon’s SCV attack left it far behind LetaBot’s cheaper SCV defense; LetaBot seemed to understand and quickly won with a tank-goliath attack. LetaBot advances 2-1 on its strong defensive and counter-attacking reactions.

Versus Locutus in the next round: LetaBot crashed 2 games in a row.

Versus BananaBrain in the loser’s bracket: LetaBot crashed 2 games in a row.

So... there might be bug fixes, but we didn’t get to see because there were bugs. :-(

new openings in Steamhammer 3.0

Part of my regular change list for each new version is a list of openings I’ve added, so here’s another preview. The list is long this time, but easy to write up. Only a few of these openings are configured for regular play, but all will show up now and again.

Steamhammer’s new proxy skills enable a huge range of cheese builds. I wrote 2 or 3 for each race, sort of as samples.

terran

• In base proxy openings ProxyBBS and ProxyFactory. Ecgberht occasionally pulls out a similar proxy factory, which has scored wins over Steamhammer. These builds annihilate unready opponents but show execution weaknesses if the enemy is able to defend at all. BunkerNatural makes barracks in the center and bunker at the enemy natural, and scouts at a timing so that it just barely works reliably on a 4-player map.

10-10-10Vultures gets vultures earlier than the standard factory timing. I wrote this to test zerg reactions to fast vultures. Might as well keep it.

protoss

Proxy2Gate in a corner of the enemy base, which I haven’t seen another bot try, and CannonRushNatural with dragoon followup, also new to bot play.

zerg

Burrow versions of existing openings, zergling openings with different timings. It is part of my followup on the burrow skill. As burrow gains more uses in the future, these openings should show up more often. 6PoolBurrow 6PoolSpeedBurrow 8Hatch7PoolBurrow 8Hatch7PoolBurrowB 9PoolBurrowB 9PoolSunkBurrow OverpoolBurrow Overpool_3HatchBurrow 9Hatch8PoolBurrow 10HatchBurrow Over10HatchBurrow 3HatchLingBurrow 5HatchPoolLingBurrow.

Proxy openings: Proxy8HatchNatural makes a quick hatchery in the enemy natural and sunkens it up. AntiTyr and AntiTyrLurker are the same idea, but timed much later to counter the Tyr protoss build where it makes cannons in its base and builds up for a timing attack. AntiTyr serenely swallows the attack and wins. Steamhammer still needs a couple more skills before it can do Fried Liverpool.

AntiFactory2 is a slightly faster version of Steamhammer’s longstanding anti-factory opening, with hydralisks first. The original opening was timed to stop a 3-vulture runby, but lately a couple of terrans have been winning with a 2-vulture runby which is earlier and sneaks in before the defenses are ready. AntiFactory2 closes the gap. I configured it as a top answer to factory openings, so it should be fairly frequent.

11Pool is slightly faster than 12 pool for ZvZ, filling a small gap.

10HatchLing and 10HatchLing2 are specialized versions of 10 hatchery 9 pool which go all-in on zerglings.

• Experimental openings: Phlegethon I timed and showed to be inferior. The alternative 2x10Hatch (10 hatchery, 10 hatchery, 9 spawning pool with repeated use of the extractor trick) I have not timed, so in my ignorance I allowed myself to write variants 2x10HatchSlow 2x10HatchAllIn and 2x10HatchBurrow. The less I know, the more fun stuff I get, there’s a lesson!

Over10Hatch11Pool starts with the same extractor trick-overlord-hatchery sequence as a number of common Steamhammer builds, but inserts a couple extra drones before the spawning pool to build up the economy.

• Going the opposite direction, 3 hatcheries before pool but cutting drones to get the hatcheries faster than standard, are 12-11Hatch, 12-12Hatch, and 12-13Hatch. I was pleased with these and added 12-11HatchLing as a zergling all-in version.

2HatchLurkerPure is a variant 2 hatch lurker build which includes minimal zerglings, making drones instead, so that there’s a little more economy. I figure that if opponents lose because they are unprepared with detection, then the zerglings may not help much.

QueenRush and GuardianRush are not really useful except for testing (the only reason I wrote the queen rush in the first place). But then, I used to think the same about the hive rush build, until it scored wins over BananaBrain. At least they’ll be entertaining if they ever show up. The queen rush makes a half dozen queens with broodling nice and early in the game.

Steamhammer 3.0 game record format

Steamhammer 3.0 is nearly ready, but I’m immoderately busy and don’t know how long it will take for the last adjustments. I can at least slip in short posts to show off some of what’s coming.

Steamhammer 3.0 changes the format of game records in the learning files of the opponent model. The original version 1.4 game record format has been in use since early 2018. The learning file for an opponent is simply a list of game records. Here is the new 3.0 game record format.

meaningitem
game record version3.0
matchupZvP
map(3)Longinus_200.scx
base ID of Steamhammer's start5
base ID of enemy start, 0 if unknown at end of game12
openingOver10Hatch2SunkHard
predicted enemy planHeavy rush
recognized enemy planUnknown
0 for loss, 1 for win0
frame of our first combat unit4382
frame we first gathered gas6814
frame the enemy scouted our base3134
frame the enemy got a combat unit3838
frame the enemy first used gas5162
frame the enemy got an air unit5182
frame the enemy got static anti-air (0 means never)0
frame the enemy got mobile anti-air5182
frame the enemy got a cloaked unit5182
frame the enemy got static detection0
frame the enemy got mobile detection18686
frame the game ended28553
skill kit data (2 skills)gas steal: 0 0 0
unit timings: 60 6161 61 9565 64 2435 65 3815 66 13383 84 18696 154 3240 156 3240 157 3217 160 3263 163 5172 164 3194 165 6575 167 5195
end of the recordEND GAME

As before, the frame number of an event is the frame when Steamhammer first noticed it, not when it happened. They are sometimes very different.

The game record version number can be “1.4” for old records or “3.0” for new records. Steamhammer can read them both and use the data; changing the format doesn’t mean I need to clear out existing learning files. Of course fresh records are written in 3.0 format.

Including the base IDs of the starting positions of the 2 sides means that Steamhammer can pay attention to starting positions. You have to know the map to interpret what the ID numbers mean. The information about enemy gas usage is new and helps with gas steal decisions. The gas steal items from version 1.4 records are moved into the gas steal skill.

There was no gas steal in the example game, so the gas steal recorded 0 0 0 for its data. The skill kit can record data for any number of skills; it is extensible. Each skill’s data is [name of skill]: [data for skill] on one line (the line can be arbitrarily long). The skill needs to know how to write one line of its own data and how to read it back, and that’s all; the central skill kit code takes care of everything else, including rewriting old records without change.

preview of Steamhammer’s proxy skills

Here is a first look at Steamhammer’s upcoming basic proxy skills. These are features that you can use to write a wide variety of proxy openings. I still have work to do before I can release Steamhammer 3.0, and I’m working slowly so it will be a while. I’m making infrastructure changes that tend to introduce bugs. But I’m looking forward.

New macro locations @ enemy main, @ enemy natural, and @ proxy. Buildings for the enemy main or natural are placed in plain sight—MadMix has played that style of proxy with success against bots, and bunkering the enemy natural is standard in some situations. Buildings placed @ proxy go into a distant corner where they have a chance of remaining unseen. I also fixed a bug so that the existing macro location @ center works reliably.

To build in enemy territory, you need to know where your enemy is. Proxy locations interact with early game scouting. On a 2 player map you can always build at a proxy location. On a larger map, you’ll need to scout early enough to find the enemy first. I recommend go scout location with an early worker; on a 2 player map, the location is known so the scout is not sent. If the enemy is not found by the time building construction is to start, Steamhammer will fall back to building in the center of the map instead.

Post workers to a macro location. You can command a worker to take up a post at a given macro location with, for example, go post worker @ proxy. The posted worker can build at that location (barracks @ proxy) and will remain there for further orders (bunker @ proxy). Release posted workers from a given location with go unpost workers @ proxy or from all locations with go unpost workers. A posted worker is different from a worker that was pulled and assigned to a combat squad; a posted worker expects to build stuff and will not try to fight.

The feature bypasses weaknesses in Steamhammer’s assignment of construction workers. A worker sent a long distance tends to arrive late; by posting the worker in advance you can avoid the loss of time. Also, Steamhammer likes to send one worker per building, so if you ask for 3 forward cannons next to your forward pylon, it will send 3 probes (after all, you need 1 worker per building for Steamhammer’s main race zerg). If you post a probe there instead, special case code makes sure that the one posted probe makes the 3 cannons one after another.

Macro locations work for all actions that they make sense for. It’s essential so that you can control where production occurs: If you have a proxy gate and a gateway in your main, you can get your next zealot from the one you choose with zealot @ main or zealot @ proxy. Or similarly, if you have a forge in an exposed blocking position (which you’ll have to write code to place; Steamhammer doesn’t support that out of the box) and a forge in your main, you can specify ground weapons @ main to get your most important upgrade in a safer place. If you don’t specify, either building might be chosen.

The feature is a little fragile. The priority is to start the requested action as soon as possible, not to start it in the location requested. If you ask for a zealot at your proxy gate and that gate is already busy, the zealot will start in your main instead if that gate is free. That can be inconvenient in a hand-written build order, though it should be little trouble for a build order generated programmatically on the fly.

Proxy locations can block bases. A minor tweak to building placement: Normally Steamhammer places its buildings so that they don’t block any future base you may want to take. If you’re building in enemy territory, you don’t care about that. bunker @ enemy natural will commonly be placed to block the base location.

No maps are special cases in the code; all placement decisions are made by analyzing the map on the fly. I think the decisions are good for a first cut, but there is plenty of room to improve them. I did find one map where a mystery bug causes a worker posted in the center to fail to build there (so that Steamhammer sends a fresh worker from its base), but that’s the only bug I know of. It’s complicated, though, and there are probably a lot of misbehaviors I have yet to see.

The features are enough to support a good range of proxy openings. I wrote two or three for each race, for testing and for the fun of having them. In Steamhammer 3.0 none of them are configured to be played frequently, but they should pop up now and again.

The skill kit will be the other major feature in this release. It may sound independent of proxy skills, but in my mind there is a close connection: I want to write skills to make dynamic decisions about whether and how to proxy. It’s possible, and it doesn’t seem too difficult, to do things like cannon the enemy base differently each game based on analysis of the map and the base layout. Many bots place buildings the same way every game, and that can be exploited too.

Stand by for Steamhammer’s next step up in versatility.

how to defile

We have the next round of SSCAIT results. I was hoping for Killerbot by Marian Devecka over ZNZZBot, because Steamhammer is a favorite over Killerbot. But ZNZZBot squeaked a win by crash. Steamhammer will face ZNZZ in loser’s round 3 and almost certainly be eliminated. Oh well.

one little plague

A highlight from Steamhammer-Icebot on Fighting Spirit. In old days, Steamhammer would have finished a winning game like this by brute force, with mass ultralisks or mass guardians. The actual ending did feature brute force, but more elegantly applied.

a plague on all your tanks!

Dark swarm ensured that zerglings would break the front. Rubble of bunkers and turrets lies everywhere. Tanks rain splash damage from above, but as zerg reduced the natural, the defiler (selected) threw a plague over every tank. When the mutalisks visited them, the tanks popped like so many bubbles.

Very satisfying. All that work on defilers was worth it.

Steamhammer 3.0 status

Steamhammer 3.0 will be coming out “real soon now,” as we used to say, meaning “later than I ever thought,” thanks to my ambition to throw too many features into it. I originally wanted Steamhammer to participate in AIST S3, but I think I will probably skip it. I don’t expect Steamhammer to be upgraded to BWAPI 4.4.0 and working reliably by then. The last day to register is 15 February, so I have time to change my mind. But I want to concentrate on new features rather than on tightening the bolts for tournament play.

Here’s the main new stuff. I chose to delay work on pathfinding, overlord control, and scouting for now, though they are high priority features for good play, and are on my must-complete list for AIIDE 2020. (No plan survives contact with the next minute.) I suppose they’ll go into versions 3.1 and following. I was more interested in the skill kit and other infrastructure additions; they hardly help Steamhammer in the short run, but lay a foundation for faster improvement in the future. That’s what seems important now, foundation laying.

The skill kit to make the opponent model extensible.
• Basic proxy skills, including new macro locations like @ enemy natural.
Resource tracking to remember minerals and gas on the map.
• Followup on burrow, with many new burrow openings and tweaks to the Watch squad skill.
• Followup on queens, with slightly improved behavior and support for larger queen numbers.

The skill kit feels like my best new idea in a long time, so I was excited to do it right away. The initial skills will be gas steal (replacing the current opponent model code with something a little smarter) and a unit timing skill which doesn’t control anything in itself but only records information for the rest of the program to refer to. They both fit into the framework. I expect the skill kit to speed up strategy work and to help make Steamhammer more and more adaptive over time.

Proxy openings are amazingly complex to execute well. A bot needs building placement skills, the right worker control, and special unit production and tactical skills. Steamhammer 3.0 will have only some of the skills it needs, but it should at least be able to pull off a simple plan like building a barracks in the center and then bunkering the enemy natural. Even that takes infrastructure work that I haven’t finished yet (partly because I changed plans in the middle). The work will bring extra flexibility that will be useful in other situations too. For complex proxies that can’t be written in data as opening build orders but require code—write a skill for the skill kit, that is one of its purposes.

There are also, of course, the usual new openings and small fixes and tweaks.