Monster GANs: create monsters for your game

How to generate novel monsters for your game or just for fun.

In this blog we are going to generate monsters. To do this we are going to use something called a Generative Adversarial Network (GAN). This is a special type of generative model that can, given some set of inputs, generate totally novel outputs. GANs learn features/traits from the input data and try to produce outputs that will have similar features. In this blog post I’m going to generate monsters you could use in your indie game. This could save you many hours of work. Generated monsters are also a great starting point for further art work.

We will turn random colored noise (64x64 pixels):

Into monsters like these (64x64 pixels):

Dark Spirit
Angry Fire Monster
Floating Eye or Magic Spell
Horned Demon
Crazed Blue Chicken

We will produce a cool animation at the end so read on!

Here are the steps we’ll take:

1 — Collect and prepare the data.

2 — Create a GAN.

3 — Train the GAN.

4 — Generate monsters!

1 — Collect and prepare the data

We need data that looks like monsters. I started going scrounging up pixel art on pinterest and other places but the problem with most of that is that its not at the same resolution and its not at the same style. While you can deal with both these issues I wanted to keep things simple. Eventually I settled on using some open source pokemon art found on 2 different pokemon community forums. Overall in my dataset there’s 14,774 JPG images of varying sizes. I’m calling this dataset the mgan, ‘monster gan,’ data set.

The prepared mgan dataset.

2 — Setup and GAN Creation

Now we’ll start laying down some code. We’re going to use pytorch to create our model and train it. I do not recommend that you run this without a powerful GPU. If you need a GPU check out Floydhub. You can pay by the hour there and it’s pretty affordable. In a GAN our generator model is going to learn how to make monsters by trying to make some, then asking another model ‘does my monster look like a real monster?’ This other model will be called the discriminator. The discriminator will tell the generator how bad its attempt to create a monster was. The generator will then take this information and improve its parameters to hopefully be able to generate better monsters. We repeat this process 100–200 times and eventually get a generator that can create novel monsters.

Let’s load some data:

This code should output a pokemon, mine looks like this:

I just wanted to check that we could read and output one image from the mgan dataset. Now we’ll get to the good stuff. The GAN, the stuff that actually generates new monsters:

This looks long but if you read the comments it’s not too bad. Basically it just describes a generator model and a dirciminator model and then creates one of each.

3 — Training the GAN

During training this should output lines like so:

They show the epoch (the training round) and how bad the generator is at generating images, and the discriminator losses, which show how good the discriminator is at its job. These values are not necessarily interpretable. Each line shows an image of 64 sample monsters created by the generator from the fixed_noise value. The quality of this image should be increasingly relatively steadily. Every epoch’s generator is saved with the epoch tacked onto the end so if you see one that generates particularly realistic monsters or a style you prefer you can just use that generator from that epoch.

4 — Generating Monsters!

I trained 125 generator epochs and in the end I decided that the generator from epoch 90 was the best one (choosing is more art than science). After generating the monsters you may notice most of the monsters generated look like blobs or, for rick and morty fans, cronenberg monsters. This doesn’t actually matter; we can generate an infinite number of monsters by passsing in new random noise. As long as a few are decent we can just keep generating monsters until we get enough good ones. Let’s generate monsters!

This could output something like this:

Most of these just look like blobs but some are cool. These two are my favorite from this batch:

Cute Seahorse and Shadowy Eye

If you re-run the noise = line you’ll keep getting new monsters. You may notice some similar monsters generated each time. If you keep generating though you should be able to build up a pretty decent collection of unique monsters.

Conclusion and GIF

You can see the full notebook code for this blog post here.

In this post we walked through how to use a GAN to generate monsters. You can use them in your games/game prototypes. You can use them as a starting point for more developed artwork. You can use them just to get ideas. GANs are a really great cerative tool and a lot of fun. One warning though: it is possible to spend a week messing with it and have it not work, stick to the numbers here and you should be ok.

Room for improvement:

  • removing colored backgrounds from the inputs that have those would probably improve our generator, black backgrounds were kind of…awful.
  • more experimentation with leaky relu activations in the generator
  • trying a wasserstein gan loss function

As promised below is an animation that illustrates the process of training of the generator each frame is a snapshot of its progress as it goes from grainy to crisp and detailed:

Signup for my newsletter. It’s about machine learning for video games. There will be more blogs in the future about generating content for games.