Typical Usage¶
from ares import AresBot
from ares.behaviors.macro.mining import Mining
class MyBot(AresBot):
async def on_step(self, iteration: int) -> None:
await super(MyBot, self).on_step(iteration)
self.register_behavior(Mining())
MacroPlan
dataclass
¶
Bases: Behavior
Execute macro behaviors sequentially.
Idea here is to put macro behaviors in priority order.
Example:
from ares.behaviors.macro import MacroPlan
from ares.behaviors.macro import (
AutoSupply,
Mining
SpawnController
)
# initiate a new MacroPlan
macro_plan: MacroPlan = MacroPlan()
# then add behaviors in the order they should be executed
macro_plan.add(AutoSupply())
macro.plan.add(SpawnController(army_composition_dict=self.army_comp))
# register the macro plan
self.ai.register_behavior(macro_plan)
Attributes:
Name | Type | Description |
---|---|---|
macros |
list[Behavior] (optional, default: [])
|
A list of behaviors that should be executed |
AddonSwap
dataclass
¶
Bases: MacroBehavior
For Terran only, swap 3x3 structures. Pass in two structures and they will swap positions.
TODO: Extend this to support an exact swap, ie. swap techlab and reactor
Example:
from ares.behaviors.macro import AddonSwap
# factory will find a reactor to fly to, any existing
# structure will fly to the factory's starting position
self.register_behavior(
AddonSwap(factory, UnitID.REACTOR)
)
Attributes:
Name | Type | Description |
---|---|---|
structure_needing_addon |
Unit
|
The structure type we want the addon for |
addon_required |
UnitTypeId
|
Type of addon required |
AutoSupply
dataclass
¶
Bases: MacroBehavior
Automatically build supply, works for all races.
Example:
Attributes:
Name | Type | Description |
---|---|---|
base_location |
Point2
|
The base location where supply should be built. |
return_true_if_supply_required |
bool
|
If can't afford supply but it's required, return true?
Useful if creating a |
BuildStructure
dataclass
¶
Bases: MacroBehavior
Handy behavior for Terran and Protoss.
Especially combined with Mining
and ares built in placement solver.
Finds an ideal mining worker, and an available precalculated placement.
Then removes worker from mining records and provides a new role.
Example:
from ares.behaviors.macro import BuildStructure
self.register_behavior(
BuildStructure(self.start_location, UnitTypeId.BARRACKS)
)
Attributes:
Name | Type | Description |
---|---|---|
base_location |
Point2
|
The base location to build near. |
structure_id |
UnitTypeId
|
The structure type we want to build. |
wall |
bool
|
Find wall placement if possible. (Only main base currently supported) |
closest_to |
Point2(optional)
|
Find placement at this base closest to |
Mining
dataclass
¶
Mining(
flee_at_health_perc=0.5,
keep_safe=True,
long_distance_mine=True,
mineral_boost=True,
vespene_boost=False,
workers_per_gas=3,
self_defence_active=True,
safe_long_distance_mineral_fields=None,
locked_action_tags=dict(),
)
Bases: MacroBehavior
Handle worker mining control.
Note: Could technically be CombatBehavior
, but is treated here as a
MacroBehavior since many tasks are carried out.
Example:
Attributes:
Name | Type | Description |
---|---|---|
flee_at_health_perc |
(float, optional)
|
If worker is in danger, at what health perc should it flee (default is 0.5). |
keep_safe |
(bool, optional)
|
Workers flee if they are in danger? (default is True). |
long_distance_mine |
(bool, optional)
|
If worker has nothing to do, can it long distance mine (default is True). |
mineral_boost |
(bool, optional)
|
Turn mineral boosting off / on (default is True). |
vespene_boost |
(bool, optional)
|
Turn vespene boosting off / on (only active when workers_per_gas < 3) WARNING: VESPENE BOOSTING CURRENTLY NOT WORKING (default is True). |
workers_per_gas |
bool, optional (default: 3)
|
Control how many workers are assigned to each gas. |
self_defence_active |
bool, optional (default: True)
|
If set to True, workers will have some basic defence. Certain workers will attack enemy in range. |
safe_long_distance_mineral_fields |
(Optional[Units], optional(default is None))
|
Used internally, value is set if a worker starts long distance mining. |
ProductionController
dataclass
¶
ProductionController(
army_composition_dict,
base_location,
unit_pending_progress=0.75,
ignore_below_unit_count=0,
ignore_below_proportion=0.05,
should_repower_structures=True,
)
Bases: MacroBehavior
Handle creating extra production facilities based on an army composition dictionary. This dictionary should be structured the same as the one passed into SpawnController
Terran / Protoss only
Example bot code:
from ares.behaviors.production_controller import ProductionController
# Note: This does not try to build production facilities and
# will ignore units that are impossible to currently spawn.
army_composition: dict[UnitID: {float, bool}] = {
UnitID.MARINE: {"proportion": 0.6, "priority": 2}, # lowest priority
UnitID.MEDIVAC: {"proportion": 0.25, "priority": 1},
UnitID.SIEGETANK: {"proportion": 0.15, "priority": 0}, # highest priority
}
# where `self` is an `AresBot` object
self.register_behavior(ProductionController(
army_composition, self.ai.start_location))
Attributes:
Name | Type | Description |
---|---|---|
army_composition_dict |
dict[UnitTypeId:float, bool]
|
A dictionary that details how an army composition should be made up. The proportional values should all add up to 1.0. With a priority integer to give units emphasis. |
base_location |
Point2
|
Where abouts do we build production? |
unit_pending_progress |
float(default=0.8)
|
Check for production structures almost ready For example a marine might almost be ready, meaning we don't need to add extra production just yet. |
ignore_below_unit_count |
int(default=0)
|
If there is little to no army, this behavior might make undesirable decisions. |
ignore_below_proportion |
float = 0.05
|
If we don't want many of this unit, no point adding production. Will check if possible to build unit first. |
should_repower_structures |
bool = True
|
Search for unpowered structures, and build a new pylon as needed. |
SpawnController
dataclass
¶
SpawnController(
army_composition_dict,
freeflow_mode=False,
ignore_proportions_below_unit_count=0,
over_produce_on_low_tech=True,
ignored_build_from_tags=set(),
maximum=20,
spawn_target=None,
__build_dict=dict(),
__excluded_structure_tags=set(),
__supply_available=0.0,
)
Bases: MacroBehavior
Handle spawning army compositions.
Example bot code:
from ares.behaviors.spawn_controller import SpawnController
# Note: This does not try to build production facilities and
# will ignore units that are impossible to currently spawn.
army_composition: dict[UnitID: {float, bool}] = {
UnitID.MARINE: {"proportion": 0.6, "priority": 2}, # lowest priority
UnitID.MEDIVAC: {"proportion": 0.25, "priority": 1},
UnitID.SIEGETANK: {"proportion": 0.15, "priority": 0}, # highest priority
}
# where `self` is an `AresBot` object
self.register_behavior(SpawnController(army_composition))
Attributes:
Name | Type | Description |
---|---|---|
army_composition_dict |
dict[UnitTypeId:float, bool]
|
A dictionary that details how an army composition should be made up. The proportional values should all add up to 1.0. With a priority integer to give units emphasis. |
freeflow_mode |
bool (default: False)
|
If set to True, army comp proportions are ignored, and resources will be spent freely. |
ignore_proportions_below_unit_count |
int (default 0)
|
In early game units effect the army proportions significantly. This allows some units to be freely built before proportions are respected. |
over_produce_on_low_tech |
bool (default True)
|
If there is only tech available for one unit, this will allow this unit to be constantly produced. |
ignored_build_from_tags |
set[int]
|
Prevent spawn controller from morphing from these tags Example: Prevent selecting barracks that needs to build an addon |
maximum |
int (default 20)
|
The maximum unit type we can produce in a single step. |
spawn_target |
Union[Point2, None] (default None)
|
Prioritize spawning units near this location. |
RestorePower
dataclass
¶
Bases: MacroBehavior
Restore power for protoss structures.
Note: ProductionController
is set to call this automatically
configured via should_repower_structures
parameter.
Though this behavior may also be used separately.
Example: