
The StarCraft path-finding hack - willvarfar
http://www.codeofhonor.com/blog/the-starcraft-path-finding-hack
======
CyrusL
One of the reasons Starcraft is interesting as an e-sport is because bugs like
this have kept the game in racial balance for over a decade.

For example, the game was not designed to give mutalisks the ability to stack
on top of each other. However, at some point in the early 2000s, it was
discovered that when 11 mutalisks were grouped with 1 overlord, the mutas
tended to stack: <http://www.youtube.com/watch?v=NfqQYJzq7o0> . This meant
that an attacking player could deal the damage of 11 units while only exposing
the surface area of 1 of them. Using this technique, a pro gamer named July
won the 3 OSL tournaments: <http://wiki.teamliquid.net/starcraft/July> .

With respect to the path-finding behavior described in the article, there is a
funny aspect the author doesn't mention: mining workers still collide with
buildings while mining, just not other workers. This lead to a technique known
as the manner pylon: <http://www.youtube.com/watch?v=EmS2ghQyAYI> . If a
protoss player builds a pylon in their opponent's mineral line with great
timing, they can trap their opponent's workers between the minerals and the
pylon. This renders the workers useless until the pylon is killed.

In Starcraft-speak, "manner" means being respectful (such as saying "good
game" when you lose). The manner pylon got it's name because it is so
incredibly annoying to deal with, it will cause anyone to lose their manners.

For those of you who might be familiar with Starcraft, but not the competitive
scene, you should know that pro players are executing these techniques at a
rate of hundreds of APM (actions per minute):
<https://www.youtube.com/watch?v=Z4UTDudShDY>

~~~
GavinB
Is changing the behavior of a group of units because it happens to be grouped
with a distant unit really a good thing for the game?

It makes for a good story, and it's great fun for the person who discovers it.
Players like it, because it lets them beat new players even more easily. But
players don't always know what's best for them.

This is why Starcraft 2 multiplayer is structured to force players to play on
complicated, resource balanced Blizzard approved maps. Starcraft 1 allowed
ranked games on any map, and players largely played simplified, resource-
soaked maps. Or played nothing but Big Game Hunters and Lost Temple. This was
what players thought they wanted, but it wasn't what was best for the game.

~~~
edias
Your comment on starcraft maps is off.

Both SC2 and BW have two sets of maps, UMS maps with custom settings used for
fun games and competitive maps made to be racially balanced and produce "good"
games. In SC2 UMS maps are part of the arcade where as ladder games are played
on tournament maps. The same is true for BW but blizzard didn't have an
official ladder so 99% of the games on battle.net were UMS maps, but ICCUP
ladder had the same competitive maps you see in SC2.

As far as the glitches are concerned, they were undoubtedly beneficial to BW,
as the last balance patch was in 2001 when the game was in its infancy as far
as strategy goes. For example TvZ could not be played in its current form
without muta stacking and terran's still have more success despite it. 99% of
players would never use these tricks of have them used against them, but it
allowed for the game to advance strategically and added an additional element
of skill.

~~~
tekromancr
BW?

~~~
edias
Broodwar, the expansion to the original starcraft.

------
invalidOrTaken
What no one has mentioned is how many "essential" skills have arisen as a
result of this hack.

For instance, an everpresent threat in Starcraft is the Zerg Rush, in which a
player skips building an economy to build zerglings---cheap, light, raider
units--- to attack the opponent early before he has any defenses (as he,
presumably, has _not_ skipped building an economy). The zerglings are melee
attackers, so holding a small choke point is an effective way of only allowing
one or two zerglings to attack at a time, even if there are more (usually
6-8).

Of course, this poses a problem---if the tight spaces allow only two zerglings
to attack, that's great, but the tight spaces _also_ only allow two of your
workers to fight back. Actual fighting units will slaughter worker units, so
you've merely slowed your death, not prevented it.

Except! By ordering all your workers to harvest the _same_ mineral patch, you
can activate this collisionless behavior described in the article, and then
fit your "super-group" of ten or so workers into small spaces---to fight the
two zerglings at a time. The workers can definitely win now!

This has become a giant wall of text, but this is actually basic, easy,
essential knowledge for the competitive starcraft 2 player, so it's fun to see
its origins in this article.

~~~
mitchi
I played Warcraft 3 and the same trick was used to surround a hero with
ghouls. Since ghouls are also the unit that gathers lumber for the Undead
Race, they enter a no-collision state when you right click on a tree. This
behavior was patched because it was too strong. You would just click on a tree
behind the enemy hero and all your ghouls would pass through all the other
units (footmen for example) and they could surround the hero and kill him.
Once you kill the hero in Warcraft 3, there's no point fighting anymore :P

~~~
ihsw
Another WC3 glitch is Shades (invisible scouting units) that triggered
collision but you couldn't target them due to being invisible. Eventually
players caught on and lined Shades up to create impassible and invisible
walls.

To combat this you had to devote significant resources to units and buildings
that could reveal invisible units, and eventually Blizzard patched it. Very
interesting.

------
prawks
> _Because the project was always two months from launch it was inconceivable
> that there was enough time to re-engineer the terrain engine to make path-
> finding easier, so the path-finding code just had to be made to work._

Really enjoyed this part of the article. When you have an infinitely long two-
month period, you still can't complete a task that requires three months.

~~~
kevingadd
That mindset is sadly pervasive in the game industry (no doubt other software
as well, but imaginary ship dates have a terrifying power in games due to The
Holidays)

~~~
prawks
I would imagine The Holidays wouldn't be a moving target as much as "soon" is,
however.

------
danso
> _Some bugs were related to the development process itself. The Protoss
> Carrier regularly lagged behind other units because it had its own way of
> doing … everything. At some point in time the code for the Carrier was
> branched from the main game code and had diverged beyond any hope of re-
> integration. Consequently any time a feature was added for other units, it
> had to be re-implemented for the Carrier. And any time a bug was fixed for
> other units, a similar bug would later be found in the Carrier code too,
> only more devious and difficult to fix._

I guess it's comforting to know that even elite development teams also
struggle with code design. I wonder how far off the branch the Carrier unit
was that required it to have its own reimplemented features...and what kind of
features needed to be reimplemented for it? (story-game events, path-finding?)

~~~
cube13
I think it's because of the way the unit works. The carrier itself doesn't
actually attack anything. It produces and spawns interceptors which are
independent and targetable(but not capable of taking orders) units, which then
go out and attack the carrier's target.

The unit, by itself, is closer to a building than an actual unit, because the
player has to manually queue up interceptor production, which has a resource
cost and takes time.

Since it does spawn the interceptors to attack, there are a lot of behaviors
that it shows that other units don't. For one, the maximum range to a target
where it can start to attack is fixed, like most units. At that range or
lower, the carrier will launch it's interceptors, which will attack the
target. However, there is also a longer "leash" range, where the carrier can
move away from the target, after the interceptors have been launched, and they
will keep attacking the target until the carrier goes out of the range, at
which point the interceptors will go back to the carrier that spawned it. An
explanation of this behavior can be found here:
<http://www.youtube.com/watch?v=1Rqx8s2qKXM>

Also, when the carrier dies, all interceptors that it has launched die.

------
acabal
This is such an amazing blog. It's fascinating to read about the sloppy guts
of games you spent hours on in your youth.

It's also a testament to Blizzard's dedication to polish, because although I
was only ever a casual Starcraft player, I spent more hours on that game than
any other game in my life and I never noticed any bugs that betrayed the
apparent messiness of the codebase.

------
ChuckMcM
I remember thinking to myself, at a talk given by an Activision employee on
some Mechwarrior pathing issues, that these guys were re-inventing printed
circuit board layout.

They had the same sorts of constraints, go from here to there, don't cross
certain types of 'terrain' (traces in the layout case). Game units don't get
to make vias though :-)

