archive by month
Skip to content

looking at cpac

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

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

The most interesting changes are to the strategy.

strategy changes

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

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

	return _latestBuildOrder;
}

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

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

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

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

tactical and micro changes

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

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

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

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

the openings

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

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

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

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

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

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

conclusion

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

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

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

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

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

Next: Overkill.