### Duplicate Command Examples Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/build_runner.md Examples of using multipliers to repeat build order commands. ```yml - 12 worker x3 ``` ```yml - 12 pylon @ ramp *5 ``` ```yml - 15 barracks ramp *2 ``` ```yml - 42 roach *16 ``` -------------------------------- ### Show Installed Dependencies Source: https://github.com/aressc2/ares-sc2/blob/main/docs/contributing/index.md Lists all dependencies currently installed in the Poetry environment. ```bash poetry show ``` -------------------------------- ### Install Dependencies from Lock File Source: https://github.com/aressc2/ares-sc2/blob/main/docs/contributing/index.md Installs all project dependencies based on the versions specified in the poetry.lock file. Creates a virtual environment if one doesn't exist. ```bash poetry install ``` -------------------------------- ### AddOnSwap Command Examples Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/build_runner.md Examples of using the addonswap command to steal structure addons. ```yml - 22 addonswap factory barracksreactor ``` ```yml - 22 addonswap starport factorytechlab ``` ```yml OneOneOneReaperHellion: ConstantWorkerProductionTill: 30 OpeningBuildOrder: - 14 supply @ ramp - 16 barracks @ ramp - 16 gas - 0 orbital - 0 reaper - 19 expand - 20 marine - 21 factory @ ramp - 21 gas - 21 barracksreactor - 21 supply *2 - 21 orbital - 21 starport - 21 addonswap factory barracksreactor ``` -------------------------------- ### Chronoboost Command Examples Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/build_runner.md Examples of targeting structures for Chronoboost. ```yml - 13 chrono @ nexus - 16 chrono @ gateway - 20 chrono @ cyberneticscore ``` -------------------------------- ### Natural Wall Placement Example Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Example of a raw coordinate list for a natural wall placement. ```text - [[ 138.0, 76.0 ]] ``` -------------------------------- ### BuildRunner Configuration with Custom Placements Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Example of a build order file using @ nat_wall and @ reaper_wall tags to specify placement locations. ```yml UseData: True # How should we choose a build? Cycle is the only option for now BuildSelection: Cycle # For each Race / Opponent ID choose a build selection BuildChoices: # test_123 is active if Debug: True (set via a `config.yml` file) test_123: BotName: Test Cycle: - DummyBuild Protoss: BotName: ProtossRace Cycle: - DummyBuild Random: BotName: RandomRace Cycle: - DummyBuild Terran: BotName: TerranRace Cycle: - DummyBuild Zerg: BotName: ZergRace Cycle: - DummyBuild Builds: DummyBuild: ConstantWorkerProductionTill: 44 AutoSupplyAtSupply: 23 OpeningBuildOrder: - 14 pylon @ nat_wall - 15 gate @ nat_wall - 16 gate @ nat_wall - 16 core @ nat_wall - 16 pylon @ nat_wall - 16 shieldbattery @ nat_wall # build the reaper wall - 16 pylon @ reaper_wall - 16 gate @ reaper_wall - 16 gate @ reaper_wall ``` -------------------------------- ### Define Build Runner Configuration Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/build_runner.md Example of a protoss_builds.yml file defining build selection strategies and specific build order sequences. ```yaml # Save the game opening and result to disk? # Setting to `True` allows Ares to select a new opening after defeat UseData: True # How should we choose a build? # Cycle simply switches on defeat # WinrateBased uses winrates to select a build BuildSelection: Cycle # if chosen by WinrateBased, how many games must be played # will use Cycle method while building data MinGamesWinrateBased: 3 # For each Race / Opponent ID choose a build selection BuildChoices: # test_123 is active if Debug: True (set via a `config.yml` file) test_123: BotName: Test Cycle: - FastExpand Protoss: BotName: ProtossRace Cycle: - FastExpand - WorkerBuild Random: BotName: RandomRace Cycle: - FastExpand Terran: BotName: TerranRace Cycle: - FastExpand Zerg: BotName: ZergRace Cycle: - FastExpand - WorkerBuild # Can also use specific opponent ids (overrides race options above) a_bot_opponent_id_from_aiarena: BotName: QueenBot Cycle: - FastExpand Builds: WorkerBuild: ConstantWorkerProductionTill: 22 OpeningBuildOrder: - 12 chrono @ nexus - 14 pylon @ ramp - 16 gateway FastExpand: ConstantWorkerProductionTill: 0 OpeningBuildOrder: ['12 worker', '13 worker', '14 supply', '14 worker', '14 chrono @ nexus', '15 worker', '15 gateway', '16 worker', '17 expand', '17 worker', '17 zealot'] ``` -------------------------------- ### Add Dependency with Poetry Source: https://github.com/aressc2/ares-sc2/blob/main/docs/contributing/index.md Installs a new dependency into the Poetry-managed project. Example adds 'burnysc2'. ```bash poetry add burnysc2 ``` -------------------------------- ### Configure Build Orders with YAML Source: https://context7.com/aressc2/ares-sc2/llms.txt Configure build orders for the early game using YAML files. This example shows Protoss build configurations including supply timings, worker production, and opening build steps. ```yaml # protoss_builds.yml UseData: True BuildSelection: Cycle MinGamesWinrateBased: 3 BuildChoices: Protoss: BotName: MyProtossBot Cycle: - FastExpand - WorkerRush Terran: BotName: MyProtossBot Cycle: - FastExpand Zerg: BotName: MyProtossBot Cycle: - FastExpand Builds: FastExpand: AutoSupplyAtSupply: 17 ConstantWorkerProductionTill: 50 OpeningBuildOrder: - 14 pylon @ ramp - 15 worker_scout: [spawn, nat, enemy_spawn, third, fourth] - 16 gateway - 16 gas - 17 gas - 19 gateway - 20 core - 22 adept x2 - 25 expand - 26 stargate WorkerRush: ConstantWorkerProductionTill: 0 OpeningBuildOrder: - 12 worker - 13 worker - 14 pylon @ ramp - 15 gateway ``` -------------------------------- ### Show Outdated Dependencies Source: https://github.com/aressc2/ares-sc2/blob/main/docs/contributing/index.md Lists installed dependencies along with their latest available versions. ```bash poetry show -l ``` -------------------------------- ### Custom Protoss Building Placements YAML Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Example configuration file for overriding specific building positions on the Persephone map. ```yml Persephone: UpperSpawn: FirstPylon: [ [ 68.0, 143.0 ] ] LowerSpawn: FirstPylon: [ [ 68.0, 36.0 ] ] ``` -------------------------------- ### Configure AutoSupply Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/build_runner.md Example of enabling AutoSupply at a specific supply count to automate supply structure construction. ```yml Builds: DummyBuild: # After 17 supply turn AutoSupply on AutoSupplyAtSupply: 17 ConstantWorkerProductionTill: 50 OpeningBuildOrder: - 14 pylon @ ramp - 15 worker_scout: [spawn, nat, enemy_spawn, third, fourth, map_center, enemy_nat] - 16 gate - 16 gas - 17 gas - 19 gate - 20 core - 22 adept x2 - 25 stargate ``` -------------------------------- ### Get Units from Multiple Roles Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/assigning_unit_roles.md This function allows you to retrieve units that belong to any of the specified roles, combining units from HARASSING and DROP_UNITS_ATTACKING roles in this example. ```python self.mediator.get_units_from_roles( roles={UnitRole.HARASSING, UnitRole.DROP_UNITS_ATTACKING} ) ``` -------------------------------- ### Retrieve Opening Build Name Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/build_runner.md Method call to get the name of the currently selected build. ```python self.build_order_runner.chosen_opening ``` -------------------------------- ### Switch Unit Roles Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/assigning_unit_roles.md This snippet shows how to switch units from one role to another, for example, from ATTACKING to DEFENDING. ```python self.mediator.switch_roles( from_role=UnitRole.ATTACKING, to_role=UnitRole.DEFENDING ) ``` -------------------------------- ### Install Dependencies Excluding Dev Tools Source: https://github.com/aressc2/ares-sc2/blob/main/docs/contributing/index.md Installs project dependencies, excluding those specified for development or linting purposes. ```bash poetry install --without lint ``` -------------------------------- ### Build Gateway and Cybernetics Core at Natural Wall Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Use BuildStructure to construct gateways and a cybernetics core at the natural expansion wall. Ensure correct base location and structure IDs are provided. This example attempts to build two gateways and one cybernetics core. ```python from sc2.ids.unit_typeid import UnitTypeId # attempt to build two gateway and cybernetics core at the natural wall self.register_behavior( BuildStructure( base_location=self.mediator.get_own_nat, structure_id=UnitTypeId.GATEWAY, wall=True, to_count_per_base=2 ) ) self.register_behavior( BuildStructure( base_location=self.mediator.get_own_nat, structure_id=UnitTypeId.CYBERNETICSCORE, wall=True, to_count_per_base=1 ) ) ``` -------------------------------- ### Configure Constant Worker Production Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/build_runner.md Example of setting a supply limit for automatic worker production. ```yml Builds: ProbeMaxout: # After 0 supply turn AutoSupply on AutoSupplyAtSupply: 0 ConstantWorkerProductionTill: 200 OpeningBuildOrder: - 200 gateway ``` -------------------------------- ### Register Build Structure Behavior Source: https://github.com/aressc2/ares-sc2/blob/main/README.md Use the BuildStructure behavior to easily manage building placement for specific structures at game start. Requires importing BuildStructure and UnitTypeId. ```python from ares.behaviors.macro import BuildStructure from sc2.ids.unit_typeid import UnitTypeId self.register_behavior( BuildStructure( base_location=self.start_location, structure_id=UnitTypeId.BARRACKS ) ) ``` -------------------------------- ### Registering Custom Combat Behavior Source: https://context7.com/aressc2/ares-sc2/llms.txt Example of how to integrate a custom combat behavior like SiegeTankDecision into the bot's behavior management system. This snippet shows adding the custom behavior with highest priority, falling back to A-move. ```python # Usage in bot: class MyBot(AresBot): def micro_tanks(self, tanks: Units, target: Point2) -> None: for tank in tanks: maneuver = CombatManeuver() # Custom behavior first (highest priority) maneuver.add(SiegeTankDecision(tank)) # Fallback to a-move maneuver.add(AMove(tank, target)) self.register_behavior(maneuver) ``` -------------------------------- ### Get Production Placements at Main Base Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Extract all three-by-three building placements designated for production within the main base. This involves querying the placement dictionary for specific attributes. ```python from ares.consts import BuildingSize from sc2.position import Point2 placements_dict: dict[Point2, dict[BuildingSize, dict]] = self.mediator.get_placements_dict main_base_placements: dict[BuildingSize, dict] = placements_dict[self.start_location] production_placements: list[Point2] = [ placement for placement in main_base_placements[BuildingSize.THREE_BY_THREE] if natural_placements[BuildingSize.THREE_BY_THREE][placement]["production"] ] ``` -------------------------------- ### Integrate SiegeTankDecision into Combat Maneuver Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_behaviors.md This example shows how to import and use the `SiegeTankDecision` behavior within a custom `AresBot`. It adds the custom behavior to an `offensive_attack` maneuver, ensuring it's considered before the default `AMove` behavior. ```python from ares import AresBot from ares.behaviors.combat import CombatManeuver from ares.behaviors.combat.individual import AMove from sc2.ids.unit_typeid import UnitTypeId from sc2.units import Units from sc2.position import Point2 # IMPORT SiegeTankDecision, modify import based on where you saved it from bot.siege_tank_decision import SiegeTankDecision class MyBot(AresBot): MARINE_TANK_TYPES: set[UnitTypeId] = { UnitTypeId.MARINE, UnitTypeId.SIEGETANKSIEGED, UnitTypeId.SIEGETANK } def __init__(self, game_step_override=None): """Initiate custom bot""" super().__init__(game_step_override) async def on_step(self, iteration: int) -> None: await super(MyBot, self).on_step(iteration) if marine_tank_force := self.units(self.MARINE_TANK_TYPES): attack_target = self.enemy_start_locations[0] self._micro_marine_tank(marine_tank_force, attack_target) def _micro_marine_tank(self, units: Units, target: Point2) -> None: for unit in units: # set up a new CombatManeuver for this unit offensive_attack: CombatManeuver = CombatManeuver() # ADD OUR CUSTOM SIEGE BEHAVIOR HERE # Maneuvers should be set up so that higher priority tasks are added first. # If this returns False for a tank, then the # AMove behavior will try to execute an action instead offensive_attack.add(SiegeTankDecision(unit)) # add AMove to this maneuver # AMove always returns True so should typically be added at the end offensive_attack.add(AMove(unit, target)) # register the maneuver so it gets executed self.register_behavior(offensive_attack) ``` -------------------------------- ### Initialize New Poetry Project Source: https://github.com/aressc2/ares-sc2/blob/main/docs/contributing/index.md Initializes a new Python project with Poetry, generating a pyproject.toml file. Use --no-interaction to skip prompts. ```bash poetry init --name ares-sc2 --no-interaction ``` -------------------------------- ### Create and Customize Ground and Air Grids Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/influence_and_pathing.md Demonstrates how to create custom ground and air grids using `SC2MapAnalysis` and modify them by adding cost based on enemy positions and unit stats. These custom grids can then be used for pathfinding. ```python from map_analyzer import MapData from ares import AresBot import numpy as np from sc2.position import Point2 class MyBot(AresBot): async def on_step(self, iteration: int) -> None: # get access to the SC2MapAnalysis library map_data: MapData = self.mediator.get_map_data_object # get a clean ground grid my_ground_grid: np.ndarray = map_data.get_pyastar_grid() # or an air grid if needed my_air_grid: np.ndarray = map_data.get_clean_air_grid() """ Add cost to this grid For this example, let's make the enemy spawn location really dangerous! In effect this will draw a circle (20 radius) around the enemy spawn, and add 100 cost to all tiles in this circle. """ my_ground_grid = map_data.add_cost( position=self.enemy_start_locations[0], radius=20, grid=my_ground_grid, weight=100.5 ) """ In a real world bot, you probably add cost for enemy units, structures and effects, something like: """ radius_buffer: float = 2.0 for unit in self.all_enemy_units: if unit.can_attack_ground: my_ground_grid = map_data.add_cost( position=unit.position, radius=unit.ground_range + radius_buffer, grid=my_ground_grid, weight=unit.ground_dps ) if unit.can_attack_air: my_air_grid = map_data.add_cost( position=self.enemy_start_locations[0], radius=unit.air_range + radius_buffer, grid=my_air_grid, weight=unit.ground_dps ) # now my_ground_grid, my_ground_grid are ready to use # will find the best path to enemy spawn, factoring in enemy cost move_to: Point2 = self.mediator.find_path_next_point( start=self.start_location, target=self.enemy_start_locations[0], grid=my_ground_grid ) """ Use custom grids with any ares method, behavior etc """ ``` -------------------------------- ### Terran Building Placements - General and Race-Specific Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Demonstrates defining building placements for Terran, including general placements using 'VsAll' and race-specific overrides. Supports inline and list-of-lists formats for coordinates. ```yaml Pylon: UpperSpawn: # VsAll means placements apply to all races VsAll: # we can define placements all in line like this BunkersWall: [[ 147.5, 78.5 ]] MissileTurrets: [[ 172.0, 88.0 ]] Production: [[ 170.5, 92.5], [ 165.5, 92.5], [ 160.5, 92.5]] UpgradeStructures: [[ 170.5, 89.5], [ 165.5, 89.5]] SensorTowers: [[ 169.0, 90.0], [ 165.5, 89.5]] # or make a list of lists if you want # to organize placements using comments SupplyDepots: # main base - [[ 169.0, 82.0 ], [ 170.0, 54.0 ], [ 171.0, 86.0 ]] # natural - [[ 138.0, 76.0 ]] SupplyDepotsWall: - [[ 166.0, 90.0 ], [ 166.0, 92.0 ]] # race specific placements can be defined separately # these take priority over the VsAll placements VsZerg: Production: [[ 166.5, 92.5], [ 163.5, 92.5], [ 160.5, 92.5]] SupplyDepots: # main base - [[ 170.0, 92.0 ], [ 171.0, 92.0 ]] # natural - [[ 138.0, 76.0 ]] SupplyDepotsWall: [[ 166.0, 90.0 ], [ 166.0, 92.0 ]] VsProtoss: SupplyDepots: [ [ 105.0, 170.0 ] ] VsTerran: SupplyDepots: [ [ 105.0, 170.0 ] ] VsRandom: SupplyDepots: [ [ 105.0, 170.0 ] ] LowerSpawn: VsAll: BunkersWall: [[ 147.5, 78.5 ]] MissileTurrets: [[ 172.0, 88.0 ]] Production: [[ 170.5, 92.5], [ 165.5, 92.5], [ 160.5, 92.5]] UpgradeStructures: [[ 170.5, 89.5], [ 165.5, 89.5]] SensorTowers: [[ 169.0, 90.0], [ 165.5, 89.5]] SupplyDepots: # main base - [[ 169.0, 82.0 ], [ 170.0, 54.0 ], [ 171.0, 86.0 ]] # natural - [[ 138.0, 76.0 ]] SupplyDepotsWall: - [[ 166.0, 90.0 ], [ 166.0, 92.0 ]] VsZerg: Production: [[ 166.5, 92.5], [ 163.5, 92.5], [ 160.5, 92.5]] SupplyDepots: # main base - [[ 170.0, 92.0 ], [ 171.0, 92.0 ]] # natural - [[ 138.0, 76.0 ]] SupplyDepotsWall: [[ 166.0, 90.0 ], [ 166.0, 92.0 ]] VsProtoss: SupplyDepots: [ [ 105.0, 170.0 ] ] VsTerran: SupplyDepots: [ [ 105.0, 170.0 ] ] VsRandom: SupplyDepots: [ [ 105.0, 170.0 ] ] ``` -------------------------------- ### Define Build Order Options Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/build_runner.md Enumeration of supported build order commands that can be used within the build order list. ```python class BuildOrderOptions(str, Enum): ADDONSWAP = "ADDONSWAP" CANCEL_GAS = "CANCEL_GAS" CHRONO = "CHRONO" CORE = "CORE" GAS = "GAS" GATE = "GATE" EXPAND = "EXPAND" ORBITAL = "ORBITAL" OVERLORD_SCOUT = "OVERLORD_SCOUT" SUPPLY = "SUPPLY" WORKER = "WORKER" WORKER_SCOUT = "WORKER_SCOUT" ``` -------------------------------- ### Starter Bot Directory Structure Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/migrating.md Compares the directory structure of a typical existing bot with the structure after setting up the ares-sc2 bot template. This helps in understanding where to place your bot's code. ```text MyBot └───my_bot │ └───some_folder │ └───another_folder │ └───main.py └───sc2 └───run.py └───ladder.py ``` ```text ares-sc2-bot-template └───ares-sc2 └───bot │ └───main.py └───scripts └───run.py └───ladder.py ``` -------------------------------- ### Organized Supply Depot Placement with Comments Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Illustrates organizing building placements using a list of lists, allowing for comments to categorize different sets of placements. ```yaml SupplyDepots: # main base - [[ 170.0, 92.0 ], [ 171.0, 92.0 ]] ``` -------------------------------- ### Get Current Semantic Release Changelog Source: https://github.com/aressc2/ares-sc2/blob/main/docs/contributing/index.md Fetches the changelog for already released versions. Assumes GitHub Actions is configured. ```bash semantic-release changelog --released ``` -------------------------------- ### List Poetry Environment Full Path Source: https://github.com/aressc2/ares-sc2/blob/main/docs/contributing/index.md Displays the full file system path to the active Poetry virtual environment. ```bash poetry env list --full-path ``` -------------------------------- ### Get Ground Grid via Mediator Source: https://github.com/aressc2/ares-sc2/blob/main/docs/api_reference/manager_mediator.md Access the ground grid information by calling `get_ground_grid` on the mediator. Ensure the mediator is accessible via `self.mediator`. ```python ground_grid: np.ndarray = self.mediator.get_ground_grid ``` -------------------------------- ### Find Next Path Point with Ares Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/influence_and_pathing.md Use `find_path_next_point` when you need only the next point to move along a path. Requires start, target, and grid information. ```python move_to: Point2 = self.mediator.find_path_next_point( start=self.start_location, target=self.enemy_start_locations[0], grid=self.mediator.get_air_grid ) ``` -------------------------------- ### Define Build Order Target Options Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/build_runner.md Enumeration of supported location targets for build commands. ```python class BuildOrderTargetOptions(str, Enum): ENEMY_FOURTH = "ENEMY_FOURTH" ENEMY_NAT = "ENEMY_NAT" ENEMY_NAT_HG_SPOT = "ENEMY_NAT_HG_SPOT" ENEMY_NAT_VISION = "ENEMY_NAT_VISION" ENEMY_RAMP = "ENEMY_RAMP" ENEMY_SPAWN = "ENEMY_SPAWN" ENEMY_THIRD = "ENEMY_THIRD" FIFTH = "FIFTH" FOURTH = "FOURTH" MAP_CENTER = "MAP_CENTER" NAT = "NAT" NAT_WALL = "NAT_WALL" RAMP = "RAMP" SIXTH = "SIXTH" SPAWN = "SPAWN" THIRD = "THIRD" ``` -------------------------------- ### Manage Army Production with SpawnController and ProductionController Source: https://context7.com/aressc2/ares-sc2/llms.txt Automates unit production and building construction based on a defined army composition dictionary. ```python from ares import AresBot from ares.behaviors.macro import ( AutoSupply, BuildWorkers, GasBuildingController, MacroPlan, ProductionController, SpawnController, ) from sc2.ids.unit_typeid import UnitTypeId as UnitID class MyBot(AresBot): @property def viking_tank_composition(self) -> dict: """Define army composition with proportions and priorities. Proportions should add up to 1.0 Priority 0 is highest (resources saved for these units) """ return { UnitID.MARINE: {"proportion": 0.69, "priority": 4}, UnitID.SIEGETANK: {"proportion": 0.13, "priority": 0}, UnitID.VIKINGFIGHTER: {"proportion": 0.16, "priority": 3}, UnitID.RAVEN: {"proportion": 0.02, "priority": 1}, } async def on_step(self, iteration: int) -> None: await super(MyBot, self).on_step(iteration) production_location = self.start_location # Create a macro plan with prioritized behaviors macro_plan: MacroPlan = MacroPlan() # Priority 1: Build supply structures macro_plan.add(AutoSupply(production_location)) # Priority 2: Build workers up to 48 macro_plan.add(BuildWorkers(to_count=48)) # Priority 3: Build gas buildings up to 8 macro_plan.add(GasBuildingController(to_count=8)) # Priority 4: Spawn units based on composition macro_plan.add(SpawnController(self.viking_tank_composition)) # Priority 5: Build production structures and tech macro_plan.add(ProductionController( self.viking_tank_composition, production_location )) # Register the entire plan self.register_behavior(macro_plan) ``` -------------------------------- ### Place Structures with BuildStructure Behavior Source: https://context7.com/aressc2/ares-sc2/llms.txt Handles building placement at specific locations, including support for wall placement and expansion bases. ```python from ares import AresBot from ares.behaviors.macro import BuildStructure from sc2.ids.unit_typeid import UnitTypeId class MyBot(AresBot): async def on_step(self, iteration: int) -> None: await super(MyBot, self).on_step(iteration) # Build a barracks at base with optimal placement self.register_behavior( BuildStructure( base_location=self.start_location, structure_id=UnitTypeId.BARRACKS ) ) # Build pylon at wall self.register_behavior( BuildStructure( base_location=self.start_location, structure_id=UnitTypeId.PYLON, wall=True # Place at wall position ) ) # Build at natural expansion natural = self.mediator.get_own_nat self.register_behavior( BuildStructure( base_location=natural, structure_id=UnitTypeId.GATEWAY ) ) ``` -------------------------------- ### Get Three-by-Three Wall Placements at Natural Base Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Retrieve all three-by-three building placements located at the natural base wall. This filters the raw placement data for wall-specific locations. ```python three_by_threes_at_wall: list[Point2] = [ placement for placement in natural_placements[BuildingSize.TWO_BY_TWO] if natural_placements[BuildingSize.THREE_BY_THREE][placement]["is_wall"] ] ``` -------------------------------- ### Build Supply Depot with Custom Placements Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Build a supply depot using custom placements defined in a separate file by setting `supply_depot=True`. This is specific to Terran and ensures the depot is placed according to predefined configurations. ```python # terran wants to use depot placements they specify in their own file # They should use `supply_depot=True` self.register_behavior( BuildStructure( base_location=self.start_location, structure_id=UnitTypeId.SUPPLYDEPOT, supply_depot=True, ) ) ``` -------------------------------- ### Get Two-by-Two Wall Placements at Natural Base Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Retrieve all two-by-two building placements located at the natural base wall. This involves accessing the raw placement data dictionary and filtering for wall placements. ```python from ares.consts import BuildingSize from sc2.position import Point2 placements_dict: dict[Point2, dict[BuildingSize, dict]] = self.mediator.get_placements_dict natural_placements: dict[BuildingSize, dict] = placements_dict[self.mediator.get_own_nat] two_by_twos_at_wall: list[Point2] = [ placement for placement in natural_placements[BuildingSize.TWO_BY_TWO] if natural_placements[BuildingSize.TWO_BY_TWO][placement]["is_wall"] ] ``` -------------------------------- ### Find Closest Safe Spot with Ares Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/influence_and_pathing.md Locate a nearby safe spot from a given position using `find_closest_safe_spot`. Useful for determining retreat locations. Specify the starting position, grid, and search radius. ```python safe_spot: Point2 = self.mediator.find_closest_safe_spot( from_pos=self.start_location, grid=self.mediator.get_air_avoidance_grid, radius=8 ) ``` -------------------------------- ### Switch build openings at runtime Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/build_runner.md Change the active build opening dynamically; ensure the provided name exists in the YAML configuration to avoid termination. ```python if self.opponent_is_cheesing: self.build_order_runner.switch_opening("DefensiveOpening") ``` -------------------------------- ### Implement a MacroPlan Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/managing_production.md Use MacroPlan to execute multiple macro behaviors in a specific priority order, reducing the need for individual registrations. ```python from ares import AresBot from ares.behaviors.macro import ( AutoSupply, BuildWorkers, GasBuildingController, MacroPlan, ProductionController, SpawnController, ) from sc2.ids.unit_typeid import UnitTypeId as UnitID class TestBot(AresBot): @property def viking_tank(self) -> dict: return { UnitID.MARINE: {"proportion": 0.69, "priority": 4}, UnitID.SIEGETANK: {"proportion": 0.13, "priority": 0}, UnitID.VIKINGFIGHTER: {"proportion": 0.16, "priority": 3}, UnitID.RAVEN: {"proportion": 0.02, "priority": 1}, } async def on_step(self, iteration: int) -> None: await super(TestBot, self).on_step(iteration) production_location = self.start_location macro_plan: MacroPlan = MacroPlan() macro_plan.add(AutoSupply(production_location)) macro_plan.add(BuildWorkers(to_count=48)) macro_plan.add(GasBuildingController(to_count=8)) macro_plan.add(SpawnController(self.viking_tank)) macro_plan.add(ProductionController( self.viking_tank, production_location )) # only need to register once for whole plan self.register_behavior(macro_plan) ``` -------------------------------- ### Implement Basic A-Move Bot Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/assigning_unit_roles.md A standard attack-move implementation using only python-sc2 without ares-sc2 role management. ```python from ares import AresBot from sc2.ids.unit_typeid import UnitTypeId from sc2.position import Point2 from sc2.units import Units class MyBot(AresBot): LING_ROACH_TYPES: set[UnitTypeId] = { UnitTypeId.ZERGLING, UnitTypeId.ROACH } def __init__(self, game_step_override=None): """Initiate custom bot""" super().__init__(game_step_override) async def on_step(self, iteration: int) -> None: await super(MyBot, self).on_step(iteration) if ling_roach_force := self.units(self.LING_ROACH_TYPES): attack_target = self.enemy_start_locations[0] self._micro_ling_and_roaches( ling_roach_force, attack_target ) def _micro_ling_and_roaches( self, ling_roach_force: Units, target: Point2 ) -> None: for unit in ling_roach_force: unit.attack(target) ``` -------------------------------- ### Medivac Mine Drop Combat Maneuver Source: https://github.com/aressc2/ares-sc2/blob/main/README.md Implement a custom combat maneuver for a Medivac to pick up mines, drop them off at an enemy location, and then return to safety. This example demonstrates using CombatManeuver with individual behaviors like PickUpCargo, PathUnitToTarget, and DropCargo. ```python from ares.behaviors.combat import CombatManeuver from ares.behaviors.combat.individual import ( DropCargo, KeepUnitSafe, PathUnitToTarget, PickUpCargo, ) from sc2.unit import Unit from sc2.units import Units import numpy as np class MyBot(AresBot): async def on_step(self, iteration: int) -> None: # retrieve medivac and mines_to_pickup and pass to method # left out here for clarity # mines would require their own behavior self.do_medivac_mine_drop(medivac, mines_to_pickup) def do_medivac_mine_drop( self, medivac: Unit, mines_to_pickup: Units ) -> None: # initialize a new CombatManeuver mine_drop: CombatManeuver = CombatManeuver() # get a grid for the medivac to path on air_grid: np.ndarray = self.mediator.get_air_grid # first priority is picking up units mine_drop.add( PickUpCargo( unit=medivac, grid=air_grid, pickup_targets=mines_to_pickup) ) # if there is cargo, path to target and drop them off if medivac.has_cargo: # path mine_drop.add( PathUnitToTarget( unit=medivac, grid=air_grid, target=self.enemy_start_locations[0], ) ) # drop off the mines mine_drop.add( DropCargo(unit=medivac, target=medivac.position) ) # no cargo and no units to pick up, stay safe else: mine_drop.add( KeepUnitSafe(unit=medivac, grid=air_grid) ) # finally register this maneuver to be executed self.register_behavior(mine_drop) ``` -------------------------------- ### Register Macro Controllers Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/managing_production.md Register SpawnController and ProductionController within the on_step method to manage unit production and infrastructure. ```python from ares import AresBot from ares.behaviors.macro import ProductionController, SpawnController from sc2.ids.unit_typeid import UnitTypeId as UnitID class TestBot(AresBot): @property def viking_tank(self) -> dict: return { UnitID.MARINE: {"proportion": 0.69, "priority": 4}, UnitID.SIEGETANK: {"proportion": 0.13, "priority": 0}, UnitID.VIKINGFIGHTER: {"proportion": 0.16, "priority": 3}, UnitID.RAVEN: {"proportion": 0.02, "priority": 1}, } async def on_step(self, iteration: int) -> None: await super(TestBot, self).on_step(iteration) production_location = self.start_location # production controller self.register_behavior( ProductionController(self.viking_tank, production_location) ) # spawn controller self.register_behavior( SpawnController(self.viking_tank) ) ``` -------------------------------- ### Path Unit to Target Behavior Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/influence_and_pathing.md Implement `PathUnitToTarget` to handle pathing and moving a single unit. Requires the unit, grid, and target position. ```python from ares.behaviors.combat.individual import PathUnitToTarget from ares.behaviors.behavior import Behavior unit: Unit = self.workers[0] path_unit: Behavior = PathUnitToTarget( unit=unit, grid=self.mediator.get_ground_grid, target=self.game_info.map_center ) self.register_behavior(path_unit) ``` -------------------------------- ### Orchestrate A-Move with CombatManeuver Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_behaviors.md Demonstrates using CombatManeuver to register an AMove behavior for a group of marines and tanks. ```python from ares import AresBot from ares.behaviors.combat import CombatManeuver from ares.behaviors.combat.individual import AMove from sc2.ids.unit_typeid import UnitTypeId from sc2.units import Units from sc2.position import Point2 class MyBot(AresBot): MARINE_TANK_TYPES: set[UnitTypeId] = { UnitTypeId.MARINE, UnitTypeId.SIEGETANKSIEGED, UnitTypeId.SIEGETANK } def __init__(self, game_step_override=None): """Initiate custom bot""" super().__init__(game_step_override) async def on_step(self, iteration: int) -> None: await super(MyBot, self).on_step(iteration) if marine_tank_force := self.units(self.MARINE_TANK_TYPES): attack_target = self.enemy_start_locations[0] self._micro_marine_tank(marine_tank_force, attack_target) def _micro_marine_tank(self, units: Units, target: Point2) -> None: for unit in units: # set up a new CombatManeuver for this unit offensive_attack: CombatManeuver = CombatManeuver() # add AMove to this maneuver offensive_attack.add(AMove(unit, target)) # register the maneuver so it gets executed self.register_behavior(offensive_attack) ``` -------------------------------- ### Compact Supply Depot Placement Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Shows a concise way to define building placements by specifying the list of coordinates inline. ```yaml SupplyDepots: [ [ 105.0, 170.0 ] ] ``` -------------------------------- ### Request First Pylon Placement Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Request the first pylon placement from the mediator without reserving it in the building tracker. This allows checking for available placements before committing. ```python from sc2.ids.unit_typeid import UnitTypeId if placement := mediator.request_building_placement( base_location=self.mediator.get_own_nat, structure_type=UnitTypeId.PYLON, first_pylon=self.first_pylon, reserve_placement=False ): pass ``` -------------------------------- ### Publish Semantic Release (No-Op) Source: https://github.com/aressc2/ares-sc2/blob/main/docs/contributing/index.md Simulates the publishing of a release without making actual changes. Useful for testing the release process. Assumes GitHub Actions is configured. ```bash semantic-release publish --noop ``` -------------------------------- ### Register Individual Combat Behavior Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/combat_maneuver_example.md Shows how to register a single combat behavior directly without using the CombatManeuver helper. ```python self.register_behavior(KeepUnitSafe(unit=medivac, grid=air_grid)) ``` -------------------------------- ### Pathfinding with Enemy Influence Grids Source: https://context7.com/aressc2/ares-sc2/llms.txt Utilize pre-configured grids to find paths that avoid enemy influence. Access grids like ground, air, and avoidance for pathfinding decisions. ```python from ares import AresBot from ares.behaviors.combat.individual import PathUnitToTarget, KeepUnitSafe import numpy as np from sc2.position import Point2 from sc2.unit import Unit class MyBot(AresBot): async def on_step(self, iteration: int) -> None: await super(MyBot, self).on_step(iteration) # Available grids with enemy influence: ground_grid: np.ndarray = self.mediator.get_ground_grid air_grid: np.ndarray = self.mediator.get_air_grid climber_grid: np.ndarray = self.mediator.get_climber_grid # For reapers/colossus ground_to_air: np.ndarray = self.mediator.get_ground_to_air_grid avoidance: np.ndarray = self.mediator.get_air_avoidance_grid # Storms, biles, etc. # Find next point in path avoiding enemy influence unit: Unit = self.workers[0] move_to: Point2 = self.mediator.find_path_next_point( start=unit.position, target=self.enemy_start_locations[0], grid=ground_grid ) # Get entire path full_path: list[Point2] = self.mediator.find_raw_path( start=self.start_location, target=self.enemy_start_locations[0], grid=ground_grid ) # Find low priority path (fewer points, good for queuing) sparse_path: list[Point2] = self.mediator.find_low_priority_path( start=self.start_location, target=self.enemy_start_locations[0], grid=air_grid ) # Find closest safe spot for retreat safe_spot: Point2 = self.mediator.find_closest_safe_spot( from_pos=unit.position, grid=ground_grid, radius=15 ) # Check danger level at a position pos: Point2 = unit.position danger_level: float = ground_grid[int(pos[0]), int(pos[1])] is_safe = danger_level <= 1.0 # 1.0 is default safe value ``` -------------------------------- ### Print Current Semantic Release Version Source: https://github.com/aressc2/ares-sc2/blob/main/docs/contributing/index.md Retrieves the current version of the project using semantic-release. Assumes GitHub Actions is configured. ```bash semantic-release print-version --current ``` -------------------------------- ### Configure Debug Options for Building Formations Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Enable debug visualization in config.yml to see custom building placements as white cuboids. ```yaml # other config file content ... Debug: True DebugOptions: ShowBuildingFormation: True ``` -------------------------------- ### Create Basic Bot with AresBot Source: https://context7.com/aressc2/ares-sc2/llms.txt Extends python-sc2's BotAI to provide access to the mediator pattern and behavior registration. Call the parent on_step to run Ares internal managers. Register behaviors like Mining for worker collection. ```python from ares import AresBot from ares.behaviors.macro import Mining from sc2.ids.unit_typeid import UnitTypeId class MyBot(AresBot): def __init__(self, game_step_override=None): """Initiate custom bot""" super().__init__(game_step_override) async def on_step(self, iteration: int) -> None: # Call parent on_step to run ares internal managers await super(MyBot, self).on_step(iteration) # Register mining behavior - handles worker mineral/gas collection self.register_behavior(Mining()) # Access game info via mediator ground_grid = self.mediator.get_ground_grid enemy_units = self.mediator.get_all_enemy( unit_type=UnitTypeId.MARINE ) ``` -------------------------------- ### Configure simple worker scout Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/build_runner.md Use the worker_scout command in a YAML build order to scout the enemy base. ```yaml Builds: DummyBuild: OpeningBuildOrder: - 12 worker_scout ``` -------------------------------- ### Worker Selection for Building Tasks Source: https://context7.com/aressc2/ares-sc2/llms.txt Demonstrates selecting an optimal worker for a building task using `mediator.select_worker`. It filters for healthy workers and assigns the BUILDING role. ```python from ares import AresBot from ares.consts import UnitRole from sc2.unit import Unit class MyBot(AresBot): async def on_step(self, iteration: int) -> None: await super(MyBot, self).on_step(iteration) # Select optimal worker for a task if worker := self.mediator.select_worker( target_position=self.main_base_ramp.top_center, min_health_perc=0.5 # Only healthy workers ): # Assign role and give command self.mediator.assign_role(tag=worker.tag, role=UnitRole.BUILDING) worker.build(UnitTypeId.PYLON, position) # Get workers assigned to specific roles building_workers: Units = self.mediator.get_units_from_role( role=UnitRole.BUILDING, unit_type=self.worker_type ) defending_workers: Units = self.mediator.get_units_from_role( role=UnitRole.DEFENDING, unit_type=self.worker_type ) ``` -------------------------------- ### Activate Poetry Shell Source: https://github.com/aressc2/ares-sc2/blob/main/docs/contributing/index.md Enters the virtual environment's shell, allowing direct execution of commands within it. ```bash poetry shell ``` -------------------------------- ### Build Missile Turrets at Third Base Source: https://github.com/aressc2/ares-sc2/blob/main/docs/tutorials/custom_building_placements.md Construct three missile turrets at the third base using custom placements specified in a configuration file by setting `missile_turret=True`. This is useful for defensive structures. ```python # terran wants to build 3 missile turrets at the third # using the placements they specify in their own file self.register_behavior( BuildStructure( base_location=self.mediator.get_defensive_third, structure_id=UnitTypeId.MISSILETURRET, missile_turret=True, to_count_per_base=3 ) ) ``` -------------------------------- ### Configure isort for Black compatibility Source: https://github.com/aressc2/ares-sc2/blob/main/docs/contributing/index.md Add this configuration to pyproject.toml to ensure isort formatting aligns with Black. ```toml [tool.isort] profile = "black" ```