Release 3.2.19
Safe movement
-
Micro::MoveSafely() is a drop-in alternative to Micro::Move() for use by units which prefer to never come under enemy fire. It follows the simple method of running away from the nearest dangerous enemy, gaining 80% of the benefit of optimized hazard avoidance with 20% of the effort. If you know what to look for it’s easy to see cases where it makes a worse decision than potential fields would, but you have to look.
-
Overlords use MoveSafely(), except for squad detector overlords which already have their own way to avoid danger. Formerly, one of Steamhammer’s great weaknesses was that it would generously donate overlords to the enemy cause. Sometimes it would try to transfer an overlord to a distant base when an enemy army happened to be on the path, fail, try again.... In the worst cases, overlords would appear to converge from all sides on a group of marines or dragoons as if they were flying ultralisks closing a surround. That is all gone. Overlords are lost at a reasonable rate and live longer, more fruitful lives.
-
Workers also move safely using some of the same code, though the implementation is more involved than MoveSafely() because of the special needs of workers. Micro has a suite of helper functions. There is one exception: When moving to construct a building, just go there. The scout worker does rely on MoveSafely(), and it has become more adept at surviving to see what is going on. Overall, it’s a clear benefit. When zealots raid, the workers scatter and have to be chased down, at worst causing delay to the enemy and at best surviving to return to mining.
-
If burrow is researched, workers burrow to avoid danger instead of running away, unless an enemy detector is seen to be in range. This behavior is a delight to watch. Zealots raid, or a reaver lands—and the enemy sees nothing but puffs of dust as the workers disappear under the ground. After the attack is cleared, the workers pop up and instantly return to work. Steamhammer still loves to transfer workers across the middle of the map where the enemy is roaming, but now the workers realize the risk and burrow for safety. The enemy may like to scan when it sees units burrow (Steamhammer terran does that), or may have an observer which was out of range when the workers burrowed but can be brought over, so it’s not entirely safe, but it’s a breakthrough compared to the former behavior of running willy-nilly into the grinder. Also if the enemy moves away a bit the workers may unburrow, try to continue, come too close again and reburrow—which is funny if nothing else.
Overall, safe movement is a huge gain. There is room to make it far better yet, but that will take incremental refinement over time. There are disadvantages in certain situations. For example, when there is only one base and it is raided, then the workers flee or burrow and there is no mining whatsoever to fuel production and defeat the attack. It might have been better to keep mining and accept the loss of workers. Terran could do something like send 1 wraith to each mineral line and stop all mining, and in fact I have seen Steamhammer lose in similar ways.
Scouting and overlord assignments
-
Every overlord is assigned a location to move to and stay at. These parts are unchanged: One overlord is under the control of the scout manager early in the game. Some overlords are assigned to squads to serve as detectors and provide vision. The remaining overlords belong to the Overlord squad. What is different is that the Overlord squad assigns a location to every overlord it controls. Formerly, the Overlord squad assigned locations to some overlords and left the remainder floating wherever they happened to be, which might be in the middle of the map. It was not efficient scouting, and it was not safe for the overlords (but it was easy and I got it done).
-
The Overlord squad has gained a general assignment system similar to (but simpler than) what I plan for the deferred Scout Boss. It lists useful overlord destinations in priority order, then assigns the closest available overlord to each destination in order. If there are leftover overlords, as there generally are by the middle of the game, the remainder are sent to the front line of the front base (both “front” ideas are detailed in sections below)—basically, they wait together in a clump near where the enemy is likely to try to attack. It’s a reasonable try because the overlords use MoveSafely() to flee dangers.
-
Early in the game, one overlord is assigned to survey the main base for hidden proxies. It uses the new function MapGrid::getLeastExploredNear() to repeatedly find what place inside the starting base has least recently been seen, and goes there. The result is that the overlord flies an irregular, adaptive, hard-to-predict and fairly efficient search pattern (and it takes literally 2 lines of code inside the Overlord squad thanks to the infrastructure). I was inspired to add this by a game versus Ecgberht where the terran built a hidden proxy factory in a far corner of the zerg base, a strategy that has earned it a lot of wins over Steamhammer. Typically Steamhammer has no idea that vultures are appearing in its base because of a proxy and fails to defend effectively, but in this game an overlord accidentally scouted the factory and Steamhammer crushed the proxy brutally. It was a short step to scout on purpose.
-
If the enemy has no mobile anti-air units (somewhat uncommon), then an overlord is assigned to watch the enemy natural. Further overlords are assigned to guard our bases against cloaked units, just as formerly. If the enemy has transport and does not have flying overlord hunters, the main base scouting pattern restarts to watch for drops. If the enemy still does not have mobile anti-air units (rare by the point there are enough overlords for it, but possible versus Stone, versus a persistent zealot rush, versus a zerg going zerglings, or very late in the game after the enemy’s army is wiped out) then overlords are assigned to watch every base on the map. As always, if there are flying overlord hunters then overlords congregate at spore colonies instead. There is a lot of room to make strides in overlord deployment; future Steamhammer versions will do things like find overlord perches where they can watch without being seen.
-
The scout manager also controls its overlord somewhat differently. If an enemy turret, cannon, or spore colony appears in range of the overlord (generally when it is in the enemy base), then the overlord is immediately released from scouting duty. It is reassigned either to a combat squad or to the Overlord squad, and in either case attempts to safely make its way to a new destination. (I wanted to have it cruise around the edge of the enemy base to keep scouting, but it was too much for now.) Releasing the overlord loses scouting information, but losing the first overlord this early in the game is a severe setback and it was happening too often, so I think it’s the correct trade. If the overlord remains safe in the enemy base, however, it no longer sits still over the enemy resource depot but instead scouts the enemy base in a * pattern: It goes to the depot, then calls MapGrid::getLeastExploredNear() to find another place in the enemy base that it needs to look at, then returns to the depot, etc. That way it regularly revisits the most important spot, but also pokes into the corners of the enemy base so that it sees more.
-
Squad overlords, or properly squad detectors since science vessels and observers are handled the same way, are also controlled slightly differently. The flying squad detectors have long had abilities to avoid dangers and seek out cloaked enemies, and they could try to protect themselves from air attackers by seeking friendly units that can shoot air. Now, rounding out their skills, they also try to protect themselves from ground attackers by seeking friendly units that can shoot ground. We’ll see how well it works!
Building construction
-
Critical bug fix: It was possible for the building manager to accept a worker for a construction job while the worker manager believed that the worker was still available for other tasks. Ouchies. The worker was alternately given conflicting commands and achieved nothing. The building it was supposed to construct was hugely delayed or canceled, a game-risking error.
-
When choosing a hatchery to morph into a lair, if possible choose a hatchery that is away from enemy units. For example, if there is a scout circling the main, start the lair in the natural where it won’t be seen right away. I wanted this to be a first step in denying and delaying information to the enemy. I wanted to also place other tech buildings out of enemy view when possible and safe (they’re constructed rather than morphed so it takes different code), but I didn’t have time. I did add UnitUtil::IsTechBuildingType() so that Steamhammer can distinguish tech buildings from other buildings (to also eventually be used in prioritizing buildings to destroy in an enemy base).
-
Bug fix: When a worker was handed over to production manager or building manager to construct a building, for 1 frame it would be given 2 inconsistent commands, one from worker manager before the reassignment and one from the production manager (to move into position) or building manager (to start construction) after reassignment. I solved it by the simple expedient of running the production manager and building manager before the worker manager, being careful to comment the change so it is not later undone by mistake. The result is that the worker is able to follow its movement or construction command one frame earlier, so the building starts sooner by one Planck time.
-
The production manager replaced a worker requisitioned for construction if the worker was locked down, stasised, or maelstrommed before it could be handed off to the building manager. Now that workers often burrow for safety, it also replaces a worker which it finds to be burrowed. The building manager by oversight did not replace a worker which was rendered unable to build (only a worker that was killed). The oversight is fixed; now the building manager also recognizes lockdown and the others. Buildings should construct more reliably in the face of enemy interference.
-
The worker manager’s setBuildWorker() no longer takes an unused building type argument. I should have gotten rid of that long ago.
Plan recognizer
The plan recognizer work focuses on detecting early shenanigans by the opponent so that Steamhammer can react in time this game, or failing that, choose a safer opening next game.
-
Recognize an enemy Contain opening plan distinct from the Proxy plan. The details of what counts as Proxy are changed accordingly. The general idea is that a proxy requires an immediate forceful reaction, while a contain should be dealt with more deliberately. This means that the configuration file can include Counter Contain openings which are different from the Counter Proxy openings (see the new openings below). Zerg also reacts somewhat differently in the two cases (see the zerg section).
-
The code to recognize a proxy is moved from Bases to OpponentPlan where it belongs, and combined with the code to recognize a contain.
-
There was a crashing bug in recognizing a proxy on a map where our starting base had no natural base. Every starting location on every competitive map has a natural, so the bug never occurred. But it’s fixed.
-
Do not recognize a gas steal as a proxy. Oops.
-
A nearby enemy forge implies that cannons are coming; there is no other reason to build a forge in or near the enemy base. (Well, theoretically it could be part of a wall, but what the wall be for? MadMixP and Steamhammer itself as protoss both do proxy forge into cannons sometimes.) Recognize a proxy forge as a Contain plan. This is not always strictly correct; sometimes the predicted cannons would be better recognized as Proxy. But good enough.
-
Enemy Fast rush and Worker rush plans are recognized more accurately by using building completion times (see when will that enemy building complete?) and unit travel times (by shortest-distance ground paths—I did mention that Steamhammer has all the parts for pathfinding except actually following paths) to better constrain the true timing of events. I always meant to do this, and now I’ve gotten around to it. The work includes tuning the time limits (“earlier than this is a rush”) based on timing the slowest builds that I want to count as fast rushes, versus the fastest builds that I don’t want to count.
-
There was a potential crashing bug in recognizing a rush. I don’t think it ever happened, and now the bug is fixed so it won’t.
-
Explicitly recognize terran BBS as Fast rush. It was a loophole. Steamhammer might fly its first overlord directly over 2 center barracks... and fail to react, and lose. That won’t happen any more.
-
Recognize a new Wraith opening plan so that Steamhammer is less often caught off guard by 2-port wraith openings. This gives a chance to react earlier to incoming wraiths and lets you configure Counter Wraith openings. Steamhammer is not reliable at recognizing wraith openings before the wraiths show up, though, because its scouting and plan inference are not good enough. I wanted to improve that, but ran out of time. Steamhammer’s anti-factory hydra-first openings are intended to protect against wraith attack but are not successful in practice because AI-controlled wraiths outmicro the hydras, which don’t have either speed or range yet. A hydralisk needs its range upgrade to equal the weapon range of a wraith.
Bases
-
Always unreserve tiles of a base we failed to take. Formerly, sometimes the base would remain reserved and could never be taken. On the one hand, that was a severe weakness. On the other hand, it created adaptivity in choosing the next base to take; repeatedly failing to take the same base over and over is not a winning plan.
-
Avoid taking a base where enemy units are thought to be. This is a cheap way to add back some of the adaptivity lost by the previous change. Steamhammer does nevertheless sometimes show perseveration in failing to take a base. The next step, for a future version, is to check the path a worker will take to reach the base, and only accept paths that seem safe.
-
The “front line” position of each base is smarter. The front line is where static defense is positioned when Steamhammer wants to defend the approaches to the base. (It may also place static defense directly next to the resource depot if it wants to defend the mineral line specifically. It depends on the goal.) The front line is now on the shortest outside ground path toward the base, which I figure is the path an enemy bot is most likely to send its attackers along. Compared to the previous calculation, the new front is much better on some maps (like Benzene and Roadkill) and slightly worse on others (like the top base of Destination, though not the bottom base). It’s a net gain.
-
A zerg base doesn’t become the “front base” until it completes, because zerg needs creep to build. The front base is where the main approach static defense goes; it is the natural base if the natural is taken. Formerly, Steamhammer might place defenses in the main because there was a hatchery morphing in the natural and the main was where it was able to build—yeesh. For terran and protoss, the natural need only be started.
-
Don’t try to take an enemy base as a hidden base. If the enemy has not been found yet, and we need to choose an expansion as a hidden base, do not choose any main or natural base (unless that’s all there is), because it might be the enemy’s and that would suck. This is critical if the enemy is following a Contain plan, because then we will try to take a hidden base early without scouting.
-
Make a stronger attempt to expand toward the edges, leaving central bases for later. The code proudly flaunts it as a big change, but it is not particularly successful; Steamhammer still likes bases in the open middle on maps like Aztec and Fortress. I probably have to bite the bullet and do the tactical analysis of the ease of approach and the width of the attacking front to figure out how vulnerable a base is.
-
Fixed: The global pointer “what is my natural?” and the local pointers “what is the natural of this main base?” might be inconsistent. I don’t know what the effects of that were, but it couldn’t be anything good. As part of correcting it, I simplified and improved the calculation of natural bases. Also, each Base object (each base on the map) now includes a backpointer to its main base if it is the natural of some main (or null if not). It makes some calculations easier.
-
Fixed: There was a crashing bug that affected maps on which every base which had minerals was a starting base. That’s very rare, but Crystallis is an example. Though I doubt any bot can play a reasonable game on Crystallis....
Squads
-
Don’t assign base defenders against nearby cannons. This is part of the system to defeat cannon rushes: Combat units should go destroy the enemy base instead, which some of them should be able to do if a zerg hidden base was created as planned. The system doesn’t work perfectly, and sometimes Steamhammer wants to attack the proxy anyway because defenders are still assigned to attack the proxy pylons and any other buildings that may be part of the proxy. But most of the time it works well for a cheap hack.
-
The hysteresis in distance for unassigning base defenders is increased. The main visible effect is that an enemy scouting worker has to run farther away before the single zergling assigned to catch it gives up and heads away.
-
The Watch squad no longer assigns overlords to watch bases to catch enemy activity. The Overlord squad is responsible for that now; see above.
-
I tried adjusting the regroup position (aka retreat point) of Steamhammer units that retreat toward static defense. It didn’t really help.
Other infrastructure
-
The movement routines in the Micro module check their arguments and drop movement commands for illegal destinations outside the map bounds. After an arduous campaign, I have finally fixed all the diverse callers so that they do not issue those commands in the first place. In long tests, the error checks were never triggered.
-
InformationManager::getUnitInfo() fetches the UnitInfo for a single unit (recording where and when an enemy was last seen, among other data). I never needed it before; in the past, Steamhammer only wanted to iterate through all unit info records.
-
Due to an error in interpreting the configuration file, AbsoluteMaxWorkers always had its default value of 75, ignoring what the config file said. Fixed.
-
The code for UnitUtil::GetUncompletedUnitCount() is simplified. Now it simply subtracts the already-computed completed unit count from the already-computed total unit count.
Other worker behaviors
-
When a worker is posted to a location, it remembers not only its macro location as it used to, but its actual map location, and stays there. This is part of the system for taking hidden bases: When you go post worker @ hidden the “hidden” location differs depending on where the enemy base is. When we take a hidden base to counter a Contain plan, we may post the worker before the enemy base is found. If we find the enemy base before starting the hidden hatchery, the map location corresponding to the macro location changes, and at first the drone would waste time and take unnecessary risk moving across the map. Now the worker stays put at the original map location and the hidden base is taken safely and on time.
-
When a worker is posted to a location using go post worker @ it first returns any minerals or gas it was carrying. A tiny mining efficiency tweak.
-
Steamhammer can mine out blocking mineral patches with non-zero mineral amounts. Not many maps have those, but it was a two-line change that makes more maps playable. The code to mine out the more common zero-amount blocking mineral patches, as seen on Destination and Heartbreak Ridge, has been in there for a while. (There is still no code to break down blocking buildings as on Benzene.)
Ranged unit kiting
In my mind this is one change with several parts to the code, but the effects vary depending on the ranged unit. For one thing, air units and ground units kite differently because ground units have to worry about terrain or other units getting in the way. For another, Steamhammer kites what it calls “AlwaysKite” units (not a good name since they don’t in fact always kite) with different code than others. The AlwaysKite unit types are set by Micro::AlwaysKite() and are vultures, wraiths, and mutalisks—fast units with instant acceleration—plus guardians. (By the way, the rate of change of acceleration is called “jerk” so instant acceleration means infinite jerk: those units are infinite jerks.) The AlwaysKite units use “muta dance” kiting code which pays closer attention to timing and latency than the regular kiting code, so that kiting is more precise and takes advantage of the instant acceleration.
-
A suite of new routines appeared in the Micro module, for use both in kiting handled inside Micro and by other unit control code as needed. For kiting, the key ones are kiteBack() for kiting regular units, and the more generic fleeEnemy() used for AlwaysKite units.
-
kiteBack() for regular units considers alternate kiting destinations if the first try doesn’t pan out, according to checks I list below. The effect is that if a unit cannot or should not kite directly backward, it may go diagonally backward or sideways. A unit that is unable to kite away will realize it and keep shooting in place.
-
Regular units, air or ground, don’t kite into enemy static defense range. If they’re already in range, they don’t kite deeper into enemy static defense range—the check counts the number of attacks on a prospective kiting destination and rejects it if the prospective count is higher than the current count. It’s relatively rare to fail this check; units are not often backed up against enemy static defense.
-
Regular ground units do not kite into terrain.
-
Regular ground units do not kite into a tile occupied by any other ground unit, whether a mobile unit or a building. The check is conservative: You might be able to squeeze in there if it fails, but if it succeeds you can definitely go there.
For zerg, the changes primarily affect hydralisks. Hydras used to kite into terrain or into each other as an everyday matter, with the result that they would turn away from the enemy, fail to move because they were blocked, fail to shoot because they were trying to move, and generally be useless and die in vain. To me it was a raging unmissable micro blunder that left hydralisk potential bleeding on the ground. Sideways kiting helps hydras keep moving and spread out so that more of them can fire. Hydras still often get backed up to where they can’t kite, but now they know that they can’t kite and they keep shooting. Hydras do more firing and less dying in battles of every scale, for battles in which kiting happens (Steamhammer units kite only when they expect a benefit). To me it is particularly obvious in small-scale hydra versus zealot fights, which are visibly more efficient.
- The AlwaysKite units don’t do the above checks, but call fleeEnemy() which unconditionally moves away, making sure only that it stays within the map bounds. Slightly complicated unimportant details follow. The muta dance code inherited from UAlbertaBot figures where to kite back to using a function called GetKiteVector() which starts with a point to move away from and calculates the destination by trigonometry. It returns an offset from the kiting unit; add the offset to the kiting unit’s position to get the destination. At some point I apparently mistook the offset for an absolute position and clipped the offset to the map bounds, a teeny-tiny gargantuan boo-boo (the effects on kiting were not severe in practice). More recently, Steamhammer added a function DistanceAndDirection() which, though I didn’t notice it at the time, does the same calculation by the mathematically equivalent method of normalizing the offset vector to length 1 then multiplying it by a scalar. Though it doesn’t make a practical difference in games, the vector math runs much faster than the trig functions, so here is an example of the optimization technique of strength reduction. In working on kiting I noticed the overlap. After undoing the mistaken clipping, I verified by test that the two routines returned identical results to the pixel. Following the motto that strength reduction makes you stronger, I removed GetKiteVector() in favor of fleeEnemy() with the same behavior and less code. By the way, it could be that kiteBack() would be more effective, especially for vultures. It does support air units. I didn’t try it yet.
Zerg
-
Place a sunken to stop a cannon push. If photon cannons are dangerously near one of our bases, place exactly one sunken to prevent them from creeping closer; set it as close as possible outside the range of already completed cannons. This stops most approaching cannon pushes in their tracks. It may be possible for the cannons to circle around outside the sunken’s range and push in regardless, but I’ve only seen that once. The calculation of the cannon’s range is not exact, and on rare occasions the sunken is placed too close, which leads to suicidal placing of the same sunken over and over.
-
Place a sunken to combat a bunker attempt. If the enemy has built a bunker near a base of ours, try to set a sunken where it can hit the bunker and the bunker cannot hit it. Again, the calculation is not exact and occasionally the sunken is too close (it’s usually good, and I’ve never seen it too far to hit). Also, by the time the sunken is up generally the terran has marines on site, and with good play the marines may kill the drone, or may kill the sunken before it can finish. It won’t just happen; terran has to play well, and zerg should smash clumsy bunker attempts. If the sunken does finish, the bunker play will normally fail and terran will be behind; even if terran kills the natural hatchery, zerg will be comfortably ahead because of the cost of the early barracks plus bunker. (Seriously! I’ve seen it repeatedly versus Halo by Hao Pan.) I concluded that the old school sunken is Steamhammer’s best defense for now, though it’s not the best possible defense. The modern standard way to defeat an early offensive bunker is to pull drones to prevent the bunker from finishing, or prevent marines from getting in. Steamhammer doesn’t have the micro skills yet.
-
When placing its one-sunken-per-base to defend against raids by vultures or dark templar, Steamhammer normally places the sunken next to the hatchery to defend the mineral line. In a change, if the base is the natural of some main base, it places the sunken at the front line position instead. That way the sunken provides some protection to both the natural and the main behind it, and if later sunkens are placed then they will also be at the front line and reinforce each other.
-
Hide a drone on the map versus Contain or Proxy plans by the enemy, and when it is next time to make a hatchery, let it be a hatchery at a hidden base. This is a reaction to a recognized plan: The openings for Counter Contain make a hidden base while the openings for Counter Proxy do not, but the reactions to both call for a hidden base. If there is a scout drone out at the time, then it abandons its scouting mission and hides on the map; otherwise a fresh drone is sent out (which is riskier because it may be caught by, say, containing cannons). Versus Contain, Steamhammer continues its planned opening; versus Proxy it breaks out of the opening unless an early pool is already queued, so that it can react decisively. There remains a weakness versus early bunkers: If Steamhammer scouts the barracks first, it may recognize the plan as a fast rush, in which case it will not update the recognized plan after the bunker starts, and will react differently than intended.
-
Scourge no longer attack floating buildings. This is a fix for a regression. Wasting gas to set a floating ebay afire is an effective way to suffer.
-
If an enemy Wraith plan is recognized, make an evolution chamber right away. Before the Wraith plan was added, Steamhammer waited until it actually saw a wraith. Now it at least has a chance to react in time to 2-port wraiths.
-
Unit mix adjustments: If the enemy cannoned us in, favor hydras much more. Vultures more strongly contraindicate zerglings. Versus protoss, favor mutas more; Steamhammer was barely making any after the opening, sometimes building a spire and never using it. Protoss air units more strongly discourage guardians; it was too common to see the guardians countered by corsairs.
-
Unit mix in the cleanup phase of the game: If all enemy buildings are unreachable by ground, prefer air units. This could mean the enemy has an island base, or it dropped buildings on a plateau, or its buildings are floating over water. This rule doesn’t outright require air units, because the enemy may still have an army in play.
-
Be slightly slower in some cases to take the second gas. It’s a tiny step.
-
A regression prevented Spawn Broodlings from being researched, so the skill was never used. Fixed. Tanks or high templar may find themselves abruptly dead.
-
In a rare ZvZ where the enemy has lurkers or ultralisks, be quicker with broodling research and prefer a higher number of queens. Queens versus ultralisks = advantage queens. It’s fun to be ready with a correct reaction to a rare situation. Steamhammer has played some successful and entertaining games by being more ready than its opponents for unusual events like hive-tech ZvZ.
-
If the enemy is attacking on the ground and you happen to have extra minerals and larvas on hand, then maybe, just maybe, you should make zerglings instead of drones. In fact, I insist on it. You probably didn’t scout the full size of the enemy army. Make zerglings, dammit!
-
If we’re in the opening and we have reacted to the enemy’s build by adding more drones than planned, and we’re nevertheless in a situation where there is a mineral shortage and a gas excess, then do not spend one of the extra drones to make an extra extractor. That normal Steamhammer reaction does not make sense in context. This improvement may prevent only a few mistakes over the course of the tournament, but some mistakes are too ridiculous and have to be prevented.
-
Steamhammer zerg normally breaks out of its opening if it faces a fast rush that the chosen opening does not already counter. Steamhammer now considers that its 7- and 8-drone dawn hydra rushes counter an enemy fast rush. The change has saved games in test versions.
-
If there aren’t “enough” drones, then when adding static defense Steamhammer zerg replaces each drone as it is used up. It’s necessary to prevent emergency defenses from wiping out the economy. I decreased the limit of “enough drones” so that Steamhammer can bring up defenses faster in some midgame situations.
-
When looking around a base to see whether it is adequately defended by sunkens, the radius is decreased for considering a sunken as defending the base. It’s a tweak.
-
Steamhammer is slightly more cautious about morphing a sunken that will be weak when it is finished. Another tweak.
-
The code to place a sunken to defend against vulture or DT raids forgot to check whether we have a spawning pool. Fixed. Other checks in the code would have prevented the error from causing incorrect commands if it ever came up, but it could have caused inefficient play during an emergency.
Openings
-
I made 3 Counter Contain builds to defeat cannon contains and other early containment attempts. They work by starting a hidden base elsewhere on the map, so that units can be produced outside the contain: 6PoolHide 9PoolHide OverpoolHide. Contains still cause Steamhammer to misbehave because it assumes that units can safely walk past (they can’t fight their way past, but walking is different), so the openings don’t work perfectly. But combat units produced outside do usually prefer to find and attack the enemy main first, so it’s a great advance over former behavior.
-
The openings I hoped would have a chance against Stardust are 10HatchLing+1, Over10Hatch+1, and Over10HatchHydra. They are all-in builds. The few Steamhammer wins over Stardust so far are due to zergling attacks after Stardust messes up, so I made 2 zergling openings with what I guessed to be good timing. Every Steamhammer win so far has been by a different opening, and neither of these was able to score—they might be as good as anything. The hydra build is one suggested by Jealous in an SSCAIT weekly broadcast. I didn’t really expect it to work and it didn’t, but it was worth a try, and besides, the opening has value for other purposes.
-
AntiWraith_2Hatch is configured as a Counter Wraith build. It makes an evolution chamber in time to get spores, and goes 2 hatch muta.
-
AntiFact_Overpool11Hatch is an additional anti-factory mutalisk opening. By opening with overpool it hopes to intimidate the terran into playing too defensively against possible early zerglings. In fact, it makes few lings and aims for 2 hatch muta.
-
2.5HatchMutaExpo is a variation of the existing 2.5 hatch muta build (2 hatch muta plus a later third hatchery), which adds the third hatchery at an expansion rather than in the main. The original version stuck to 2 bases because it struggled to place the third base on the 2-player SSCAIT maps. That weakness is mostly solved, so it’s time to play the build right.
-
Steamhammer doesn’t defeat ZZZKBot as consistently as it should, because Steamhammer is weak at defense. (Microwave is good at defense and wipes the floor with ZZZKBot. “You are my mop!”) Falling back on a quick fix, I tried writing openings. 9PoolHatchSpeedSpire2 as written is too slow to beat the 4 pool. 9PoolHatchSpire is good and should beat all ZZZKBot builds, but Steamhammer still isn’t consistent, only getting about 80% wins in the latest test. A quick fix is not enough, Steamhammer needs the actual skills.
Debugging
-
Clarified the wording in the building manager’s debug display. The construction status strings were kind of cryptic.
-
A meaningless yellow square is no longer drawn in the upper left of the map. It was a leftover code snippet from old debugging. It took me a couple searches through the code to find it.