archive by month
Skip to content

Steamhammer’s improved queue reordering

It’s taking a long time to write up the uses of burrow, because there are so many, so here is a note on queue reordering.

Steamhammer retains UAlbertaBot’s production system, with a queue of items to produce. The queue lays out the exact order of units to make, research to do, and so on. In the beginning of the game, the queue is filled by an opening build from the configuration file. Later, the build order planner BOSS (for terran and protoss) fills the queue with long sequences, or the zerg strategy boss fills it with shorter sequences.

Most of the opening builds, though not all, are tightly written. Executing the build in order is normally efficient. But game events can intervene. For example, if the enemy scout harasses gas workers and slows down gas mining, maybe it will be more efficient to rearrange the order slightly. Maybe the 100 gas for the lair is delayed, and it makes sense to pull forward the drone that was going to be built afterward. The zerg strategy boss will often blindly misorder items the same way: It will ask for a lair that there is not enough gas to make yet, then (say) a second extractor that could be made immediately. And BOSS creates long and poorly-designed sequences with many items out of order.

I started experimenting with queue reordering in version 1.4 to mitigate these problems. The first version of queue reordering is extremely conservative: It recognizes only one case of misordering, the gas case where we are waiting for gas to start the first item in the queue, and we can pull forward a later item (up to 3 items later in the queue) that requires no gas and has no dependencies other than a worker to build it (a resource depot, a supply unit, a refinery building, or a zerg creep colony—the supply unit might be an overlord, which requires a larva instead). Also it doesn’t try to predict mineral income; there have to be enough minerals to build both items before it will reorder the queue. Because of this conservatism, queue reordering happens rarely, about once per game on average, and has virtually no effect on the bot’s strength. But it doesn’t seem to introduce any bugs despite its trickiness, so it proved the concept.

I got e-mail from a Steamhammer user who suggested that I should make the queue production “multithreaded”. To me that meant reordering the queue more freely. Maybe a better analogy is a compiler’s peephole optimizer.

I extended the lookahead in the queue from 3 items to 4, allowing reordering in a slightly wider window. I removed the requirement that the item moved forward have no dependencies; now it checks that the dependencies are met. Most importantly, I added a second case: If the next item can’t be produced because no producer is available for it (you asked for a tank, but every factory with a machine shop is already busy producing something else), or because tech dependencies are not met (you asked for a goliath but the armory is not finished yet), then a later item whose dependencies are met can be pulled forward and produced next. I kept the conservative requirement that there must be enough resources for both, to reduce the risk that the reordering will delay production overall. To relax the requirement, Steamhammer would have to predict future income, and it doesn’t do that yet. There is still some risk that reordering will delay production, if an unimportant item is moved ahead of an important item that is produced from the same source—you desperately needed scourge to survive the air harass? Too bad, the larva was used up making another drone that could be started a little earlier.

So far, my tests have not turned up any bugs, although reordering the queue is delicate and seems easy to mess up. I also haven’t noticed any cases of important items being delayed in favor of unimportant ones, though I’m sure it must happen occasionally. In practice, it looks like all win.

The zerg queue is still not often reordered. The strategy boss is fairly accurate in its production, and also it usually puts out short sequences that don’t have many items to reorder. Protoss, and especially terran, see frequent queue reordering, and it helps noticeably. BOSS likes to do silly things like order 4 SCVs in a row when there are 2 command centers, delaying everything else. Now Steamhammer is able to start 2 SCVs, then look into the future and say “OK, the next SCV has to wait, but these marines can go ahead.” Protoss and terran macro is still not strong, but it is visibly less bad than before. Also some production jams are mitigated, since Steamhammer can move items ahead of the jammed item.

Of course I intend to drop BOSS when I get that far. But I don’t think the queue reordering work is wasted. It helps occasionally in the opening, and it allows even the more careful zerg strategy boss to be a little sloppy about its sequences. I think there is a fair chance that I’ll keep the queue reordering even after I replace BOSS.

Steamhammer’s squad structure 2: design ideas

My plans for replacing the squad infrastructure are in a vague state. Here’s what I’m thinking.

• Above all, turn the worker manager and scout manager into ordinary squads. All the special cases of delegating units to managers should go away, subsumed by a general assignment mechanism. Other design features follow from that decision.