~~~
AnIrishDuck
Pathfinding is a much easier problem than circuit routing and can essentially
be solved in O(n + k) where n is the number of nodes and k is the number of
edges between nodes.

Circuit routing is an entirely different beast. A previously routed "shortest"
trace from one node to another can obstruct a much shorter trace between two
unrelated nodes. In this way it's similar to the traveling salesman problem,
where early "greedy" choices made by the salesman can force him to make much
less efficient choices later.

I remember circuit routing was an example in Skeina's Algorithm Design Manual
[1], and believe he proved that it was indeed NP-complete, not polynomial like
the general pathfinding problem.

1\. [http://www.amazon.com/Algorithm-Design-Manual-Steven-
Skiena/...](http://www.amazon.com/Algorithm-Design-Manual-Steven-
Skiena/dp/1849967202/)

~~~
ChuckMcM
_"Pathfinding is a much easier problem than circuit routing"_

I'm not sure I agree with that, the mechwarrior talk was pretty informative
and the variability of terrain and dynamic obstacles made for some interesting
challenges. It was particularly interesting when they talked about 'squad
walking.' (going into a line in tight spaces etc) When I was thinking about
writing my own RTS I did some simple experiments and certainly got a feel for
it being quite complicated.

~~~
AnIrishDuck
I was confused by your original comment. You're absolutely right though;
trying to path a squad of _multiple_ units so that their routes don't conflict
is much harder. I can see how it could be very similar to circuit routing.

