Creating the random enemy spawner, improving performance

When building my Win8 port of Super Rawr-Type, I ran into all sorts of performance issues, due to lack of optimization. This was to be expected, as I on gave myself 1 month to complete the base game, then I would take the second and final month to port it to different platforms and worry about optimization.

The design of my levels is where most of my issues came from. I explain it pretty well in this post here. The gist of it is this: When the map loads, it is filled with ~150 enemies, which are constantly being updated. Obviously this comes with quite a bit of overhead. The browser version played well, but on a dedicated OS it chugs.

Removing all enemies

I went back to the drawing board and redesigned the way I spawn enemies now. The first thing I did was remove all entities (enemies) from the level.

I looked at a number of different ways for spawning enemies for shmup and bullet hell. Matt and Jason Doucette at Xona games do it in an interesting way for their upcoming title Duality-ZF: They store all of the enemies in an excel spreadsheet, which is then parsed by their game engine and appropriately draws the entities on screen.

Then again, they are using C# and running on the Xbox, whereas I’m running JavaScript on a PC, so JSON may be a more appropriate format here, if I were to take this approach. I don’t even think the Xbox has a way of parsing JSON; I know that Visual Studio just adopted JSON.NET, so it’s doubtful that the 8 year old Xbox has the ability to do the same.

Creating the Random Enemy Spawner

I found that my best approach was to create an entity, Random Enemy Spawner which sits just off the right side of the screen, and is always aligned on the Y-axis with the player. For debug purposes, I threw in placeholder art which is a copy of the player’s ship, and had it sit on the edge of the screen so that I could see not only where my enemies spawn, but also how frequently.


As you can see here, the enemies and spawner are all aligned on the X-axis. This may appear as though the enemies come in flat waves, but to counter that I have them all spawning on a timer. Three timers, actually.

I broke the enemy ships into three groups, and one example is illustrated below:

 * randomFromTo
 * Random number generator
 * Courtesy of Liza Shulyayeva's flea project
 randomFromTo: function (from, to) {
     return Math.floor(Math.random() * (to - from + 1) + from);

 * spawnEnemyGrpA
 * Spawns 1 of 2 types of enemies at random intervals
 spawnEnemyGrpA: function () {
     // Resets random number
     var rndNum = null;
         // Rolls a random number
         rndNum = this.randomFromTo(1, 10);

     // Spawns enemies within the Y bounds of the screen
     this.randomSpawnLocY = this.randomFromTo(ig.system.height - 20, ig.system.height / 20);

     // determines which enemy type will spawn
     if (rndNum > 5){, this.pos.x, this.randomSpawnLocY);
     if (rndNum < 5){, this.pos.x, this.randomSpawnLocY);
     // Resets timer

I use spawnEnemyGrpB and C to spawn different types of enemies. They are set on timers like this:

 * init
 * Handles initialization
init: function (x, y, settings) {

     // Spawning timers for enemy ships
     this.spawnTimerGrpA = new ig.Timer(this.randomFromTo(3, 9));
     this.spawnTimerGrpB = new ig.Timer(this.randomFromTo(3, 8));
     this.spawnTimerGrpC = new ig.Timer(this.randomFromTo(4, 9));

These timers are responsible for triggering enemy spawns at random times, which is what allows for a staggered appearance on screen.

I’ve noticed an incredible performance improvement from this, although it has been tricky to balance the difficulty. What I really need to do is create a variable that affects how frequently enemies are spawned, and that variable will adjust based on the chosen difficulty level of the game. A higher difficulty will obviously spawn more enemies at once.

The EnemySpawner.js class can be found in its entirety on my GitHub.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s