• A new bookkeeping class for squad information. SquadData as it stands seems awkward to me.

• Possibly create a hierarchy of squads. In that case, the root is the supersquad of all units and acts as the bookkeeping class for its children, which are the base-level squads that exist now. Each squad could subdivide its units into subsquads with different roles or purposes. The future worker squad might have a subsquad for each base to mine, a combat squad might have subsquads corresponding to the current unit micro managers, and so on.

• Alternatively, have a flat squad structure but allow roles in each squad to be assigned by a tag attached to each unit. This allows for the same features, it’s just a different code design. I’m still thinking through which idea makes better sense. I can think of a case for allowing both....

• In either case, provide the features through a tidy object oriented design so that a combat squad doesn’t have to worry about accidentally assigning a unit to mine gas. Look up the names of the design patterns if you want; I only remember the patterns themselves. No matter the details of the design, the current unit micro managers will become more general role managers. The way that role managers coordinate with the larger squad seems like the key to working out the undecided design details. I’ll need to work through cases in detail to foresee what’s needed in the implementation.

• Information wants to flow both up and down. Top-down control means that the tactics boss gives tasks to squads, which in turn give more detailed tasks to its units. Bottom-up control means that units examine their environment and decide what to do accordingly, perhaps self-organizing into larger task groups. As I mentioned in a comment yesterday, you want both. Units should examine their environments in light of their tasks, and the information they produce should work its way back up to the tactics boss. I have to think more about how to manage the upward flow of information.

• Currently, some bits of code that aren’t much interested in unit control end up issuing orders directly to units: The building manager takes temporary ownership of a worker to construct a building, the combat commander directly orders comsat scans on its own initiative, and a few more cases. It probably makes sense to consolidate all these somewhere in the squad code. Put all unit orders in the same module and it will be easier to cope with latency frames and the like. That will involve adding some mechanism to issue these more detailed commands to a squad.

Whatever the decisions, the goal is cleaner, more regular code that at the same time better supports the features needed for good play. More regular code will make it possible to apply machine learning uniformly across tactical and micro decisions. The purpose of investing time to rewrite working code is to earn back that time in the long run and reach the goal sooner.

Steamhammer’s squad structure 1: awkward points

UAlbertaBot’s squad structure, still used in Steamhammer with little change, is not rich enough to easily support good play. It can be made to work, but things get awkward. When I reach the 1.5.x series of versions, which will be about strong mutalisk play, I intend to do a big rewrite, to make it easier to support good tactical play and good cooperation between units in a squad. I’ve been thinking about what the plan should be.

Today’s post is about the awkward points in the squad infrastructure. Next I’ll write up my thoughts on how to do it better.

Too many special cases. In Steamhammer, in theory every unit is assigned to a squad. I’m not sure it’s true in practice, but it’s close. Workers busy mining or building are in the Idle squad, because by 1984 doublethink, work is idleness. Well, I guess the real reason is that workers are not controlled by orders to their squad, but by the worker manager (or briefly by the building manager)—the squad itself is idle, though its members mostly aren’t. The worker manager has its own special case task system, and assigns workers to mine minerals or mine gas or repair or whatever. A worker sent to fight is taken out of the Idle squad and put into a combat squad. The squad code itself has a special case to treat the Idle squad a little differently.

Another special case is the scouting worker, and for zerg, the scouting overlord. Their movements are controlled not by the squad, but by the scout manager. The scout manager also has its own system to keep track of goals and tasks. I would like to unify the different systems at least enough that they can be seen as different variants of the same thing, not as unique subsystems that share little in common.

Weak squad orders. The special cases come about because the squad order system is not powerful enough to represent all the goals and tasks needed to control workers or scouts. That means it’s also not powerful enough to represent everything that a squad wants to do in combat. There are a bunch more special cases in the micro managers that are part of the combat squad code, working around the limitations in ad hoc ways.

Internal coordination. Suppose that Steamhammer’s marines and tanks meet mass sunkens and decide to attack. The tanks siege out of sunken range and the marines charge in. It’s fine if the force is strong enough to defeat the sunkens with marines left over, but if the marines all die, then zerglings or mutalisks kill the tanks. Something similar happens when vultures and tanks meet photon cannons. The squad splits up its members into unit types that may behave differently, but it provides no mechanism for the unit types to cooperate depending on the situation. There are many, many cases where Steamhammer comes to grief because its squad members don’t coordinate among themselves, and without any general mechanism, each case has to be implemented from scratch.

