Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: build runner features #137

Merged
merged 3 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 116 additions & 19 deletions docs/tutorials/build_runner.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ race. For each build name, ensure that there is a corresponding build name under
be careful adding build steps that are impossible to commence. Such as adding a barracks before a
supply depot or a gateway before pylon.


### Valid build order options
Each item in the build order should contain a string, with the first word being the command.
This supports any [`UnitTypeID`](https://github.com/BurnySc2/python-sc2/blob/develop/sc2/ids/unit_typeid.py)
Expand All @@ -99,8 +100,10 @@ class BuildOrderOptions(str, Enum):
GATE = "GATE"
EXPAND = "EXPAND"
ORBITAL = "ORBITAL"
OVERLORD_SCOUT = "OVERLORD_SCOUT"
SUPPLY = "SUPPLY"
WORKER = "WORKER"
WORKER_SCOUT = "WORKER_SCOUT"
```

Additionally, strings may contain targets such as `14 pylon @ ramp`, where the last word should contain the target
Expand All @@ -110,57 +113,151 @@ 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"
RAMP = "RAMP"
SIXTH = "SIXTH"
SPAWN = "SPAWN"
THIRD = "THIRD"
```

### Spawning units
Targets may be used to target warp ins, for example:
```yml
- 36 adept @ enemy_nat
```
Will warp in an adept at a power field closest to the enemy natural.
### AutoSupply
Enable AutoSupply in your build order at a specific supply count.
This example turns on AutoSupply after the first supply building:
```yml
- 36 marine @ enemy_nat
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
```
Will prioritize using barracks closest to the enemy natural.

If omitted the default spawn target is our start location.
### Automatic worker production
Like AutoSupply, this cleans up your build order. Use `ConstantWorkerProductionTill` to set an integer value:

```yml
# this is perfectly fine
- 36 adept
Builds:
ProbeMaxout:
# After 0 supply turn AutoSupply on
AutoSupplyAtSupply: 0
ConstantWorkerProductionTill: 200
OpeningBuildOrder:
- 200 gateway
```

### Build complete
Upon completion of the build, a typical bot workflow should allow for dynamic production. To check whether the opening
has been completed or not, you can use the following method call:

```self.build_order_runner.opening_completed```

### Chronoboost
If you are using chrono, then the target should contain the structure ID that represents a `UnitTypeID` type,
for example:
For chrono, target structures using UnitTypeID, e.g.:

```yml
- 13 chrono @ nexus
- 16 chrono @ gateway
- 20 chrono @ cyberneticscore
```

### Duplicate commands
Use `x`, `X`, or `*` followed by an integer to duplicate commands. Ensure sufficient supply.
And consider turning `AutoSupply` option on if using duplicate commands.

### Build complete
Upon completion of the build, a typical bot workflow should allow for dynamic production. To check whether the opening
has been completed or not, you can use the following method call:

```self.build_order_runner.opening_completed```
Examples:
```yml
- 12 worker x3
```

This will return a boolean value indicating whether the opening has been completed or not.
```yml
- 12 pylon @ ramp *5
```

### Get the opening build name
```yml
- 15 barracks ramp *2
```

```yml
- 42 roach * 16
```

### Retrieve the opening build name
Retrieve the opening build name using the following method call:

```self.build_order_runner.chosen_opening```

This method will return a string value containing the name of the currently selected build from the
`<my_race_lowercase>_builds.yml` file.

### Scouting
`worker_scout` and `overlord_scout` options are currently available.

#### Simple worker scout
Use `worker_scout` to scout the enemy base:
```yml
Builds:
DummyBuild:
OpeningBuildOrder:
- 12 worker_scout
```

#### Advanced worker scout
Provide locations via a list for the worker to scout:
```yml
Builds:
DummyBuild:
OpeningBuildOrder:
- 12 worker_scout:
[spawn, nat, enemy_spawn, third, fourth, map_center, enemy_nat]
```

See `BuildOrderTargetOptions` above for all valid options.

#### Overlord scout
Use `overlord_scout` command to send overlord to scout. Unlike the worker scout
there is no default behavior so please provide locations.
See example below, overlord checks enemy natural, then finds a close high ground spot.
```yml
Builds:
DummyBuild:
OpeningBuildOrder:
- 12 overlord_scout:
[enemy_nat_vision, enemy_nat_hg_spot]
```

See `BuildOrderTargetOptions` above for all valid options.

### Spawning units
Targets may be used to target warp ins, for example:
```yml
- 36 adept @ enemy_nat
```
Will warp in an adept at a power field closest to the enemy natural.
```yml
- 36 marine @ enemy_nat
```
Will prioritize using barracks closest to the enemy natural.

If omitted the default spawn target is our start location.
```yml
# this is perfectly fine
- 36 adept
```
8 changes: 8 additions & 0 deletions src/ares/behaviors/macro/auto_supply.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,12 @@ def _num_supply_required(ai: "AresBot", mediator: ManagerMediator) -> int:
)
return min(num, 6)

# we have no prod structures, just in case
elif (
num_production_structures == 0
and supply_left <= 2
and not pending_supply_units
):
return 1 - pending_supply_units

return 0
Loading
Loading