Heck, it probably has the same basic time complexity and is amenable to the
same algorithmic solutions.

------
kevinh
It's pretty cool to see the source of this. Back when I used to play Starcraft
I primarily played UMS maps (custom game modes) and several of them were based
on using "bugs" in the game engine to surmount situations that appeared
impossible.

Moving a harvester unit past an invincible wall of enemies was one of these,
which was accomplished by right clicking on a further mineral field. It's
interesting to see that this was an intentional design decision.

Other tricks in those maps were definitely bugs, like the ability to
infinitely cloak burrowing units by using an arbiter and other ones I can't
remember. I think they fixed that bug though (although it would be unlikely to
occur in real play).

Now that I think about it, there was one other trick in those maps that likely
was a similar hack to fix a bug. You could destroy a siege tank if you tried
to siege a tank in the location a terran building was landing in. It seems
like it was a quick fix to two immovable units taking up the same position.

Reading these blog posts is always a treat.

~~~
TeMPOraL
AD. exploding siege tank, it was actually a fix in one of the patches. Some
players discovered that you could land a building on a tank if you time the
landing right with switching to siedge mode, making the tank unreachable for
meelee units (which were the kind of units usually used against the tank). It
created an unfair advantage, so Blizzard removed it by making the tank explode
when landed on.

Funny fact: if you landed a building on your opponent's tank, you could
actually get a label "Kills: 1" on the building :D.

------
stcredzero
_> Others, like a multiplayer synchronization bug, would pop up and require
dedicated attention from several members of the programming team — sometimes
weeks of effort for a single problem. Other game developers have reported
similar experiences with their sync bugs: Ages of Empires and Supreme
Commander._

This seems like a pain point that's an opportunity in disguise. A technology
that made it much easier to get multiplayer sync correct would be an enormous
advantage.

 _> While programmers can become obsessed with finding the most pure,
abstract, clean, even sublime solution to a problem, there are times in a
project when a few sacrifices have to be made. If they’re done well no one
notices the evil compromises that had to be made, as is true for the hacks
written up by Brandon Sheffield in his article Dirty Coding Tricks._

Human beans [sic] are probably full of Dirty Coding Tricks -- as organisms, I
mean. It's just that we work well enough.

~~~
skittlebrau
I worked at Ensemble Studios (Age of Empires) and by the time we shipped Age
of Mythology we had much better tools for dealing with sync bugs. Most of the
run of the mill ones could be tracked down pretty quickly, but there were
still plenty of painful ones. What made them easier to track down was a more
advanced tracking/logging system for the simulation state history. The
simulation was littered with tons of sync logging code that tracked the
execution flow and values of things as they were calculated/updated. When the
state went out of sync, all the machines would dump their last couple updates
worth of logging (often several gigs) and you could diff them to see where
things diverged. If you were making a synced simulation game, a nicely done
version of this type of thing would be pretty useful to have, especially if
you made a good diff tool to go with it.