With the current code, it’s somewhat awkward to implement features like positioning other units in front of sieged tanks to provide vision. The division of unit behaviors by unit type is not helpful here; you should be able to pick any suitable unit to provide vision, whether a floating building like Krasi0, or wraiths, or vultures, or marines. We care about the role of providing vision, not the unit type playing the role. And similarly for many other combat roles.

Coordination between squads. Steamhammer’s main combat squads are the Ground squad and the Flying squad, separating ground and air units because they often want to act separately. But when they do come together in the same place with the same goal, they still don’t cooperate; see limitations of combat simulation (tactical coordination section). The squads could be merged together in this case, but that doesn’t improve the behavior! The internal coordination weakness is just as bad.

Different roles with the same goal. Here is another example of poor coordination. When new fighting units are produced, they are put immediately into a combat squad, but they may start out far from the front lines. They are reinforcements and have to make their way across unseen terrain to reach the front lines. Steamhammer has almost no understanding that the different units in the same squad are in different situations and need to do different things—only a few bits of special case code to provide different behavior. It often loses the reinforcements unnecessarily, or sees them distracted by passing targets.

One fix would be to break the units into two or more squads and give each squad a different order: The vanguard squad fights as usual, the reinforcement squads attempt to join up (or are simply given the order to attack the same target as the vanguard squad, so that they end up going to the same place and then are merged, perhaps by a clustering algorithm). Another fix would be to retain the single squad, but allow it to be partitioned into a vanguard group and reinforcement groups. The 2 plans differ mainly in the code organization; they’re the same otherwise.

Next: My ideas for fixing these issues.

the most underused skill?

If a skill is effective in games and not too hard to implement, and yet isn’t implemented in many bots, then surely it is an underused skill. For example, I think that evacuating workers from a base under attack is underused. It is easy to tell whether to evacuate workers: If you have a combat simulator or an army strength estimator or any method to tell whether you’ll win or lose a fight, then run it when the enemy reaches a base of yours, at least if you have another base that can keep mining. It is not as easy to tell where to evacuate workers to, since they might flee toward the enemy army. But you know the current place is bad, and running anywhere else is probably no worse.

Steamhammer doesn’t evacuate workers, and suffers for it. It’s high on my list. The 7 bots above it on the bot ladder do, except I think for XIMP by Tomas Vajda; Steamhammer may be the strongest bot missing the skill. Killerbot by Marian Devecka is particularly good at it, if as ask me. Most other bots don’t; it’s a fairly rare skill, which is why I say it is underused.

There is a special case that is even easier to implement: Terran can evacuate SCVs by simply lifting the command center. If terran has another command center landed anywhere else (reachable by land), then the SCVs will return their cargo there. If not, the SCVs will stay near the minerals or gas, not the best place to hide but better than nothing. As a side benefit, if the attacking force includes units that can’t shoot up, the command center will often take longer to destroy—even if it only floats there and doesn’t move away.

PenaBot by Henri Kumpulainen used to lift its command centers, if I remember from so long ago. Iron does it sometimes when losing, though I don’t think the purpose is to evacuate SCVs. LetaBot by Martin Rooijackers will float a command center, but only to move it into position. I can’t think of any current bot that lifts its command center to protect itself.

I nominate lifting the command center for safety as the #1 most underused skill. What do you think are underused skills?

new bot WillyT

New terran bot WillyT is easier to write about than GuiBot. I can’t see anything in common with WillBot. “T” in “WillyT” might stand for terran, and “Bot” in “WillBot” is semantically empty, so the names are nearly the same—but apparently it is a coincidence. The internet knows a bunch of things named Willy T. Anyway, WillBot is Java and WillyT is C++.

WillyT plays similarly against all races. It builds 2 barracks, gets medics, stim, and marine range, then goes for an all-in attack with marines, firebats, medics, and 8 SCVs. It’s a scary attack; it beat Tscmoo random which rather randomly decided to make carriers. ForceBot made 3 sunkens a little late and could not hold, while Arrakhammer diagnosed the situation and made 5 sunkens. WillyT sends reinforcements as it produces them, but the attack truly is all-in. If the opponent spoils it ahead of time, or is ready and holds it off without much damage, then WillyT has little chance. As I write, WillyT is ranked a little below average.

