# python-sc2: a StarCraft II API client that fits a worker rush in twenty lines

> burnysc2 is a Python 3 client for the StarCraft II scripted interface, packaged as the sc2 library, with a fork of Dentosal's original that trades some backward compatibility for speed and a lower level of abstraction. It ships the protocol client, the game state model and a plugin ecosystem, and it talks to a real game install rather than to a simulator.

**BurnySc2/python-sc2** — A StarCraft II bot api client library for Python 3

- Repository: https://github.com/BurnySc2/python-sc2
- Stars: 638 · Forks: 190
- Language: Python
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/burnysc2-python-sc2

## The promise is a simple API, and the fork trades compatibility for speed

python-sc2 is described as an easy-to-use library for writing AI bots for StarCraft II in Python 3, with the ultimate goal being simplicity and ease of use while still preserving all functionality. The concrete measure of that goal is given: a really simple worker rush bot should be no more than twenty lines of code, not two hundred. The library also intends to provide both high and low level abstractions.

One boundary is stated up front. This library, currently, covers only the raw scripted interface, and the author does not intend to add support for graphics-based interfaces. That is a meaningful narrowing, and it is a deliberate one, because the scripted interface is what makes the library fast and scriptable rather than a screen-reading wrapper.

The project is a fork. It was originally Dentosal's python-sc2, and the author plans to change this fork more radically than the main repository, for bot performance benefits and to add functions that help new bot authors. The consequence is stated plainly: this may break older bots in the future, although deprecation warnings are added to give a heads up. A named consequence follows, that the video tutorial made by sentdex is outdated and no longer directly works with this fork.

There is an issue tracking the ongoing changes and differences to the main repository, linked from the README as the place to check.

The primary language is Python and the licence in the package metadata is MIT. The default branch is develop, the last push was on 2026-04-25, and the package version is 7.3.0.

## A worker rush in twenty lines is the whole API in miniature

The example the README leads with is the clearest statement of the design, and it is worth reading closely because everything in the library is arranged to make this short.

```python
from sc2 import maps
from sc2.player import Bot, Computer
from sc2.main import run_game
from sc2.data import Race, Difficulty
from sc2.bot_ai import BotAI

class WorkerRushBot(BotAI):
    async def on_step(self, iteration: int):
        if iteration == 0:
            for worker in self.workers:
                worker.attack(self.enemy_start_locations[0])

run_game(maps.get("Abyssal Reef LE"), [
    Bot(Race.Zerg, WorkerRushBot()),
    Computer(Race.Protoss, Difficulty.Medium)
], realtime=True)
```

Six lines of bot, three of setup. The shape tells you the layering. run_game takes a map and a list of players. A player is either a Bot with a race and a BotAI instance, or a Computer with a race and a difficulty. The bot itself is a class that subclasses BotAI and implements an async on_step method which receives the current iteration number.

Inside on_step, the state is already there. self.workers is a collection of your own workers, and self.enemy_start_locations[0] is a position, so worker.attack takes the position and the action is queued for the game to carry out. The bot never talks to the game protocol directly; it only reads the state and issues actions.

The author is honest about the quality of that particular bot, calling it probably the simplest bot that has any realistic chances of winning the game, and saying they have run it against the medium AI a few times and once in a while it wins.

The examples directory shows the range of what the library supports. There are examples per race, with protoss, terran and zerg subdirectories, plus arcade_bot.py, bot_vs_bot.py, distributed_workers.py, external_bot.py, fastreload.py, host_external_norestart.py, observer_easy_vs_easy.py, play_tvz.py, simulate_fight_scenario.py, too_slow_bot.py, watch_replay.py, worker_rush.py and worker_stack_bot.py. A competitive/ directory and a separate one for running several bots against each other.

## The performance knobs are the fork's main contribution

The API configuration section is where the fork earns its keep, and it is short. Three settings are documented, and each one is a concrete trade.

The first is unit_command_uses_self_do, set when your bot issues commands using self.do(Unit(Ability, Target)) instead of Unit(Ability, Target). It is a compatibility switch rather than an optimisation, and it exists because the fork changed the calling convention and a bot written the old way needs to opt back in.

```python
class MyBot(BotAI):
    def __init__(self):
        self.unit_command_uses_self_do = True
```

