Skip to content

Plans and Build Order

DrInfy edited this page Aug 30, 2021 · 6 revisions

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))
Clone this wiki locally