Its unit mix seems to vary by the race of the opponent. Versus terran, it mixes in a few firebats. Versus protoss and zerg, it makes far more firebats, I guess expecting mass zealots or zerglings.

WillyT has some micro skills. It scans for cloaked units. It has a win over Stone, so it has an idea how to defend itself against tricks. It keeps marines in the mineral line until it is time to move out, somewhat like Tscmoo, for safety against rushes and to make sure that the opponent can get in to see everything. After it moves out, it makes attempts to keep its force from spreading out too much.

WillyT doesn’t expand. If it destroys the enemy main, it doesn’t know how to search for more enemy bases. In this absurd game versus NiteKatP, WillyT destroys the protoss main and then neither side can figure out what to do next.

WillyT is the opposite of GuiBot in a way. GuiBot will benefit from bug fixes; WillyT will benefit from new features so it can cope with a wider range of situations.

OverpoolSpeed is broken in Steamhammer 1.4.1

Today I discovered that Steamhammer’s OverpoolSpeed opening is broken in version 1.4.1. It was still correct in the previous version 1.4. I had been experimenting with an overpool +1 build similar to the one in Killerbot by Marian Devecka. Somehow a weak, unfinished version of the +1 build got into the distributed configuration file under the name of the overpool speed opening. It must have been a copy-paste slip or something.

It’s fixed for the next version, of course. With so many openings, how many others have gross mistakes? Few, I hope, but I know there are many that could benefit from refinement.

new bot GuiBot

GuiBot has been getting extremely frequent updates, so anything I say about it may be obsolete by tomorrow. With that caveat....

Protoss GuiBot crashes in a large proportion of its games. When it doesn’t crash, it often performs poorly. On SSCAIT, it is currently ranked 4th bot from the bottom, making it extremely weak. But GuiBot shows some promising signs. It knows how to use a wide variety of units, including complex units like shuttles, reavers, and high templar. It gets many upgrades in a sensible order. Some of its skills are excellent. If the author can fix the crashes and a few of the biggest weaknesses, GuiBot will move quickly up the ranking.

I think GuiBot’s favorite opponent race is zerg. Against zerg, GuiBot opens with a forge expand build. It likes to place the forge beneath the gateway in a ling-tight arrangement, the most popular placement among human players, and for some reason unusual among bots. I imagine that the author knows the game. It also places the cannons farther behind than necessary, which is odd—it makes busts easier. Zealots plug the gaps in the wall. It makes corsairs and sets about clearing the skies of undefended overlords. A strong start.

Then when it comes to the fight, GuiBot tends to fall down. When the corsairs meet mutalisks, their natural prey, the corsairs don’t win as they should but fly around in panicked curves until they are shot down. They were serious when they said it was a good day to die. (Probes have a similar panic behavior, losing too much mining time.) Zealots group into a long line and chase stray enemies this way and that without making any decisive attack. If GuiBot had good combat skills, it would become strong. In this game, just played, ForceBot busts GuiBot’s wall, taking advantage of the rear placement of the cannons and the overeagerness of 2 zealots.

I don’t want to draw conclusions about GuiBot’s mix of openings. I have seen it play different builds, but the bot is updated so frequently that I can’t tell whether it is GuiBot or its author that is choosing the build.

I think GuiBot’s favorite unit is the shuttle. It likes to build a robo facility early, and the first thing it makes in the robo fac is a shuttle. If shuttles are shot down, it makes more shuttles. 1 or 2 shuttles accompany the army, and it uses them to micro units in battle: When a unit is in danger of dying, the shuttle picks up the unit and pulls it back a little before letting it re-enter the fight. This is a unique skill among bots and can be valuable, but I don’t think it is worth making a shuttle just for that.

Once reavers come out, somewhat later than I expected in watching the games, GuiBot’s shuttles switch to reaver dropping. GuiBot is good at it, about the same level as other good reaver bots. It does have a tendency to spend too much time at home waiting for new reavers to finish; a shuttle carrying 1 reaver will drop what it’s doing and run home as soon as a second reaver starts in the robo fac. Reaver dropping is not a rare skill any more, but it’s still deadly. The bot’s reaver targeting looks fairly good too; it doesn’t only shoot at the closest enemy, like Steamhammer or CerkoBot by Tomas Cere. See this game versus Ecgberht for an example (though the game was decided in a boring way, by a production freeze).

