# I need an enemy spawning algorithm for a 2D tower defense

I need an enemies spawning algorithm for a 2D tower defense game. I have 4 maps, each has 4 stages and each stage has 40 rounds. I need to create an algorithm which will instantiate waves, increase health and change their type in new rounds, new stages and in new maps. I need your suggestions and ideas to resolve my problem.

It should be done like in geoDefense and Fieldrunners.

Lets take an example which is somewhat in my mind:

MAP1- Stage-1, on Rounds 1,2,3,4 loop around with '+5' on it so also in Rounds 6,7,8,9 ...so on... instantiate 'Type-1 swarm' after increment(+5) add 'Type-1 swarm + some value' so that if previous 'Type-1 swarm' (on rounds 1,2,3,4) has 3 enemies, after above increment(+5) 'Type-1 swarm' has 3+some value. The rounds multiple of 5 will instantiate 'Type-2 swarm + some value', and as round increases health value should also increase.

On Map-1 Stage2/ and other Maps and stages repeat the above process with some slight difficulty and change type swarm1 and swarn2 with other swarn types.

I hope you people got what I actually need. I don't want to hardcode the rounds because there is also an endless option in my game and hard level would have 100 rounds instead of 40.

Any other spawning ideas/algorithms followed by TD game programmers/designers.

• possible duplicate of How can I specify which enemies to spawn for each round in a tower defense? Jan 5 '12 at 10:21
• this question is more specific to my query.
– Syed
Jan 5 '12 at 10:32
• I don't see how it's more specific. It's just slightly more confusing. And I think the answers in the other question still apply.. did you try any of these approaches? Jan 5 '12 at 11:04
• Fieldrunners doesn't use dynamic swarm generation, it's the same waves made up of the same units each time. If you want a consistent user experience that you can tweak, you're better off building levels yourself. Jan 5 '12 at 11:46

If you want infinite rounds define 2 functions for each enemy type, one will determine health of the enemy spawned, given the round number, the other will determine the number of enemies spawned, given the round number.

Functions that would be interesting (given your example) are things like Health = Math.Ceiling(round / 5) * 5 This would mean every 5 rounds the health increases by 5 more.

For simple enemies the number to spawn might just be round * 2, so each round would have 2 more monsters than the last.

Maybe harder enemies might have round % 5 == 0 ? 1 : 0, so you get a hard enemy every 5 rounds (where % gets the remainder).

You could add extra functions defining things like enemy speed etc.

• round * 2 is two times as many enemies, not two necessarily two more. Jan 5 '12 at 22:03
• If the round number increases by one, then the result of that formula increases by 2. E.g. round 10 has 20 enemies, round 11 has 22 enemies. Jan 5 '12 at 22:46
• Yeah, I'm an idiot. Must have been thinking powers. Jan 6 '12 at 16:10

I used to made a project like this time ago with a team at the college, but in our case we just had 1 stage, what we did was calculating how many enemies will be created plus an auto-growing factor to make it massive and by the higher number only change the type of enemy and the count of then but (we never did but it can be done) never changed theirs stats, just made sure that you should build the most. It were a end-less TD.

The enemiesPerWave formula were taken from PvZMultiplayer formula, where the pwaveDifficulty was originally the number of players on it. (usefully hint to consider how it truly affect)


int Wave::enemiesPerWave()
{
int rsp = (int)((0.15 * this->pWaveNumber) * (24 + 6 * (this->pWaveDifficulty-1)));
return rsp;
}



void Wave::raiseDifficulty()
{
if(this->pWaveNumber/this->pDifficultyFactor == 1)
{
if(this->pWaveDifficulty pDifficultyFactor*=2;
}
this->pWaveDifficulty++;
}
}



Generate a enemy, type and storage it


void Wave::generateEnemies(int enemiesCount)
{
for (int i = 0; i generateEnemyType();
Enemy* enemy = Enemy::create(type);
this->pEnemies.push_back(enemy);
}
}


This could be optimized by using a Json with load N number of option, but may replace this whole function to make less hardcoded


eType Wave::generateEnemyType()
{
int actualRange = (rand() % this->pWaveDifficulty);
eType enemyType;
if (actualRange == 0)
enemyType = BLUE;
else if (actualRange == 1)
enemyType = GREEN;
else if (actualRange == 2)
enemyType = YELLOW;
else if (actualRange == 3)
enemyType = RED;
else if (actualRange == 4)
enemyType = BLACK;
return enemyType;
}


If you want to upgrade the enemies, in the enemy class they shall had a method upgrade or level up that change their stats instead of doing that in the spawning (or Wave for my use) class.

Hope this may be useful!