archive by month
Skip to content

lurkers, decisiveness, and partial overlapping solutions

I claim that, unlike other zerg bots, Steamhammer’s lurkers (in the upcoming version) do not burrow and unburrow too often. They are decisive. Not that Steamhammer’s lurker play is exemplary or anything, but at least the bot doesn’t change its mind on alternate frames.

I did it by combining 3 different techniques to increase decisiveness. None solves the problem by itself, but each reduces part of it, and the techniques overlap so that together they create decisiveness.

I want to advertise the meta-idea of partial overlapping solutions. An engineer seeing one problem may think it calls for one solution. In a complex situation, partial overlapping simple solutions are more likely to be robust than one fancy solution. Biological evolution often solves problems with partial overlapping solutions. Take a minute to think about how many different partial solutions evolution overlapped to convince humans to reproduce!

  • Each trick is easy to implement, no more than a few lines of code.
  • The tricks are independent. They don’t step on each other’s toes.
  • The effects combine, each reducing some aspects of the indeciveness problem so that the problem as a whole is much reduced.

1. Never unburrow while a target is in range—any target. Take Killerbot by Marian Devecka as an example; many bots are similar. Marines are more important targets than supply depots, so when a lurker has a supply depot in range but no marines, it may unburrow and move toward the marines. The marines may back up and force it to unburrow again, or may catch it above ground and kill it.

Steamhammer simply stays in the ground and batters down the supply depot. When nothing of the enemy remains in range, then it will unburrow and approach the marines. Lurkers are stronger if the enemy has to come to you, because if you maneuver the lurkers then you have to spend extra time burrowing and unburrowing.

2. Only unburrow at the top of each second. Many bots (I think most) unburrow a lurker the moment that it has no target in range. If you do that when a line of marines is feeding itself into the sausage machine, then the lurkers may spend half their time above ground and lose the fight instead of winning effortlessly.

I simply changed each call

    lurker->unburrow();

into this, unburrowing by the clock.

    if (BWAPI::Broodwar->getFrameCount() % 24 == 0)
    {
        lurker->unburrow();
    }

The slight delay is hardly noticeable when you watch Steamhammer play, but the effect is that a lurker is much less likely to unburrow and then immediately burrow in the same place when another enemy moves into range.

3. Don’t always burrow at maximum range. If you can approach closer without taking too many hits, you’ll do more damage and constrain the enemy’s movement more. For now, Steamhammer implements this idea with an approximation. Each lurker is given an enemy target. If any enemies in the area threaten the lurker, then the target is probably one of the threats. Steamhammer simply checks: Is the single target enemy a threat? It is a threat if it can hit ground and is not a worker. If it’s a threat, the lurker burrows at maximum range for safety. If not, the lurker approaches to within 64 pixels before burrowing (compared to the lurker’s maximum range of 192 pixels).

The implementation is easy. There is not much more to it than changing

    if (lurker->getDistance(target) <= lurkerRange)

to

    int dist = lurker->getDistance(target);
    bool isThreat = !target->getType().isWorker() && UnitUtil::CanAttackGround(target);
    if (isThreat && dist <= lurkerRange || dist <= 64)

The effect is that, when attacking workers or defenseless buildings, the lurkers approach much closer, come in range of more targets, do more damage, stay underground for longer before having to move, and push the enemy farther away. If marines retreat behind buildings, the lurkers do not try to follow, but stop and tear down the buildings first.

Trackbacks

No Trackbacks

Comments

PurpleWaveJadien on :

Iron bot's similar approach for unsieging its Siege Tanks (which, let's be honest, are Terran Lurkers) is: when unsieging is reasonable, to do if (randInt % 100 == 0), which produces the effect of preventing all his tanks from unsieging at the same time. One approach you could try if you want more aggressive Lurkers: Check the targets of enemy units and get closer until at least one enemy is targeting you.

Jay Scott on :

Oh, that is a cute idea.Maybe I’ll do it.

Arrak on :

Pretty similar to what I have. Instead of doing it every 24 frames, though, I'm predicting the target's position ~8 (or was it 6?) frames or so in the future based on its velocity and using mainly this for burrowing.

I added a new mechanic (which I'm still testing) recently which checks for nearby burrowed lurkers to go more aggressive forward -- so lone-wolf or support lurkers remain cautious. Unlike siege tanks, lurkers are much more shorter ranged, less cost-effective, and die really quickly to marines and dragoons, so I'm not a fan of using randomness to determine their behavior (aside from burrowing near buildings -- it's cute).

I have not yet decided when I want a lurker to simply always stay burrowed, though --- I think this is a different case altogether compared to advancing.

Add Comment

E-Mail addresses will not be displayed and will only be used for E-Mail notifications.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Form options

Submitted comments will be subject to moderation before being displayed.