Welcome to a tutorial for building artificial intelligence agents within Blizzard's Starcraft 2 game. I visited this topic some years ago, but quite a bit has changed, so I figured I would revisit it again. For those of you who are new to Starcraft 2 (SC2) or it's been a while, the game at a basic level is actually fairly easy to understand. In order to be highly competitive, lots of factors can indeed come into play, but if you're looking for a fun environment to try your programming and maybe even deep learning/reinforcement learning skills, this is a pretty good choice.
The layout of the game is: There are resources (minerals and gas), you use these resources to build buildings and units. Certain buildings and units require other buildings to exist before they can be built. Within Starcraft 2, there are 3 different "races" that you can play as, each with their own advantages and disadvantages. To start in this series, I will be playing as Protoss, purely because I like the way the units and buildings look most, but you're free to try to play as a different race. Your building and unit names will vary a bit, but many of the concepts are the same. The Protoss buildings and units order, for example is:
You can find the source for this image, and check out the other races from: Protoss Units.
From here, for example, if we wanted to build the Void Ray unit, we would need a Nexus first, then build a gateway, then a Cybernetics Core, then finally a Stargate, which can build Void Rays. Each building requires resources to build, but the Nexus, gateway, and cybernetics core all just need minerals to be built. The Stargate requires some Vespene Gas and minerals to be built. To collect resources, we have worker units that can mine the resources, and we'll need a special building, the "assimilator" to collect gas.
If that's still somewhat confusing, no worries, it'll probably make more sense as we get going. I am no Starcraft 2 expert, and my main intention is to eventually move from hand-coding everything to using reinforcement learning for at least some of the actions. I am mostly just doing this for fun, I have no real intention to be ultra competitive, but I have already enjoyed myself quite a bit competing against the bots. So, to begin, my general thoughts with Protoss are:
Building Void Ray units for attack, and some cannons for defending the main base from early attacks, along with of course gathering resources, building units, and building the necessary buildings. If you understand things up to this point, then you know basically as much about Starcraft 2 as me, so congratulations!
In order to code an artificial intelligence agent with Starcraft 2, we're going to make use of python-sc2 from BurnySc2. For getting Starcraft 2, installing BurnySc2, and getting some maps, you can use the instructions on the Github. I went ahead and just downloaded a handful of maps to play with, so just be prepared to possibly be using a different map name than me, but that should be fine for getting started. If you want to use the exact same map as me, just in case, the map I will be using is 2000AtmospheresAIE
from 2021Season2Ladder
, which you can find here. Once you have everything setup (Starcraft 2, Maps downloaded and moved to the Maps directory, and BurnySc2 installed), we can begin building our agent.
To begin, we'll start with some imports:
from sc2.bot_ai import BotAI # parent class we inherit from from sc2.data import Difficulty, Race # difficulty for bots, race for the 1 of 3 races from sc2.main import run_game # function that facilitates actually running the agents in games from sc2.player import Bot, Computer #wrapper for whether or not the agent is one of your bots, or a "computer" player from sc2 import maps # maps method for loading maps to play in.
Next, we can begin building our actual bot class and logic.
class IncrediBot(BotAI): # inhereits from BotAI (part of BurnySC2) async def on_step(self, iteration: int): # on_step is a method that is called every step of the game. print(f"This is my bot in iteration {iteration}") # prints out the iteration number (ie: the step).
Finally, we can run the game:
run_game( # run_game is a function that runs the game. maps.get("2000AtmospheresAIE"), # the map we are playing on [Bot(Race.Protoss, IncrediBot()), # runs our coded bot, protoss race, and we pass our bot object Computer(Race.Zerg, Difficulty.Hard)], # runs a pre-made computer agent, zerg race, with a hard difficulty. realtime=False, # When set to True, the agent is limited in how long each step can take to process. )
Full starting code:
from sc2.bot_ai import BotAI # parent class we inherit from from sc2.data import Difficulty, Race # difficulty for bots, race for the 1 of 3 races from sc2.main import run_game # function that facilitates actually running the agents in games from sc2.player import Bot, Computer #wrapper for whether or not the agent is one of your bots, or a "computer" player from sc2 import maps # maps method for loading maps to play in. class IncrediBot(BotAI): # inhereits from BotAI (part of BurnySC2) async def on_step(self, iteration: int): # on_step is a method that is called every step of the game. print(f"This is my bot in iteration {iteration}") # prints out the iteration number (ie: the step). run_game( # run_game is a function that runs the game. maps.get("2000AtmospheresAIE"), # the map we are playing on [Bot(Race.Protoss, IncrediBot()), # runs our coded bot, protoss race, and we pass our bot object Computer(Race.Zerg, Difficulty.Hard)], # runs a pre-made computer agent, zerg race, with a hard difficulty. realtime=False, # When set to True, the agent is limited in how long each step can take to process. )
We can now run everything in a console, for example:
The game should look something like:
This has us at least getting minerals and seeing how a game steps, but eventually the enemy will build up some units to come and defeat us. In the coming tutorials, we'll work on some defense and then some offense to start winning some games.