The second is raw_affects_selection, which the documentation says improves bot performance by a little bit.

```python
class MyBot(BotAI):
    def __init__(self):
        self.raw_affects_selection = True
```

The third is distance_calculation_method, with three values: 0 for raw Python, 1 for scipy pdist and 2 for scipy cdist.

```python
class MyBot(BotAI):
    def __init__(self):
        self.distance_calculation_method: int = 2
```

That third one is the most consequential for a bot author, because distance queries are the hot path in any bot deciding what to attack. Choosing the scipy implementation moves the work into compiled code, and choosing between pdist and cdist is a decision about what shape of distance you actually need.

The dependency list backs the picture up. The package requires aiohttp for the protocol connection, loguru for logging, mpyq, portpicker for the local port the game instance listens on, pys2clientprotocol for the StarCraft II client protocol itself, and numpy and scipy with version markers per Python version, so a 3.14 install gets a newer numpy and scipy than a 3.12 install.

The two examples that best show the library's range are distributed_workers.py, which is about running several workers, and watch_replay.py, for replay watching. A bot framework that can drive distributed workers and consume replays is a research tool, not just a game AI kit.

## Connecting to the game means connecting to a real install

This is where the library differs from a simulator, and it is where most of the setup friction lives.

You need a StarCraft II executable. On Windows and macOS you install it from the Blizzard app. On Linux the options are Wine, Lutris, or the Linux binary from the s2client-proto project, with the note that the latter is headless so you cannot actually see the game. With Lutris, StarCraft II can be directly installed from Battlenet once it has been downloaded.

The environment variables configure the connection, and they are the same on every platform.

```
SC2PF=WineLinux
WINE=/usr/bin/wine
# Or a wine binary from lutris:
# WINE=/home/burny/.local/share/lutris/runners/wine/lutris-4.20-x86_64/bin/wine64
# Default Lutris StarCraftII Installation path:
SC2PATH='/home/burny/Games/battlenet/drive_c/Program Files (x86)/StarCraft II/'
```

WSL gets special handling. The library detects WSL by default and starts the Windows StarCraft II rather than a Linux one, and you disable that by setting SC2_WSL_DETECT to "0", either as an environment variable or in Python before the connection.

```py
import os
os.environ["SC2_WSL_DETECT"] = "0"
```

Under WSL version 1 no configuration is needed, though you may be asked to allow Python through the firewall. Under WSL version 2 you have to supply the client and server hosts.

```
SC2CLIENTHOST=<your windows IP>
SC2SERVERHOST=0.0.0.0
```

If you put them in your .bashrc you may need to export them.

```sh
export SC2CLIENTHOST
export SC2SERVERHOST
```

The Windows IP is found with ipconfig /all from PowerShell.exe or CMD.exe. This networking detail is the one that catches people out, because the WSL version decides whether the local address works.

## Maps have to be in the right directory or ladder replays fail

The maps section looks like housekeeping and is not, because where a map file sits changes whether the library can use it.

Official Blizzard map downloads come from the s2client-proto project and go into their respective subdirectories in the SC2 maps directory, for example install-dir/Maps/Ladder2017Season1/.

Maps run on the SC2 AI Arena Ladder come from the AI Arena wiki, and those go into the root of the SC2 maps directory instead. The documentation is explicit that this is otherwise where ladder replays will not work, and the example given is install-dir/Maps/AcropolisLE.SC2Map.

So the two sources have different destination rules, and the reason is that the library looks up maps by path depending on how the map is being used. Official maps are matched by their ladder subdirectory structure, while a ladder map is matched by file name in the root.

Once the library, the executable and the maps are in place, running a bot is one command, and it starts an instance of StarCraft II with the bot running inside it.

```sh
python examples/protoss/cannon_rush.py
```

The repository also carries the machinery for the data the library needs. There is a data/ directory, and two generator scripts at the root, generate_dicts_from_data_json.py and generate_id_constants_from_stableid.py, which produce the lookup tables for unit ids and other constants. A docs_generate/ directory, a test/ directory, a dockerfiles/ directory and a pyproject.toml with a uv.lock complete the tree.

