Plans and Build Order - DrInfy/sharpy-sc2 GitHub Wiki
Plan is the any part of a build order and inherits the ActBase class. In Sharpy, plans are categorized into acts, requirements and tactics. Acts are meant to be part of the actual build order, while tactics are more about moving units and armies. Requirement are just that, they just require some condition to be triggered.
Plans are formulated into an actual build order or "overall plan" by combining them with BuildOrders, SequentialLists and Steps. Plan should always return either True or False from their execute method. True is returned when the bot the step is either finished or the build is allowed to step to the next plan.
BuildOrder
BuildOrder will run its plans in order, but it will progress to the next plan, regardless of whether the previous one has completed or not. Let's consider the following build:
BuildOrder(
ProtossUnit(UnitTypeId.IMMORTAL, priority=True)
ProtossUnit(UnitTypeId.ZEALOT)
)
It's defined here that we want infinite amount of both immortals and zealots. Because immortal production has priority flag and it is before zealot production, it will reserve resources for next immortal when robotics facility is available for production. Thus zealots would only be produced when the bot has 375 minerals (275 + 100) or when all robotics facilities are busy and the bot has 100 minerals.
SequentialList
SequentialList will only progress to next plan after the previous plan has been completed.
SequentialList(PlanZoneAttack(), PlanFinishEnemy())
Because PlanZoneAttack is a blocking plan, PlanFinishEnemy will only run when PlanZoneAttack returns True from its execute.
Step
Step combines multiple plans in order to make the plan a conditional one: requirement, action, skip and skip_until.
SequentialList(
# Weapons
Step(None,
Tech(UpgradeId.PROTOSSGROUNDWEAPONSLEVEL1)),
Step(None,
Tech(UpgradeId.PROTOSSGROUNDWEAPONSLEVEL2),
skip_until=All(
UnitReady(UnitTypeId.TWILIGHTCOUNCIL, 1),
TechReady(UpgradeId.PROTOSSGROUNDWEAPONSLEVEL1, 1)
)),
Step(None,
Tech(UpgradeId.PROTOSSGROUNDWEAPONSLEVEL3),
skip_until=All(
UnitReady(UnitTypeId.TWILIGHTCOUNCIL, 1),
TechReady(UpgradeId.PROTOSSGROUNDWEAPONSLEVEL2, 1)
)),
# Armor
Step(UnitReady(UnitTypeId.FORGE, 1),
Tech(UpgradeId.PROTOSSGROUNDARMORSLEVEL1)),
)
In this example, forge upgrades weapons, unless there are 2 forge or 1 forge, +1 weapons and without twilight council.
IfElse
IfElse is a simpler option to Step when a binary decision is required.
# Start gathering resources for warp prism when second immortal is almost ready, otherwise do nothing
IfElse(UnitReady(UnitTypeId.IMMORTAL, 1.9), ProtossUnit(UnitTypeId.WARPPRISM, 1, priority=True))
# Build 5 stalkers vs protoss, otherwise build 2
IfElse(lambda ai: ai.enemy_race == Race.Protoss,
ProtossUnit(UnitTypeId.STALKER, 5), ProtossUnit(UnitTypeId.STALKER, 2))