GuiBot also knows how to use psionic storm, though like most bots it is not skilled at the when and where. But a bot could use 100 good skills in a row and lose the game in the next moment with one big mistake. As I've said before, the law is: Adding features decreases elo; fixing bugs increases elo. I know from experience that after adding a big feature that will be valuable in the long run, I may have to fix a lot of problems to get back to zero in the short run. The greater part of bot development is not about adding skills, it is about fixing the weaknesses in the skills you have, and in the interactions between them.

developing an anti-vulture opening for Steamhammer

I decided I was tired of seeing Steamhammer lose helplessly to Iron’s vulture runby and Tscmoo’s factory openings. Terran can start with vultures and force zerg to defend: Zerglings quickly become useless, drones are at risk, and terran can run by defenses into the main as Iron does. Steamhammer’s strategy boss understands that a sunken is needed at the front, and has a vague idea that hydralisks may be useful if the book line happens to end, but in the end it doesn’t defend adequately. Then terran can follow up with more factory units or with wraiths, and zerg has to be ready for a range of possibilities. Against Steamhammer, Tscmoo likes to follow up with goliaths, which is effective against Steamhammer’s mutalisk openings. Too many crushing losses.

Zerg has a standard way to defend: Place a sunken at the front as a vulture obstacle and keep a modest number of unupgraded hydralisks in a defensive position. The hydras are general purpose and can fight off vulture runbys, wraith harassment, small drops—all the natural followups. Zerg then continues to mutalisks as usual. The mutas are delayed, but terran is playing a slow strategy so it’s OK.

Today I set about developing an “AntiFactory” opening that implements the standard defense. I decided on development tests against Iron to see whether the runby defense works. In the very first test, when the opening timings were still all screwy, Steamhammer put up a persistent defense and didn’t lose until well into the middlegame. An improvement already, good. I made a few fixes and tried again. Steamhammer held the early aggression cleanly and fought a long level game until Iron finally mined out and collapsed.

I did not expect that! Steamhammer lost drones by the barrel and miscontrolled scourge and chased 1 SCV with 3 ultralisks, all its usual mistakes, but Iron struggled too and could neither stop zerg from expanding nor keep a fourth base up. I guess Iron depends heavily on the success of the early vulture runby.

Well, one win does not make a champion. We’ll see how it goes as I polish the opening. It’s just that the test game was so long that by the time I finished watching it, I had forgotten what needed fixing in the opening....

When the opening is ready, will the opponent model be able to select it when it should? I think the answer is no. I think I will have to extend the plan recognizer to recognize early vulture plans. Then Steamhammer should be able to counter the vultures in the second game, and ideally cope with the followup. It would be nice if Steamhammer could get back into the learning war against Tscmoo terran, and come out on top this time.

AntiFactory branches fairly late from related openings. When the opening tree is available, Steamhammer should be able to recognize the vulture plan during the game and choose the right build on the fly, more like a human player. It might need some scouting improvements first, though.

Next: The new bots GuiBot and WillyT.

experience on the BWAPI bots ladder

I like the BWAPI ladder. It doesn’t seem to have an official name; I’ll just call it “the ladder”.

I’ve enjoyed following the games. I play over most of Steamhammer’s games on the ladder every day. The ladder makes random pairings, so it feeds me a wider variety of opponents and I see more strengths and weaknesses. Also the ladder plays more games in total, because it plays games at full speed, not slowed down for streaming.

Providing accurating rankings and elo is the primary purpose of the ladder, at least as I see it. With a diet of randomly chosen opponents, Steamhammer’s rank stabilized at #8, behind CherryPi and ahead of TyrProtoss, with elo steady in the 2230s. On SSCAIT, the same version’s ranking is not stable—it has varied by over a factor of 2, with the elo tending to rise into the low 2200s, then fall rapidly, then slowly rise again, depending on the whims of the voters. When the voters see Steamhammer with a high rank, they tend to pair it against opponents that it will lose rating points to; after it has lost the rating points, they tend to pay less attention. Steamhammer ends up below its equilibrium elo, and the popular opponents that defeat it end up overrated. The ladder pairs bots fairly, so it better predicts tournament performance.