The AI and Machine Learning License question deserves attention before you install. The README states that by installing this library you agree to be bound by the terms of the AI and Machine Learning License, and it links to the terms hosted on a distribution CDN. The package metadata lists an MIT license with the LICENSE file, so the licensing picture for the code and for the StarCraft II interaction is stated separately, and a company reviewing this needs to read both.

## Where python-sc2 is the wrong tool

The first wrong-tool case is anything that needs to read the screen. The library covers the raw scripted interface only, and the author has no intention of adding graphics-based support. A project that has to perceive the game visually rather than through the game's own scripting API is outside its scope, and no amount of configuration changes that.

The second case is a team that needs long-term API stability. The fork is explicitly planning more radical changes than the upstream repository, and it is candid that this may break older bots. The named casualty is the sentdex video tutorial, which no longer works directly with this fork. A project whose bot is a long-lived asset has to weigh that against the performance gains, and the issue tracking the differences is where that work goes.

The third case is a Windows-only or Linux-only deployment that expects a single path. The WSL story has version-specific behaviour, and the Linux story depends on Wine or Lutris and a set of environment variables that have to be right per machine. The library handles the protocol, but the connection setup is still yours, and a fleet of bots across machines means configuring SC2PF, WINE, SC2PATH, SC2CLIENTHOST and SC2SERVERHOST correctly on each one.

A fourth case is a project that wants a simulator. The library launches a real game install, so running a bot at scale means running that many game instances, with the memory and CPU cost that implies. The simulate_fight_scenario.py example exists for a specific scenario rather than replacing the game.

What the fork gives you in exchange is a protocol layer written for performance, a game state model that exposes workers, units and positions directly, and a plugin ecosystem. The sc2 folder files named in the README, bot_ai.py, unit.py, units.py, client.py, game_info.py and game_state.py, are the ones to read, since the documentation says looking directly at them can benefit bot authors and that most functions in them have docstrings, example usages and type hinting.

The audience is a Python developer building a StarCraft II bot, and the project is MIT licensed with the license files in the repository root.

## Conclusion

burnysc2 suits a Python developer writing a StarCraft II bot who wants the protocol layer handled and a twenty line example to start from, and the fork's performance work is the reason to choose it over the upstream client. It does not suit a project that needs the graphics-based interface, because the library covers only the raw scripted interface and the author does not intend to add graphics support. Before adopting, read the fork's issue on ongoing differences with the main repository, decide whether the breakages to older bots are acceptable, and expect to read the sc2 folder source directly, since the documented path for bot authors is to look at the files rather than the API reference.

## FAQ

### How do I install python-sc2?

Install the PyPI package with pip install --upgrade burnysc2, or install from the develop branch with pip install --upgrade --force-reinstall https://github.com/BurnySc2/python-sc2/archive/develop.zip. The fork needs Python 3.9 or newer, and both commands use the sc2 library folder, so Dentosal's version cannot be installed at the same time without virtual environments.

### What is the difference between burnysc2 and the original python-sc2?

The fork plans more radical changes than the main repository, aimed at bot performance and at adding functions for new bot authors, and the README warns that this may break older bots in the future. It adds deprecation warnings as a heads up, and a separate issue tracks the ongoing changes and differences to the main repository of Dentosal.

### Does python-sc2 work with graphics-based interfaces?

No. The README states that the library currently covers only the raw scripted interface and that the author does not intend to add support for graphics-based interfaces.

### What do I need to run a python-sc2 bot?

A StarCraft II executable, which on Linux you install with Wine, Lutris or the headless Linux binary, plus maps in the correct SC2 maps directory. Official maps go into their subdirectories while AI Arena ladder maps go into the root, otherwise ladder replays will not work.

### How do I run a python-sc2 bot under WSL?

The library detects WSL and starts the Windows game by default, and you set SC2_WSL_DETECT to "0" to use the Linux game instead. Under WSL version 2 you also need SC2CLIENTHOST set to your Windows IP and SC2SERVERHOST set to 0.0.0.0, exported if they live in your .bashrc.

## Sources

- [BurnySc2/python-sc2 on GitHub](https://github.com/BurnySc2/python-sc2)
- [Issues](https://github.com/BurnySc2/python-sc2/issues)
- [License: MIT](https://github.com/BurnySc2/python-sc2/blob/develop/LICENSE)
- [README](https://github.com/BurnySc2/python-sc2/blob/develop/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/burnysc2-python-sc2
