Skip to main content

2.4 - Your First Hello, World Bot

In programming, a "Hello, World!" application is the simplest possible program that proves a new system is working. Our goal here is the same: we will build a bot that does nothing in-game but prints messages to your console.

This exercise will teach you the fundamental structure and lifecycle of every bot you will build from now on.

Chapter Checklist

  • Task 1: Create the Python file for the HelloBot.
  • Task 2: Understand the bot's lifecycle diagram.
  • Task 3: Run the bot and observe the output.
  • Task 4: Verify that the bot completes its full lifecycle.

The Bot's Lifecycle

Every python-sc2 bot follows a simple, predictable lifecycle. Understanding this flow is the key to knowing where to place your code.

(Game Starts)
|
v
[ on_start() ] <-- Runs ONCE at the beginning for setup.
|
|--------------------------.
| |
v | (Loop)
[ on_step() ] <-- Runs REPEATEDLY, many times per second.
| |
'--------------------------'
|
v
[ on_end() ] <-- Runs ONCE after the game has finished.
|
v
(Game Ends)

Step 1: The Code

Create a new file named hello_bot.py and paste the following code into it.

# hello_bot.py

# =================================================================
# IMPORTS: We are importing necessary components from the sc2 library
# =================================================================
from sc2.main import run_game # The function that starts the game
from sc2 import maps # The function for loading maps
from sc2.bot_ai import BotAI # The base class for our bot
from sc2.player import Bot, Computer # Defines the players in the game
from sc2.data import Difficulty, Race # Defines race and game difficulty


class HelloBot(BotAI):
"""A bot to demonstrate the fundamental lifecycle."""

async def on_start(self):
"""Runs once, at the start of the game."""
print("Lifecycle: on_start() - Game has begun!")

async def on_step(self, iteration: int):
"""Runs on every game step (frame)."""
if iteration % 200 == 0:
# Print a message every 200 steps to show this is looping.
print(f"Lifecycle: on_step() - Iteration: {iteration}")

async def on_end(self, game_result: Result):
"""Runs once, after the game is over."""
print("Lifecycle: on_end() - Game has finished!")
print(f"The game result was: {game_result}")


if __name__ == "__main__":
main.run_game(
maps.get("AbyssalReefLE"),
[
Bot(Race.Terran, HelloBot()),
Computer(Race.Zerg, Difficulty.Hard), # Add an AI to ensure the game ends.
],
realtime=False, # Run as fast as possible.
save_replay_as="HelloBotReplay.SC2Replay",
)


Step 2: Anatomy of the Bot

This code has two main parts: the bot's "brain" (the HelloBot class) and the "launcher" (main.run_game). Let's dissect the brain.

ComponentCodeRole
The Bot Classclass HelloBot(BotAI):This is the blueprint for your bot. It inherits all the core capabilities from the library's BotAI class.
The Setup Methodasync def on_start(self):This is your bot's constructor. It's the perfect place for setup logic that only needs to run once.
The Main Loopasync def on_step(self, ...):This is the heart of the bot. Almost all your decision-making logic (to build, fight, or expand) will live here.
The Cleanup Methodasync def on_end(self, ...):This is your bot's destructor. It's ideal for post-game analysis or saving learned data. The game_result tells you if you won or lost.

Step 3: Execution and Verification

  1. Activate your virtual environment. (venv)
  2. Run the script from your terminal.
    python hello_bot.py

Expected Outcome:

Because we set realtime=False and added an opponent, the game will run very quickly and you won't see much on screen. The important part is the output in your terminal. You will see messages appear in a specific order, proving the lifecycle works as expected.

Lifecycle: on_start() - Game has begun!
Lifecycle: on_step() - Iteration: 0
Lifecycle: on_step() - Iteration: 200
Lifecycle: on_step() - Iteration: 400
...
Lifecycle: on_end() - Game has finished!
The game result was: Result.Victory

Congratulations. You have successfully created a bot and verified its core execution lifecycle. You are now ready to add actions inside this structure.