Getting started with BWAPI
After you’ve been modding games for awhile you might be tempted to dip your feet into doing some Artificial Intelligence (AI) programming. But where to start? There’s dozens of books, libraries and information available.
Do you write an AI module for a specific engine? A specific game? What if that game has no easily accessible API or scripting language available? Now what? Well that’s where the BWAPI project comes in. BWAPI allows you to write a custom AI or Bot for Blizzard’s classic RTS StarCraft BroodWar.
I first noticed the BWAPI project a number of years back and while it showed promise back then, it was riddled with bugs and I was never able to get it to successfully run. However now the project is mature, stable and runs like a dream.
So let’s jump straight in!
NB: As far as I know BWAPI is only compatible with BroodWar version: 1.16.1. I did not test it on any other versions but if you encounter issues make sure you’re using that exact version.
If you’re using Visual Studio 2017 like me you must rebuild the project from source. Grab the source from here. Or simply clone the repo using git:
git clone https://github.com/bwapi/bwapi
Once you’ve got it downloaded open bwapi.sln and make sure you specify a release build.
Don’t forget to re-target for Windows 10:
Right Click Solution -> Retarget Solution
Now build the solution. It’s quite big and if your PC is a potato like mine it’ll take several minutes to build. Once the project has built successfully we need to setup StarCraft so we can load our AI modules.
I don’t think so, Admiral. You see, at this point, I’m pretty much the Queen Bitch of the Universe. And not all of your little soldiers or space ships will stand in my way again. -Kerrigan
Create a new folder called bwapi-data in the root of your game install path i.e:
Now create a subfolder called AI:
Once that is done you’ll need to copy BWAPI.dll and ExampleAIModule.dll from your release directory into the bwapi-data directory. Make sure the AI Module is inside the AI folder.
Now you just need to create a basic config file for BWAPI. The full list of options is available here or you can just use my config file here:
[ai] ; Paths and revisions for AI ; - Use commas to specify AI for multiple instances. ; - If there are more instances than the amount of ; DLLs specified, then the last entry is used. ; - Example: SomeAI.dll, SecondInstance.dll, ThirdInstance.dll ; - Absolute paths are acceptable. ai = bwapi-data/AI/ExampleAIModule.dll ai_dbg = bwapi-data/AI/ExampleAIModuled.dll ; Used only for tournaments ; Tournaments can only be run in RELEASE mode tournament = [auto_menu] ; auto_menu = OFF | SINGLE_PLAYER | LAN | BATTLE_NET ; for replays, just set the map to the path of the replay file auto_menu = SINGLE_PLAYER ; character_name = FIRST | WAIT | <other> ; if FIRST (default), use the first character in the list ; if WAIT, stop at this screen ; else the character with the given value is used/created character_name = FIRST ; pause_dbg = ON | OFF ; This specifies if auto_menu will pause until a debugger is attached to the process. ; Only works in DEBUG mode. pause_dbg = OFF ; lan_mode = Same as the text that appears in the multiplayer connection list ; Examples: Local Area Network (UDP), Local PC, Direct IP lan_mode = Local Area Network (UDP) ; auto_restart = ON | OFF ; if ON, BWAPI will automate through the end of match screen and start the next match ; if OFF, BWAPI will pause at the end of match screen until you manually click OK, ; and then BWAPI resume menu automation and start the next match auto_restart = OFF ; map = path to map to host relative to Starcraft folder, i.e. map = maps/(2)Boxer.scm ; leaving this field blank will join a game instead of creating it ; The filename(NOT the path) can also contain wildcards, example: maps/(?)*.sc? ; A ? is a wildcard for a single character and * is a wildcard for a string of characters map = maps/(?)*.sc? ; game = name of the game to join | JOIN_FIRST ; i.e. game = BWAPI will join the game called "BWAPI" ; and game = JOIN_FIRST will join the first game in the list. ; If the game does not exist and the "map" entry is not blank, then the game will be created instead ; If this entry is blank, then it will follow the rules of the "map" entry game = ; mapiteration = RANDOM | SEQUENCE ; type of iteration that will be done on a map name with a wildcard mapiteration = RANDOM ; race = Terran | Protoss | Zerg | Random ; - Use commas to specify race for each AI module when running multiple instances. ; - If there are more instances than the amount of ; races specified, then the last entry is used. ; - To be used in conjunction with multiple AI modules ; - Example: Terran, Protoss, Terran, Zerg race = Terran ; enemy_count = 1-7, for 1v1 games, set enemy_count = 1 ; only used in single player games enemy_count = 1 ; enemy_race = Terran | Protoss | Zerg | Random | RandomTP | RandomTZ | RandomPZ | RandomTPZ ; only used in single player games enemy_race = Random ; enemy_race_# = Default ; Values for enemy_race are acceptable, Default will use the value specified in enemy_race enemy_race_1 = Default enemy_race_2 = Default enemy_race_3 = Default enemy_race_4 = Default enemy_race_5 = Default enemy_race_6 = Default enemy_race_7 = Default ;game_type = TOP_VS_BOTTOM | MELEE | FREE_FOR_ALL | ONE_ON_ONE | USE_MAP_SETTINGS | CAPTURE_THE_FLAG ; | GREED | SLAUGHTER | SUDDEN_DEATH | TEAM_MELEE | TEAM_FREE_FOR_ALL | TEAM_CAPTURE_THE_FLAG game_type = MELEE ; game_type_extra = Text that appears in the drop-down list below the Game Type drop-down list. ; If empty, the Starcraft default will be used. ; The following are the game types that use this setting, and corresponding example values ; TOP_VS_BOTTOM 3 vs 1 | 2 vs 2 | 1 vs 3 | # vs # ; GREED 2500 | 5000 | 7500 | 10000 ; SLAUGHTER 15 | 30 | 45 | 60 ; TEAM_MELEE 2 | 3 | 4 | 5 | 6 | 7 | 8 ; TEAM_FREE_FOR_ALL 2 | 3 | 4 | 5 | 6 | 7 | 8 ; TEAM_CAPTURE_THE_FLAG 2 | 3 | 4 | 5 | 6 | 7 | 8 game_type_extra = ; save_replay = path to save replay to ; Accepts all environment variables including custom variables. See wiki for more info. save_replay = maps/replays/%BOTNAME6%/$Y $b $d/%MAP%_%BOTRACE%%ALLYRACES%vs%ENEMYRACES%_$H$M$S.rep ; wait_for_min_players = # ; # of players to wait for in a network game before starting. ; This includes the BWAPI player. The game will start immediately when it is full. wait_for_min_players = 2 ; wait_for_max_players = # ; Start immediately when the game has reached # players. ; This includes the BWAPI player. The game will start immediately when it is full. wait_for_max_players = 8 ; wait_for_time = # ; The time in milliseconds (ms) to wait after the game has met the min_players requirement. ; The game will start immediately when it is full. wait_for_time = 60000 [config] ; holiday = ON | OFF ; This will apply special easter eggs to the game when it comes time for a holiday. holiday = ON ; shared_memory = ON | OFF ; This is specifically used to disable shared memory (BWAPI Server) in the Windows Emulator "WINE" ; Setting this to OFF will disable the BWAPI Server, default is ON shared_memory = ON ; console_* = TRUE | FALSE ; Used for getting a console for displaying text written to stdout and stderr, and read from stdin. ; console_attach_* ; Allows BWAPI to attach to the parent process' console. i.e. if the parent ; has a console, output will be displayed on that console, and that console ; also kept open even if the parent dies. ; console_alloc_* ; Allows BWAPI to allocate it's own system console window. Not executed if ; corresponding console_attach_* is enabled and succeeds. ; console_*_on_startup ; Executes when BWAPI.dll is first attached to Starcraft. ; console_*_auto ; Executes when something is written to std::cout or std::cerr, ; and no console was successfully attached/allocated on startup. console_attach_on_startup = FALSE console_alloc_on_startup = FALSE console_attach_auto = TRUE console_alloc_auto = TRUE [window] ; These values are saved automatically when you move, resize, or toggle windowed mode ; windowed = ON | OFF ; This causes BWAPI to enter windowed mode when it is injected. windowed =ON ; left, top ; Determines the position of the window left =313 top =102 ; width, height ; Determines the width and height of the client area and not the window itself width =640 height =480 [starcraft] ; Game sound engine = ON | OFF sound = ON ; Screenshot format = gif | pcx | tga | bmp screenshots = gif ; Random seed override. This uses a fixed seed at the start of the game so that if played out the exact same way, ; the same occurrences will happen every time. This value must be a decimal integer. ; ; When this key is commented out, Starcraft will use the system time as a seed. This is the default behaviour. ; ; Note: This option affects both single AND multi-player modes (for game hosts only). This means that hosting a multi-player ; game with this option enabled will distribute this fixed seed to all other players in the game. ;seed_override = 123456789 ; Speed override. This overrides the default game speed setting and prevents bots from changing the game speed. ; Enabling this option causes it to take effect. The value is the number of milliseconds per frame. A negative ; value uses the game's default speed value. ;speed_override = -1 ; drop_players = ON | OFF ; This specifies if BWAPI should drop other players from the game when the timeout dialog reaches 0. Players ; usually time out when there are connection issues or their client is not responding. Setting this to OFF ; will cause BWAPI to wait an infinite amount of time until the player reconnects. drop_players = ON
Now download ChaosLauncher and copy BWAPI_PluginInjector.dll to its directory making sure to rename its extension to *.bwl.
One you’ve got Chaos up and running it should ask you to set the StarCraft install path under settings.
Then make sure you’ve got everything configured as below:
Once this is done you should be ready. Chaos may complain about not being able to set debug privileges however this did not seem to affect anything on my system. If you have issues trying running Chaos as with elevated privileges.
If you used my configuration settings the game will automatically start a 1 v 1 melee match the selected race as Terran. You can then watch the example AI build nothing but SCVs and Supply Depots and promptly get ground into dust by the normal StarCraft AI, hilarious.
From here you can head back over to Visual Studio and inspect the Example AI module to see how it works. The API is pretty straight forward and available for viewing here. There’s also quite a few BWAPI AI projects floating around on github.
That’s all for now! Remember to share this article with your friends. Follow me on Twitter or Facebook to get notifications when new content is available. Or even show some support by becoming a Patreon!