Randomhammer’s rank can’t be compared across competitions so neatly, though, because the competitions treat random players differently. The difference in rules makes it less useful for predicting the tournament performance of a random player.

File I/O seems to work a little differently in each competition. They are all based on Dave Churchill’s tournament manager software, but each competition uses a different version or tweaks it differently, and the behavior is not exactly the same. They all share in common a read directory and a write directory, with read-only access to read and write-only to write, and copy the contents of write to read. They differ in whether and/or when they clear directories. AIIDE proceeds in all-play-all rounds, and clears write at the end of each round of many games. SSCAIT and the ladder proceed by single games, and can’t do exactly the same thing. I believe that SSCAIT never clears write. I don’t know what the ladder does, but it has different behavior, and Steamhammer’s code doesn’t work correctly.

Steamhammer’s problem, I saw immediately when I requested and received the stored data, is that its record of games against each opponent only extends back 1 game. Instead of the whole history, the opponent model has to draw conclusions based on the one previous game. Data is being cleared at some point; perhaps write is cleared before each game. Steamhammer appends data to the opponent’s file after each game, which works on SSCAIT. I think if I change it to rewrite the entire data file (originally read from read), instead of only appending the new game record, it will work everywhere, including the ladder and the AIIDE tournament. I won’t know for sure until it happens, though, because the details are not documented. The change will be in the next version, 1.4.2.

Call it a bug in Steamhammer. The bug means that Steamhammer’s rank and elo can’t be compared between SSCAIT and the ladder, even though the opponents are mostly the same in both. It’s possible that Steamhammer plays better with the bug, so its higher rank on the ladder is justified. The point about the stability of the rank stands, though.

Steamhammer 1.4.x plans, more concretely

I’ve narrowed down some of the decisions of what to do in the 1.4.x series, which is about improving the opponent model until it becomes more clever than Clever Hans. Of course my plans tend to change frequently, so no promises. This is what I’m thinking now. I wrote up less specific plans in February.

As always, I’ll do a lot of things that I don’t call my primary goals. Here are some that I feel pretty sure about.

  • Make some necessary improvements to the plan recognizer.
  • Speed up and improve building placement. In particular, fix the bug with protoss.
  • Make a start on reworking the production system to accept more general goals. I thought of ways to take it step by step.
  • Try a few experiments with squad control, so that I have a toe on the ground when I move on to the 1.5.x series, which will be about mutalisk control. I might teach units to hold position in locations where they can hit targets from outside enemy range, for example, which seems like an important basic skill.
  • Protoss shield batteries.
  • Overlord safety! Steamhammer loses far too many.
  • At least 1 new terran skill and 1 or 2 new zerg skills, just to keep progress up.
  • Probably a few skills made easier by the new base and map code, such as running workers away from a base under attack.

There are also things I want to try but feel less sure about fitting in. There’s already too much. One is Antiga’s ideas about ramps and chokes and stuff.

1.4.2

  • Fine-tuning of opening choice: Tend to repeat successful openings, regardless of other considerations.
  • The opponent model will try to understand whether the opponent plays a single fixed strategy, or varies its play. Just knowing that gives a lot of leverage to learning.
  • New base placement code, a major step in dropping BWTA.
  • Make the opponent model work on BWAPI bot ladder and other tournaments. There are slight technical differences between SSCAIT and other competitions in when directories are cleared.

With Steamhammer’s large number of opening build orders, it would be very slow to learn which one to use against each opponent using an undirected algorithm like UCB. Every opening would have to be tried a few times—even a long tournament like AIIDE would not be long enough to find good openings against all opponents. We have to use knowledge to direct the search to try more promising builds first. The instant learning of the opponent model is one piece of that knowledge.

For this version, fine-tuning will consist of noticing which openings have been more successful against this opponent, and tending to repeat them. I may also add exploration, but only a limited amount because there is too much to explore.

1.4.3

  • Collect opening data.
  • Start to adapt opening choice to the maps.

