Combat simulation answers one question, and answers it pretty well. It adds a lot of strength to a bot’s play. But there are many related questions that the simulation does not answer, at least not simulation as we currently implement and use it.
Taking free shots. Combat simulation is all about armies fighting, but the enemy army is not the only thing you want to shoot at. When the combat sim says to retreat from the enemy, Steamhammer retreats, even if if is already out of range and could safely take shots at exposed supply depots or other valuable stuff that can’t shoot back. It’s not a problem with the combat sim in itself, but it is a side effect of relying on the combat sim as the big decision maker. I’ve been thinking I’d solve it by calculating safe places and advantageous places, and holding position in advantageous places that are safe.
Can you run away? You’re in a hot fight, and the sim says you’re going to lose. Steamhammer runs away, and sometimes it is a mistake. If you’re fighting ranged units, you may die before you’re out of range; better to stay and do some damage first. If you’re fighting faster units, they can catch you and get free kills. Unupgraded marines should not flee from speed zerglings; if they are going to die no matter what, at least take some of the enemy along. It’s complicated, though. If you have friends nearby, maybe you can run and live. Or the dragoons can run and leave the reaver behind. The reaver is too slow to escape, so it should stop and fire when it can. In general, you want to simulate different cases and see which one comes out best. It amounts to performing a search over different tactical actions.
Harass versus big battle. FAP author Hannes Bredberg suggested (see comments to separate, independent unit control for micro) running the simulation for a very short period such as 0.5 second, a poke at the enemy. If you gain from the poke, do it. It’s a smart idea; a bot might do well without once looking ahead beyond the next moment. But instant gratification is not the only gratification. What if the first zerglings die to firebats, but once those are gone you mop up survivors and come out ahead? What if you lose more than you gain in the battle itself, but the enemy is wiped out and afterwards you can go to town on the enemy base? To recognize chances for delayed gratification, you want to look further ahead.
Maybe the right idea is to sample the outcome-so-far periodically as the simulation runs. If you’re ahead after 0.5 second, stop there and attack. If you’re behind then but ahead after 1.0 second, that’s a higher risk so maybe you should attack only if you’re a little further ahead. And so on. You can also cut the sim short if you’re too far behind. Maybe you can estimate whether losses are accelerating, or decelerating and possibly turning around. It’s both cheaper than running a simulation of the entire battle, and potentially more valuable. It’s an idea, anyway.
Tactical coordination. Here’s a common blunder made by Steamhammer, and also by related bots like Microwave: Zerglings and mutalisks are assigned to different squads, and act independently. There is no explicit coordination. The combat simulator acts as an implicit coordinator. It runs separately for each squad, and if the squads are in the same place then in each run it will pit the same friendlies against the same enemies and give the same answer. The mistake comes when both squads are deciding whether to attack (say) an enemy base strongly defended by sunken colonies and zerglings. Combat sim says, “Well, the zerglings are toast, but the mutalisks eventually win, so yeah! Go attack!” The right decision is to keep the zerglings back to stave off any attempted breakout, and go win with the mutalisks alone—losing your own zerglings lets the enemy’s run free, forcing the mutalisks to give up the attack and defend. The combat sim itself is unable to understand. In this case we could work around it by handling each squad separately, but that is a special case; in general, arbitrary units might be unhelpful in a given battle. I’ve seen Tscmoo do it right, at least in some cases.
Screening. Steamhammer likes to keep its army forward, just out of contact with the enemy. The forward position is aggressive and also risky. One advantage is that Steamhammer gets to see what the enemy has and what the enemy is doing; the corresponding disadvantage is that the enemy gets to see Steamhammer too. One of the skills I want for Steamhammer is screening: Maintain a small screening force forward to keep tabs on the enemy, and hold the bulk of the army farther back, in a more flexible position where it is also out of enemy sight. The screening tactic is common in pro zerg games, especially earlier in the game.
How does that affect combat simulation? It’s perfectly possible to simulate a fight between distant enemies, but the result will be less accurate. Imagine a zerg army gathering far outside the range of photon cannons and defending zealots. Should the zerg attack? SparCraft and FAP will assume that the armies approach each other and fight in the middle, far from the cannons, and will keep saying “zerg wins!” until the zerg army actually approaches the cannons and finds that the zealots are still in defensive positions. The combat sim needs more smarts to get the right answer.