The config file is named Steamhammer_1.2.1.json and controls settings including the bot’s choice of opening build order.
The config file is easy and fun to edit. Especially useful are the Debug section if you want to see what the bot is thinking, and the Strategy section if you want to change its openings. If you want to test your own play or any bot against a specific opening, you can write out the opening build order and tell Steamhammer to follow it. (The config file is inherited from UAlbertaBot and you can do the same with UAlbertaBot, though Steamhammer has more features.)
The file is in JSON format. If you introduce a syntax error that you can’t find, drop it into any handy JSON checker (plenty are online).
I’ll go through section by section.
The bot’s name and author. If you fork Steamhammer, don’t miss this part! Setting PrintInfoOnStart to true tells the bot to announce its name and author when it starts up.
SetLocalSpeed is 0 to let the bot play at its full speed in games you set up against other bots. Some bots set a slower local speed by default. You can enter commands like /speed 30 to slow it down and /speed 0 to speed it up again. These commands work across bots, not only in Steamhammer, and there are other commands. UserInput means you can manually enter Starcraft actions for the bot while it is playing, which makes some experiments easier. Set CompleteMapInformation to true for the bot to cheat and see everything (it is not allowed in competition, obviously).
Various micro settings. The most confusing is KiteLongerRangedUnits, which really means “kite these units even if the opposing unit has a longer weapons range.” It makes sense mostly for fast units like mutalisks and vultures. If ScoutDefenseRadius is set to a positive integer, then an enemy worker scout which approaches to within that range of our main base (in pixels) will be met with a worker of our own that tries to chase it away. In Steamhammer it is turned on for terran, because terran needs to defend SCVs which are constructing buildings, and set to zero for other races.
The following settings can be given a single integer value, or if you are playing random, they can be given a different value for each race.
RetreatMeleeUnitHPRegroupRadiusUnitNearEnemyRadiusScoutDefenseRadiusTo give a single value, just specify it: "RegroupRadius" : 600.
To give a different value for each race, use a JSON object like this. "RegroupRadius" : { "Zerg" : 400, "Protoss" : 600, "Terran" : 700 }.
If you use a JSON object and leave out some races, then omitted races get the value 0 for the setting. In Steamhammer, this is how scout defense is turned on only for terran: "ScoutDefenseRadius" : { "Terran" : 500 }.
WorkersPerPatch sets the maximum number of workers to seek to make for each mineral patch at the bot’s bases. It is a floating point number. According to conventional wisdom, you should go for 1 to 1.5 drones per mineral patch as zerg, and 2 workers per patch or slightly more as the other races.
If you play a fixed race, you can give a single floating point number for WorkersPerPatch. Steamhammer gives a number for each race so that it can play random. It works the same as in the Micro settings; see above.
The other options should be self-explanatory, except that PylonSpacing only applies to the first 2 pylons made. The first 2 pylons are spaced more widely to power a larger area for buildings.
In the release version, all the “draw” options except DrawGameInfo are turned off. In development, I turn on the appropriate ones to see what the bot is thinking. They draw information on the screen. If you turn on too many at the same time, they’ll draw all over each other. DrawGameInfo and DrawProductionInfo are my favorites.
ErrorLogFilename - when an assertion fails, it writes to this fileLogAssertToErrorFile - you should never need turn this offDrawGameInfo - the opponents, chosen strategy, map, and game time in the upper leftDrawStrategySketch - (only for zerg) during the opening, the name of the opening; later, the unit mix and tech target, drawn in the same location as DrawGameInfoDrawUnitHealthBars - above each unitDrawProductionInfo - the production queue, what the bot is planning to build, drawn in color on the leftDrawBuildOrderSearchInfo - tech info from BOSS, can be useful to coders (not used when playing zerg)DrawScoutInfo - about the early game scouting worker and its plansDrawEnemyUnitInfo - counts of enemy stuff we’ve seen, drawn on the rightDrawModuleTimers - black box of millisecond timers, to see how well the bot is adhering to the time limitDrawResourceInfo - details related to gathering minerals and gasDrawCombatSimInfo - who will win the fight and by how much (can be confusing because of the multiple squads)DrawUnitTargetInfo - lines pointing to where units are going or aimingDrawUnitOrders - for each unit, unit->getOrder(), plus any research or production that is underway DrawBWTAInfo - terrain analysis from the BWTA2 libraryDrawMapGrid - a big grid laid over the map, with summary info in some grid squaresDrawBaseInfo - x,y locations of all bases down the right side of the screen, green if we own them, orange if the enemy is believed toDrawStrategyBossInfo - (only for zerg) info from the strategy boss, drawn to the left of the base infoDrawSquadInfo - the bot divided its forces into these squads, drawn in the upper centerDrawWorkerInfo - some stuff related to workersDrawMouseCursorInfo - I never use thisDrawBuildingInfo - buildings about to be started or under construction, drawn in the upper centerDrawReservedBuildingTiles - places where buildings are not allowedDrawBOSSStateInfo - more tech info from BOSS, not really usefulThe only remaining module is UseStrategyIO, which uses a simple machine learning method to seek openings which are successful against previously-played opponents. I have not tested the feature to work with Steamhammer’s random openings. In any case, it is turned off in the code—Steamhammer inherited the strategy I/O from UAlbertaBot, where it was already turned off.
The map grid that Steamhammer uses to keep track of explored areas and find nearby units efficiently. I have never had a reason to change the number.
ScoutHarassEnemy - if true, the scouting worker attacks, wreaking havoc on weak opponents and dying quickly to strong opponentsReadDirectory - for reading back saved learning data between games; see UseStrategyIO above; don’t change it unless you know what you’re doingWriteDirectory - for saving learning data for future games; dittoThe next entries tell which opening to play when. Steamhammer inherited the opening specification from UAlbertaBot, but adds many features.
There are several different ways to tell Steamhammer which opening to play.
1. If you put in a line "Zerg" : "9PoolSpeed", then Steamhammer will play 9 pool speed whenever it is zerg. (Don’t forget the comma that separates it from the next line.)
2. If you put in a line "ZvT" : "ZvT_2HatchMuta", then Steamhammer will play its 2 hatch mutalisk opening every time it faces a terran. In the matchup name, “U” means that the opponent chose random (the race is “unknown”). Note: The bot’s own race can never be unknown, even when playing random; we know it as soon as the game starts.
3. Steamhammer can choose openings randomly. Instead of the name of an opening, give a StrategyMix which lists different openings with weights for how often they should be played. The weights can be any positive integer, but I like to choose weights which add up to 100 so that they are percentages. (Get the punctuation here exactly right.)
"ZvU" :
{ "StrategyMix" : [
{ "Weight" : 10, "Strategy" : "5Pool" },
{ "Weight" : 20, "Strategy" : "9PoolExpo" },
{ "Weight" : 70, "Strategy" : "9PoolSpeed" }
]},
4. Steamhammer can play different openings against opponents that it recognizes by name. Set UseEnemySpecificStrategy to true and, inside the EnemySpecificStrategy subsection, give an opening for each opponent that you want to treat differently. The example means “When playing Jakub Trancik as zerg, play the 9 pool expo opening. When playing as protoss, open with double gateways on 9.” In this example, the terran opening is not specified, so it is chosen by the usual method.
"Jakub Trancik" : { "Zerg" : "9PoolExpo", "Protoss" : "9-9Gate" }
5. The random openings also work inside the EnemySpecificStrategy section, but they assume that you are playing a fixed race. If you play random, you can’t specify random openings against specific opponents.
Finally, the Strategies subsection defines the opening build orders themselves. The opening build order is a sequence of items to build one after the other. Each item can be a unit, a building, an upgrade, a tech to research, or a command. The name of each item is case-insensitive, that is, upper case and lower case do not matter.
As an abbreviation, you can order up multiple units or buildings of the same kind. "3 x zergling" is the same as "zergling", "zergling", "zergling".
Steamhammer provides a number of commands that can be executed during the build. All the commands start with the keyword “go”.
go scout - unconditionally send a scout worker to the enemy base and have it stay there watchinggo scout if needed - send a scout only if the enemy base location is not already known (by any means)go scout location - return the scout home (or don’t even send it out) as soon as the enemy base location becomes knowngo steal gas - take the enemy’s geyser with the scout workergo stop gas - stop collecting gas from all extractorsgo start gas - start collecting gas from all extractorsgo gas until [n] - collect amount [n] of gas, then stop (e.g. go gas until 100 for zergling speed)go defensive - units stay at home for the time beinggo aggressive - units seek out the enemyGas. When you first build a refinery, Steamhammer assumes that you want to collect gas right away, so gas collection is turned on. I put “go gas until” commands right after the refinery (such as for zerg): "extractor", "go gas until 100". Steamhammer remembers the intention and executes the steps at the right time (though it often collects 8 or 16 gas more than it should).
Aggressive versus defensive. After "go defensive", units wait next to the command center, nexus, or hatchery unless an enemy comes near. After "go aggressive", they head out onto the map and close with the enemy. Units start out aggressive and only become defensive if you explicitly put in "go defensive". At the end of the opening build order, units automatically become aggressive if they aren’t already. Defensiveness is most useful for terran, which benefits from gathering a group of units before moving out, but it can also be useful for other races when playing an opening with few early units. I put "go defensive" right at the start of a defensive opening.
If you ask for “hatchery”, Steamhammer assumes you want the hatchery at a gas expansion. You can choose.
"hatchery" - at a gas expansion"hatchery @ expo" - at a gas expansion (the same)"hatchery @ min only" - at any expansion, whether it has gas or not"hatchery @ hidden" - at a “hidden” base somewhere far from both players’ mains"hatchery @ macro" - macro hatchery at the main baseIf you ask for "bunker", "missile turret", "photon cannon", or "creep colony" to build static defense, Steamhammer assumes that you want it at the main base. Other buildings are the same; stuff is built at the main unless you say otherwise. There are only 2 choices. The arrangement is awkward and limited and I will probably change it in a future version. Steamhammer does not have the smarts to place defenses in good locations (like toward the enemy), so it may do something silly.
"creep colony" - at the main base"creep colony @ main" - at the main (the same)"creep colony @ natural" - at the natural, if possible (otherwise at the main)this version 30 March 2017
updated 4 April 2017 with minor nav fixes