It's not completely obvious what technology you could make that would make it
easier to avoid sync bugs in the first place. You could make a good network
command-passing and simulation timing library, but in my experience the
majority of problems did not come from bugs with the networking itself. Most
of the sync bugs were from things like uninitialized variables, memory
overwrites, using user input or other local machine state directly in the
simulation without going through a multiplayer command, using a non-synced
random number generator in the sim, DirectX changing the FPU rounding mode on
you, etc. (Using a "safer" language would help with stuff like uninitialized
variables/memory overwrites of course, but at an inevitable performance cost.
Static code analysis tools are pretty good at finding these type of problems
now too.)

------
grecy
That article links to 'Dirty Coding Tricks'[1] - extremely interesting and
well worth a read!

[1]
[http://www.gamasutra.com/view/feature/132500/dirty_coding_tr...](http://www.gamasutra.com/view/feature/132500/dirty_coding_tricks)

------
tomp
I always thought that the fact that workers don't jam was one of the coolest
little details of the game that made it so awesome! I never would have thought
that it was basically an ugly, last-resort bugfix :)

~~~
rvkn
It's become such an important part of the gameplay that it's funny to think it
was just a fix.

~~~
baq
see also quake rocketjumping, strafe jumping, bunnyhopping, etc. when carmack
wanted to fix all those issues in q3arena, the players protested, because the
game was dull.

~~~
ChrisClark
And skiing in Starseige: Tribes, a bug with the jumping code. They had to
reimplement it for all the following games.

~~~
robertfw
And sadly, they never got it quite right! none of the subsequent tribes games
had the same skiing behaviour. The only reason the competitive community in
Tribes 2 has hung on for so long is that a community mod sped the game up to
be more like Tribes 1.

Forget about Tribes: Vengeance & Tribes Ascend, neither captured that same
feel.

------
GavinB
_The Protoss Carrier regularly lagged behind other units because it had its
own way of doing … everything._

The Carrier should have been scrapped entirely and replaced with a different
air unit. Even to the latest upgrades of Starcraft I, the AI simply couldn't
deal with the carrier effectively--they would always attack the interceptors
first. This made using the carrier a cheap game-breaking trick against the
computer.

~~~
john_b
...and made it one of the most interesting units in multiplayer. In
programmer-land, where all abstractions should be pure and elegant, the
carrier (as implemented in SC1) may be abhorrent, but this is irrelevant
because _the customers (i.e. the players) loved it_.

Some of the quirky behavior of the SC1 carrier was even re-implemented into
the upcoming SC2 expansion at the behest of fans. Why? Because it made the
unit _fun_.

~~~
GavinB
A fun unit in multiplayer isn't really a good excuse for a gamebreaking
behavior in single player.

An examination of what it was that made the Carrier fun might have revealed
ways to get similar effects (long range, able to fire while retreating,
requires paying minerals for continued use . . .) in a unit that wasn't such a
weird gamebreaker. Most people just liked Carriers because it cast a field of
enemy unit and Ai stupidity around it. Once players get attached to a unit,
you may be stuck keeping it in the game even if it's not really good for
overall playability.

Just because it worked with this one unit doesn't mean the overall game
experience couldn't have been better with something different in there. But
once something is introduced, status quo bias takes hold in a major way.

Edit: I'll concede that you want the AI to be stupid in some ways so that it
can be exploited. The Carrier just always seemed to me too extreme.

~~~
jlgreco
Starcraft singleplayer always seemed sort of like Q3A singleplayer to me.
Clearly not the main attraction.

~~~
wmil
It was a lot more like Quake 1 single player. Many people spent more time on
the multiplayer, but many people only played the single player.

------
thisisnotatest
I got a kick of reading about how this hack was one of the things that enabled
StarCraft to be released. As an eager 12-year-old, it seemed like I couldn't
get it soon enough. But as a software engineer now, I can't stop cringing at
this story.

So much of the discussion here is focusing on SC and SC2. What about the
software development aspect of this story?

What's the moral of Patrick Wyatt's tale? I mean, it's hard to argue that
there's some parallel universe where Blizzard did things differently and
StarCraft was an even BIGGER success. What would that even look like -- it
became the national pastime of several countries, instead of just one? Yet I
can't help but think how expensive it must have been for them to have made
these poor decisions in design, implementation, and planning, each one
compounding on top of all the previous ones, constantly delaying their launch.

