A computer standing helpless in front of a wall-in is an old weakness, and the stock answer is Send All Units on Random Suicide Missions - they attack regardless of aggro. But it is every unit, map-wide, workers included, exactly as the name says. Fine for a handful of mobs; unusable for a computer with an economy.
After every attempt to scope it failed, what is left is the struct. The measured minimum is five fields.
| 0x4D order | 0x0A, Attack Unit. |
|---|---|
| 0x4E orderState | 1. |
| 0x58 orderTargetPos | The target's position. |
| 0x5C orderTarget | The target's pointer. |
| 0x7C autoTargetUnit | The target's pointer again. |
Do not leave the last one out. 0x5C is the order and 0x7C is what the unit picked for itself, so writing only the first lets the unit's own acquisition replace it with whatever is nearest and wander off. And re-issue it every cycle for as long as you want the attack held.
u.order = 0x0A; u.orderState = 1; u.orderTargetPos = target.pos; u.orderTarget = target; u.autoTargetUnit = target;
Do not run a full unit loop every frame to find them. That is the same source's conclusion - EUDLoopUnit every frame lags badly. Classify each unit once as it appears with EUDLoopNewUnit, into an array or a UnitGroup, and let the per-frame work loop only that list.
If your map uses triggers and AI scripts together there is one more thing. An AI script takes no arguments and returns no values, so maps that need both halves to talk build a protocol out of hero unit creations: the trigger side creates a particular hero to mean “the Factory is done”, the script watches for it, and each side removes the other's signal once it has read it.
It is crude and it is the only channel there is. Write down which unit means what - the map that did this kept the protocol as a separate document. One unremoved signal unit is a deadlock with no error message.
| expand | You cannot say which worker takes the expansion, so a computer running two races may send the wrong one. |
|---|---|
| Add-ons | After an expansion is taken, add-ons stop being buildable through build or player_need. Nobody has explained why. |
Which is why that map placed buildings through the struct and used the AI script only for unit production, upgrades and research. It is not a choice between the two but a division of what each can actually do.
Before reaching for the struct, three things people build whole systems for and that are one field or one action each.
| Hitting what is in front without chasing | Set that unit type's AI Attack Unit order to 19, Tower: it engages what comes into range and does not follow when the target leaves. Order 100, Watch Target, is the near miss - it tracks and never attacks. |
|---|---|
| A computer fleeing an invincible unit | You cannot stop it. A computer unit flees anything it cannot counter-attack with its own weapon - invincible, cloaked, or out of its weapon's domain. Workers and buildings are the exceptions. Either drop the invincibility or re-issue the attack order the moment it flees. |
| Cancelling every targeted order at once | The stock SetAllyStatus action does it - see below. |
The last one is the interesting one. SetAllyStatus walks that player's units and cancels an order when the order matches that unit type's AI attack order and the order's target belongs to an ally. Which can be used like this:
- 1Write 1, allied, over the whole alliance table for that player.
- 2Set the unit type's AI attack order to the order you want cancelled.
- 3Set CurrentPlayer to that player and run SetAllyStatus.
- 4Restore the alliance table and the AI attack order.
It only works on orders that have a target. StarCraft assumes an attack order always has a target unit and reads it unconditionally, so pointing this at a targetless order crashes.
When a computer unit castsThree ways to read the struct wrongHolding on to many units