Another piece of knowledge to direct the search for a good build is knowledge of which openings are similar to each other. If a lurker rush opening gets smashed hard, maybe try a mutalisk opening next, or at least a slower mass lurker opening. That’s only the simplest way to use the knowledge. I want Steamhammer to collect data about its own openings in real games, so it learns the timings of when production and tech get completed, and the variation of the timings due to maps and to pressure from real opponents. It’s a model of each build, you could say. The bot should be able to compare the opening models against the opponent model, so it can choose an opening likely to upset the opponent’s plan.

1.4.4

  • Represent the tree of openings, and make choices at each branch.

I expect to implement the opening tree for zerg only at first. I think that by combining the opponent model, the opening models, and the smarts of the zerg strategy boss, it should be possible to make good enough choices at each branch point in the tree. The idea is that the opponent model tells us what the opponent is planning, the opening models tell us what we’ll do for each branch we might choose, and the strategy boss understands counters and can tell which result is best. I could be wrong, and in that case I’ll have to find more knowledge to add.

If successful, this could be an amazing skill. I’m determined to try. We’ll see how it goes!

Steamhammer 1.4.1 change list

I uploaded Steamhammer 1.4.1 today. As promised, the occasional crash bug is fixed—I never identified it, but I can no longer reproduce it, so I think my changes have fixed it or at least made it much less common. Also as announced, the primary goal of improving the opponent model is put off until the next version, 1.4.2. New map code is largely written, but it is not finished so it is turned off. As always, I have made a lot of minor fixes and improvements, because working on what I said I would work on would be almost like having a job. Key fixes are to limit protoss gateways to 10 (idea borrowed from Locutus by Bruce Nielsen) and a serious zerg bug in choosing the tech target, which suppressed tech switches in the midgame.

People will want some of these fixes, so I’ll put up source approximately tomorrow.

maps

• Fixed a crash on a certain seemingly messed-up version of Bloody Ridge.

Nicer code for distance maps, borrowed from a later UAlbertaBot. The new code is much cleaner and less bug-prone.

configuration file

• The debug option DrawBWTAInfo is replaced with DrawMapInfo, since I’m preparing to drop BWTA. For now, DrawMapInfo doesn’t do anything, since the new map code is turned off. The old BWTA info drawing code is removed.

• Bug fix: "n x item @ macrolocation" finally works, e.g. "2 x photon cannon @ natural". It was a bug in parsing.

• Added a new macrolocation @ center. Don’t use it though, except maybe on specific maps where you’ve tested it out; it doesn’t work consistently due to building placement bugs. If you ask for 2 buildings in the center, you may get 1 or none.

opponent model

• A new strategy reaction for all races: If the opponent is following a heavy macro strategy and we are still in the opening, drop any planned static defense. We won’t need it right off. Static defense added later (as a reaction to seeing scary enemy stuff) is built as normal.

tactics

• A squad that can’t find any buildings or units to attack has always been sent to explore the map. The change is, if the squad includes air units, it can be sent to explore tiles which are only reachable by air. It will help... if any opponent ever expands to an island or builds on a cliff, which hasn’t been seen so far.

• Steamhammer decides which enemy base to attack based on how much static defense it has. The change is, the enemy static defense is counted only up to a smaller distance. The longer distance was causing some mistakes in choosing targets.

• Bug fix: Units like scourge, which could belong to either the ground squad or the flying squad, could sometimes be mistakenly stuck permanently in the ground squad. The change is to CombatCommander::updateAttackSquads(). I saw a game today where this change would have helped, so I’m hopeful that it is a useful fix (but it’s certainly a fix).

micro

• Melee units (other than workers) prefer targets under dark swarm, in hope of also staying under swarm. This mainly helps protoss for now, but it is also preparation for when Steamhammer gets defiler support.

• Dark templar target zerg spore colonies with higher priority. I saw a bad game.

other stuff

• A few more opponent-specific strategies were dropped from the configuration, after experience showed that they were not needed any longer. My plan is to drop the remaining ones in the next version, 1.4.2, and rely solely on learning.

• Seeing a unit in the act of burrowing now tells Steamhammer that the enemy has burrow tech. It used to have to detect the burrowed unit to know. So many details to catch....

• The old ProductionManager::goOutOfBook() is renamed to goOutOfBookAndClearQueue(), which is what it does. A new goOutOfBook() goes out of the opening book if we are in it, and nothing else. This simplifies a few bits of code and makes them easier to understand.

