separate, independent unit control for micro
I notice a lot of bot authors want to control each unit independently for micro decisions, to make it an agent with a mind of its own. There are good reasons to write a bot that way.
- It’s simple. Fewer bugs and less implementation effort are strong reasons.
- Being simple, it can run fast.
- Frame-accurate control depends on each unit’s exact state at each frame. It seems much easier to handle unit by unit.
- Units can sidestep the stupidest behaviors, like moving too much without shooting. Each unit can act efficiently under its local circumstances.
- Cooperation: If a squad still gets orders from above, then the squad still acts together for higher-level goals.
- Cooperation: Units can still work together on low-level goals like focus fire by simple means like preferring targets that are already hurt. Cooperation occurs as an emergent behavior.
- Cooperation: At a cost in simplicity and speed, units can look at each other’s targeting and movement plans or expectations, to get more effective focus fire, to reduce overkill, to kite better, and so on.
- And hey, you can call it an agent architecture, which sounds great.
It doesn’t make sense to me. My micro plans in Steamhammer call for reducing the independence of units, calculating more things centrally at the squad level and leaving less for individual units to decide. For focus fire and avoiding overkill, I want a data structure in the squad to keep track of assignments of shooters to targets. For kiting and fleeing, I want a near-term prediction of when each of my units is likely to die, based on the rate it is taking damage or on the approach of enemy melee units. A planning algorithm can look at all the data to decide, “You, shoot at that” and “You, pull back.” It’s not as simple, but I expect it will have a higher ceiling in practice, because it is easy to change out the planner. And I think that, done right, it can execute fast. Units act frame to frame, but the squad-level planner needs to execute only about once per cooldown period, and it can be out of synchrony with unit actions.
That’s general micro, but there are also important micro skills that bots don’t have and would benefit from. I’ve never seen a bot do any of these effectively.
Zergling surrounds. Watch a bot attack zealots with zerglings: Each zergling heads for where the zealot is now, and the lings pile up. With fast zerglings and slow zealots, if the zealots flee then the zerglings end up trailing behind and getting a hit in now and then, and mostly waste their time getting in each other’s way. Arrakhammer does modestly better by predicting the zealot’s future location, react to the future style. Then watch a human do it: The zerglings move into or around the formation of zealots, then attack all at once. If the zealots are fleeing, they get surrounded and have to find or make a way out before they can escape. Any intermediate zerg player knows this micro.
I’m seriously considering implementing zergling surrounds in Steamhammer with human-like control, at least as a first cut. It’s 2 commands total for small fights with up to one control group of zerglings: Command lings to move as a group, command lings to attack as a group. Choosing the destination for the move command is the tricky part.
Dragoon backstepping. Like most bots with a combat simulator, Steamhammer mostly attacks or retreats, and doesn’t know anything in between. But watch what happens in a human game when a strong terran early timing attack moves out and faces forward dragoons: The dragoons will lose if they stand and fight, they must step back... and back.... But if vultures pull too far in front of the tanks, or if any sloppy movement isolates a few terran units, the dragoons may suddenly stop and fire. The terran force must move slowly or be whittled down—usually some of both. Protoss gains time for more dragoons to take the field.
Related situations are common. FAP doesn’t understand vultures versus zealots, so if there are too many zealots, Steamhammer’s vultures will retreat in terror instead of pulling hit-and-run attacks. If an opportunity comes up, take it even if you weren’t intending to fight. I think the decision is best made at the squad level, so that the squad behavior stays coherent. I often see Tscmoo lose squad coherence and disintegrate; I want to avoid that.
Getting out of each other’s way. A large group of ranged units arrives to fight—hydralisks, say. The closest hydras get into range and stop to fire, and the ones behind maneuver around the sides to get into range (that is inefficient already). The ones behind those... push and shove, but can’t get into range and achieve nothing. Any human above beginner level will move the front hydras forward so that all can get into range, but bots don’t.
Climbing a ramp is similar. Bots see targets at the top of the ramp and stop to hit them, blocking the way so that the rest of the force is stuck below. Steamhammer is clever enough not to siege tanks on the ramp, but sieges them above the ramp and blocks the path anyway. Humans keep the front units moving until the whole force can get up. The difference in DPS is huge.
These decisions can be made by individual units, swarm intelligence style, but I find it hard to design good emergent behaviors. I think it is better to make the decisions at the squad level. It should be more efficient and more effective.