So is the moral of the story, "here's why you shouldn't code for 'two months
from launch' mode"? Or is it, "when the chips are down, you can take or leave
all your fancy MVCs and UMLs, they don't make the difference between a mega-
blockbuster and a dud or vaporware"?

------
barbs
The "passing through other units" bug is well known in the community as
"Mineral Walking"

<http://wiki.teamliquid.net/starcraft/Bugs#Mineral_Walk>

Also, I wonder if the author has thought of getting his articles on Starcraft
(and maybe Warcraft 2) into Korean? I'm sure there'd be a huge audience for
them.

------
snippyhollow
If you want to experiment with StarCraft's pathfinding, you can, with BWAPI
<http://code.google.com/p/bwapi/> . Particularly, there is some reverse-
engineering information on pathfinding here
[http://code.google.com/p/bwapi/issues/detail?id=190&cols...](http://code.google.com/p/bwapi/issues/detail?id=190&colspec=ID%20Stars%20Type%20Priority%20Status%20Milestone%20Summary)

------
glesperance
Here's an interesting list of bugs [1] (some related to path-finding some not)
found in SC / Broodwars.

[1] <http://wiki.teamliquid.net/starcraft/Bugs>

------
jiggy2011
I've been curious for a while as to how path-finding gets implemented in real
world games.

For example, the common algorithm appears to be A* where you use some
heuristic to guess the most efficient path but update the path when you find
another is more efficient (for example you hit a large wall on the first
path).

This is easy enough when you have only one moving object (because you can just
compute that path at the start and then follow it), however in a real game
there are likely many moving colideable objects and you might choose a path
that causes you to get stuck or have to take a very suboptimal path.

The most "correct" way to do it would be to recalculate the path for each
moving object on each frame, but this would probably lead to unacceptably poor
performance.

So you can wait until you get stuck and then try and find a path out (which
may be impossible). Or you can divide your path into recursive sub-paths and
compute different sub-paths as you move.

Now for simulation this is interesting, for example if you order a military
unit to move to some location in real life then you would expect them to at
least consult a map before setting off however there may be unanticipated
situations on the ground which mean that they have to take a suboptimal path.
So pathfinding inefficiency might add realism.

I have noticed that overall path finding is much improved in modern games,
especially RTS. So curious roughly how their implementation works.

~~~
Paradigma11
you can find tons of information here: <http://aigamedev.com/> the most
interesting stuff is behind a paywall, tough.

------
systematical
You can see this when the workers run out of minerals and boom they expand all
over the place. Awesome read and makes me feel great about some of my own git-
r-dun hacks :-)

------
Havoc
Nice article. Good balance between tech details & understandability.

Never really noticed path finding issues (well no more than other
games)...except that one time I attempted a massive zerg rush. If you've got
enough of them the pathfinding algo craps itself and sends them into the enemy
base +- individually. So much for rushing...

------
d0m
There was a fun bug with zerg in the early days of Starcraft where you could
build everywhere on the map even your drone wasn't there. I don't remember
exactly how, but I know it was using a mineral path-finding bug :O

------
glesperance
I wonder what part of their path finding algo created a glitch like the drone
float[1]

[1] <http://www.youtube.com/watch?v=7MN0wjoqmzU>

~~~
duskwuff
I suspect a hack was involved -- the animation leading up to the construction
of a Zerg Extractor involves the drone hovering over the geyser temporarily.
This requires the unit to be put into a "floating" state which wasn't properly
cancelled if the build failed -- queueing up additional move commands would
then allow it to clip through barriers.

A number of similar bugs with queued commands existed. I get the sense that
this feature wasn't adequately tested. :)

------
Aardwolf
I'm not a professional player but I also noticed back then that harvesters
walked through each other! I thought it was done on purpose for this reason -
and this confirms it :)

------
rtpg
Am I the only one who is bothered by the fact that changing the perspective
rendering somehow forced them to go and change the pathfinding? How recent is
MVC design patterns?