• The unused BuildOrderQueue.queueItem() is removed.

terran and protoss

• Emergency response: If we have fewer than 3 workers, urgently make more if possible. This provides a small chance of surviving an extreme emergency—maybe the opponent is broken too.

• New 21Nexus opening, borrowed from Antiga.

• In tank openings, get vulture speed earlier. It was too late.

• Limit gateways to 10 total, an idea borrowed from the excellent Steamhammer fork Locutus. There are 2 benefits: 1. BOSS likes to order far too many gateways, so limiting the total prevents unnecessary expenditure. 2. What’s even more important is, it works around the building placement bug that causes the bot to exceed the per-frame time limit and lose games. The bug comes up when Steamhammer runs out of space to add buildings, so adding fewer buildings prevents it from happening. It is a super successful mitigation; it works better than all my other tries put together. In fact, I’ve been thinking of removing the vertical building placement workaround, which now probably causes more problems than it solves—maybe next version.

zerg

• When dropping excess upcoming hatcheries, count unstarted hatcheries in the limit. Steamhammer still often makes excess hatcheries, but it’s a little less severe. Steamhammer can’t time its hatcheries accurately, because it depends on future production timings and future unit mix, which Steamhammer doesn’t try to predict. The heuristics it uses instead are usually not far off, and this change is a small improvement to one of them.

• Supply counting for overlord production simulates how supply changes as queue production proceeds. The simulation is not exact, because it doesn’t account for timings such as how long hatcheries take to finish, but it is as exact as possible otherwise. This makes it possible for opening lines to order overlords at exact points and expect that runtime execution will follow the instructions. In practice there’s no gain for most openings, because overlord production was already fairly accurate. For occasional openings that depend on producing later overlords at precise timings, the difference is dramatic. Overlord production outside the opening is not improved, because overlords aren’t queued ahead of time then. (They aren’t always queued in the opening either. It’s optional, and overlords are only included when they are to be made at specific timings.)

• Important macro improvement: In midgame and later, make overlords faster. This fixes Steamhammer’s tendency to repeatedly supply block itself once the drone count grows over 40 or 50. Steamhammer still has some zerg macro weaknesses, but they are getting to be so slight that they aren’t worth attention for now. Well, except for one problem where it accumulates minerals versus terran....

• If the lair, spire, or hydralisk den is lost or cannot be made, break out of the opening. The plan has gone awry, so give it up and hand over control to the strategy boss.

• If the enemy has air tech or cloak tech, order a lair even if we don’t otherwise need a lair yet. The lair is a precondition for existing rules to fire, adding a spire or researching overlord speed to react to the enemy tech. I added this after watching Steamhammer lose a game where it thought that fast hydras with slow overlords were a good counter to dark templar (they could be good enough if it knew the right way to use them...).

• If hydras are needed in a hurry, get hydras in a hurry. If Steamhammer finds that zerglings are bad and hydralisks are good, and lair tech is still far away, then get hydras immediately without considering the longer term plan. This is a simplified way of accounting for the time it takes to get tech, as well as the value of the tech. In some future version, Steamhammer will calculate the time to get each tech and the urgency with which it is needed, and take all into account uniformly.

• Critical bug fix: Tech target calculation was wrong because a condition was coded as “if we have hive” instead of “unless we have hive”. This stopped many tech switches that should have happened in the middle game. This should improve play in many games, especially versus terran—though I have seen one or two games where Steamhammer probably played better because of the bug. Steamhammer’s understanding of tech switches remains shallow.

• Slight tweaks to ZvT tech choices.

• All zerg openings are updated to allow sunken colonies to auto-morph.

• The overhatch openings played versus random are switched from the in-base hatchery to the expo hatchery versions. The expo hatchery is better versus terran and protoss and still playable versus zerg, so it should be an improvement.

New openings: Over10Hatch1Sunk ZvZ_12PoolMain ZvZ_12PoolLing 2.5HatchMuta. The openings offer new choices against all races and should make Steamhammer even harder to prepare against. Also renamed a few existing openings with more specific names, to fit with the new ones.

Coming soon (in one order or another): More concrete plans for the following version. The new bot GuiBot. Experience with the BWAPI bot ladder. Squad structure.