Automating the Interesting Stuff

Jack McComiskey
3 min readMay 20, 2021

Earlier this year I completed my first end to end videogame, FLO. As the first piece in my game development portfolio I wanted to demonstrate a couple of things. First, my ability to program gameplay and UI. Second, my ability to complete a project. And finally an ability to design a rudimentary top down shooting game.

A screenshot of some gameplay

Now, There are a couple of areas that are missing there. Namely, level design and game art. For game art I was attempting to lessen my focus on agonising over the appearance of game assets as this has been a problem in the past.

For level design, I just didn’t have the energy to devote to it. If we’re being honest here. I had the 3 enemy types and their behaviour programmed and had prefabs for them all. So I created 6 possible locations for them to spawn and got to work writing a script to generate myself some levels.

Each of the fan icons represent a spawn location.

My levels would be described in JSON. The levels are a list of ‘Spawn Increments’ that have a time delay before moving on to the next increment. Additionally there was a chance for a ‘blocking’ incremement to spawn. This increment would not clear until there were no enemies left on the screen. This is to give the player some time to deal with whats in front of them. Were these blocks placed at appropriate times? *Shrugs*… The name of the game here is to not think about that. So I tweaked the percentage chance of a block spawning to what seemed fair.

Inside a spawn incremement is a list describing what to spawn and where. Below is a snippet from an example level JSON.

Some sample JSON the level generation script outputs.

So I had a means to generate JSON that could describe a level. I just need to parse it at run time to instantiate the enemies and detect when we had finished reading from the level file. Below is the code that iterates and interprets the JSON file.

In my GameManager.cs I created a coroutine that would be run on a gameplay scene’s startup.

You’ll notice we are iterating through the ‘increments’ I described eariler and grabbing the details and feeding them in as parameters for our Instantiate call. We also check for the spawn.type == -1f. If that’s the case the increment is a blocking increment and will halt the iteration until there are no enemies remaining, we do this check on line 16 where we yield until there are no game objects tagged ‘enemy’ in the scene.

Beyond that we just needed to know when we had reached the end of the JSON file and that any remaining enemies were defeated. So I had levels without so much as having to give it any thought. Nice! Well, sort of.

Honestly, the levels don’t play that great. There are weird difficulty spikes and troughs and raw JSON is not the easiest format to design levels in so I was quite discouraged from making tweaks. So I generated 3 increasingly longer levels and with a lower incidence of blocking to get some progression in difficulty. Worked well enough.

This was one of the final steps I took in finishing the game. It’s no marvel of game design but this method helped me complete my first game end to end. Perhaps it’ll inspire you to also accept less than perfection and cut yourself some slack from time to time and just finish the damn thing.

You can get the source of the game here.

You can have the level generation script(Python) here.

And finally, you can play/download the game here.

--

--