Hey, that's something I know a bit about. I wanted to get a more complete grasp on how the AI works and document all of that, but I never got around it, so here's what I know. Most notably I never looked into the attacking logic itself, just how AI base management / unit building works.
= Towns and `build` opcode =AI's bases are called towns. When the AI expands (`expand` opcode), it creates a new town. I don't know what's the difference between "town" and an "area town". Each of the AI script's threads is assigned to some town, but most of the opcodes modify AI's global state.
Most notably, the `build` opcode modifies the current thread's town's buildings / workers. Using `build` is a permament change to the town's buildings, that is, `build 3 barracks 100` tells the AI that the town should have 3 Barrackses, and the AI will keep rebuilding those 3 barrackses even if they get destroyed (I believe that the zerg morphing buildings have special handling so the AI won't build a Hatchery after it "loses" one by upgrading to Lair). Workers are also part of town's "buildings", but there's special handling that makes AI limit worker building when it thinks there are enough of them.
= Base locations =At start of the game, AI will scan the map's resources and determine the places that a base can be placed on. If the resources are placed in a unusual way, AI might place its main building to a nonsensical location when expanding. Most notably,
all Start Locations of the map will always become base locations, so they should be placed in places which actually are sensible places to expand.
= Town defense =The `defensebuild_xx` opcodes and variants define AI's defense
composition. For example, using `defensebuild_gg 1 marine` and `defensebuild_gg 2 vulture`, will make the AI build 33% marines and 66% vultures when it needs to get units to defend its town.
The `defenseuse_xx` opcodes will allow AI to take military it has built beforehand and use it to defend against attacks. Again, the number will define the ratio of ideal composition of what the defense forces should consist of. The AI will use all of it's preexisting military it has (as long as the unit type is allowed to defend with `defenseuse_xx`), before it starts training units specified with `defensebuild_xx`.
Enemies are separated to four different classes in the town defense opcodes.
`_ga` Enemy ground units attack own air units
`_ag` Enemy air, own ground
`_gg` Enemy ground, own ground
`_aa` Enemy air, own air
Also, there's limit of 20 units per defense_xx in the script, anything after that will be ignored. So "defenseuse_gg marine 10" followed by "defenseuse_gg vulture 9" will leave only one defenseuse_gg slot free. I believe `defenseclear_xx` clears these, but I'm not sure what's the exact behaviour (Does it affect both "use" and "build" ?)
= Unit strength =When attacked, the AI will bring/train enough, but not too many defenders to defend its town. It determines this ideal number by calculating a "
strength value" for each unit. The formula is as follows:
Strength = sqrt((damage * factor * (range_pixels + 8 * (hitpoints + shields))) / cooldown) * 7.58
- Workers get 25% of default
- Interceptors, scarabs, mines 0%
- Firebats, mutalisks, zealots 200%
- Defilers, inf. terrans 1/16
- Reavers 10%
This means that if the units have some cool and flashy iscript attacks which shoot 10 missiles per attack cycle, the AI will misevaluate the units' strength to be far lower than the actual efficency.
So fancy iscript can lead to an AI which over/underreacts when its town gets attacked.
= Training military =The main training commands are `train`, `wait_train`, `do_morph`, and `wait_force` AI can only train one unit at once (Not counting defense training, which is really common), so multiple threads should not be training units simultaneously.
- `train` will set the unit to be trained, and wait until enough units have at least been started to train. Ai does not understand morphing Zerg units as something that has started to train, so when used with Zerg, it will wait until all units have completed. But `train` should still work fine with Zerg units.
- `wait_force` is same as `train`, but it always waits until the units have been completed.
- `do_morph` will not wait at all, it just sets the unit to be trained. Again, there is nothing Zerg-specific in there. Because the AI can only train one unit at once, using multiple `do_morph`s in succession without any waits is always the incorrect thing to do.
- `wait_train`
does not set the unit to be trained, so it will hang the script if other training command didn't set the training unit to what is being waited. Blizzard scripts only use wait_train in short child threads, which call `wait_train` and start an upgrade once the AI has enough units the upgrade is affecting.
= Bugs =- If AI tries to tech/upgrade something it does not have the necessary tech for, it will start behaving very inefficiently
- If an SCV building a Terran building is killed without destroying the building, AI will try to "repair" the building instead of "continue construction", which will completely break the town's management, as SCVs just stop doing anything.
= Some specialized opcodes =- `harass_location` is unused and doesn't do anything
- `killable` ends the current thread once any thread calls `kill_thread` (Should use `end` if the thread should just end right now)
- `fake_nuke`. AI has a cooldown on nukes, `fake_nuke` will set the cooldown as if the AI just nuked.
- `help_iftrouble` will make AI treat any current allied computer base areas as places that should be defended.
- `allies_watch`. The first argument is a index of the base location (I don't think there are any tools to determine the index), and second is a script position. If the base location has resources remaining, *something* happens.
Post has been edited 3 time(s), last time on Jul 20 2017, 11:21 pm by Neiv.
None.