ProcJam (November 2015)
Since being introduced to it in University in 2012, I have been fascinated by the world of procedural generation. It is beautiful to me how you can create such varied content built from humble algorithms.
For the past year or so I haven't really done much procedural generation, so I leaped at the chance to participate in the procedural jam. I had no idea what I wanted to make, but it was comforting that there was no push to make something that is an actual playable game.
My first step was to add in my salt, improved perlin noise. As with anything, Unity3D already has an implementation of Perlin Noise. However it is limited to 2 dimensions and I wished for the versatility of 3. As such, I added my own version. I then created a few scripts that would scale and colour an object based from noise hashed from it's position. It looks cooler in motion, but I took a picture to show the differences in the 3D noise.
For the past year or so I haven't really done much procedural generation, so I leaped at the chance to participate in the procedural jam. I had no idea what I wanted to make, but it was comforting that there was no push to make something that is an actual playable game.
My first step was to add in my salt, improved perlin noise. As with anything, Unity3D already has an implementation of Perlin Noise. However it is limited to 2 dimensions and I wished for the versatility of 3. As such, I added my own version. I then created a few scripts that would scale and colour an object based from noise hashed from it's position. It looks cooler in motion, but I took a picture to show the differences in the 3D noise.
Another difference to the Unity internal Perlin Noise is that my version returns values from -1 to 1 instead of 0 to 1. It is a personal preference to work with this range. In the above image, the boxes are scaled based on this range and their RGB colour is mapped based on where their gradient value lies in the -1 to 1 range.
After I'd finished playing around with this collection of cubes, I started thinking about what I actually wanted to create.
Something I'd come across a few times in John Conway's "Game of Life". It's a simple set of rules that control cells on a grid which can be either on or off. It is a lovely demonstration of apparent complexity born out of simplicity. I'd been meaning to try to implement it at some point and decided this jam was a great excuse. Still I didn't know what the overall aim would be, I just wanted to make it.
I decided that I wanted each game to be unique to the player each time they played it and so seeded my noise function with what ever time it currently was At this early stage, I thought I might have the player fly around to observe their life as it lives and dies. I added in a realtime sun which is a fancy way for saying a directional light that I had rotate based on the current system time. From the time-based seed, I create a starting state for the game - deciding which cells to turn on and off. For convenience during testing, I placed the camera with a top-down view.
After I'd finished playing around with this collection of cubes, I started thinking about what I actually wanted to create.
Something I'd come across a few times in John Conway's "Game of Life". It's a simple set of rules that control cells on a grid which can be either on or off. It is a lovely demonstration of apparent complexity born out of simplicity. I'd been meaning to try to implement it at some point and decided this jam was a great excuse. Still I didn't know what the overall aim would be, I just wanted to make it.
I decided that I wanted each game to be unique to the player each time they played it and so seeded my noise function with what ever time it currently was At this early stage, I thought I might have the player fly around to observe their life as it lives and dies. I added in a realtime sun which is a fancy way for saying a directional light that I had rotate based on the current system time. From the time-based seed, I create a starting state for the game - deciding which cells to turn on and off. For convenience during testing, I placed the camera with a top-down view.
I also wanted to emphasise the relation to time, and so I displace the time as the start screen and then when the player starts, it stays at the top of the screen. I also wanted the player to feel like they had an impact, instead of it simply being something they watched. First, I added the ability to create new life, when the player held down the mouse that cell would become alive, and so the player could run the mouse along the screen and create waves of cells. The cells made me think of slime mould, so I ended up making the cells yellow. I felt like the player still needed more of an impact and so I went about implementing functionality so that it would start blank and the player would "seed the land". I thought a radial effect would be cool for introducing this and I'm happy with the outcome. It started from the centre but I realised it seemed counter intuitive for it to not come from the point that the player clicked. Adding in this offset ended up a lot more troublesome than I had anticipated... But I am pleased with the outcome.
I wanted the game of life to look more organic than simply popping in and out of existence. To this end, I made it so that each cell grew and shrank. A cell would be determined to be dead once it's scale was zero.
I wanted to reflect the imperfection of life. So that it didn't appear so calculated, I added in some error to the system. When a cell is born, it is given a random growth rate that ranges from the step speed and a bit slower than the step speed. The error is small and so it's barely noticeable, but it means that when you see a really symmetrical shape appear, it will eventually mutate. I also didn't want the life to be eternal, the game of life can cause the cells to enter a state of equilibrium where the cells match the criteria for not dying and no more being created. To avoid this, I added a lifetime to the cells. If they stay alive for too long, they will die.
After working with it in top-down view for so long, I decided that it was really the best view to appreciate how it plays out and so left it like that. However it still felt pretty barren so I decided to add a load of cubes to represent the floor that were coloured based on their position. This meant it was possible to see the part of the noise texture that satisfied my rules for which cells can start the game alive. To my surprise however, it ran like shit. I was confused because although every cube ran the noise function, they only did so at the start, because they didn't need to change their colour any later. I disabled the colouring script and yet it still ran shit, with just a load of white cubes dotted about. I tried changing them to quads, maybe the vertex count was to high. But that seemed like bullshit, this is a professional game engine; there was a lot of cubes, sure, but there can't have been that many vertices that the game couldn't handle it? Even after moving to quads, it ran like shit. I couldn't have this. If it was my own engine, I'd simply have a square and unload the colouring to the GPU. I was going to have to do that here... But I hadn't really delved into shaders in Unity. Hell, I hadn't written a shader in well over a year. I tried looking into it and started realising it wasn't something that would just click for me, not something I could do within the time I had for the jam. I'd need a GPU version of the noise function and some way to call it. It'll definitely be possible in unity but the fuck if I had the time to work it out. Fortunately Unity strives to make life easier for developers. I came across a function which would allow me to set the individual pixels in a texture and then assign that texture to a mesh renderer. I didn't have the time to work out how Unity manages to make the rendering side of things so slick. But this worked, I was able to get my texture image to render with no noticeable impact to performance. And even higher resolution than my boxes, ironically. There was a slight bit of faffing about so that I could increase the size of the texture beyond the play area so that it went passed the edges of the screen but overall it was pretty painless.
The final thing I added was to display statistics once all the life ran out. By this point I knew this was just a sandbox for people to play with, but as it's personally interesting to me to know statistics about the things I play, I added them in. it notes how long the game went on for (although it doesn't account for when the game wasn't being played - for example when the player is on a different screen) and how many generation (steps) the game managed. It also says what the most amount of active cells were and which generation. Not surprisingly, it's usually the first or second generation, but that's when left alone, if the player's messing about they might create a really full board.
My ProcJam submission can be found on itch.io and I uploaded a video of it being played.
I wanted the game of life to look more organic than simply popping in and out of existence. To this end, I made it so that each cell grew and shrank. A cell would be determined to be dead once it's scale was zero.
I wanted to reflect the imperfection of life. So that it didn't appear so calculated, I added in some error to the system. When a cell is born, it is given a random growth rate that ranges from the step speed and a bit slower than the step speed. The error is small and so it's barely noticeable, but it means that when you see a really symmetrical shape appear, it will eventually mutate. I also didn't want the life to be eternal, the game of life can cause the cells to enter a state of equilibrium where the cells match the criteria for not dying and no more being created. To avoid this, I added a lifetime to the cells. If they stay alive for too long, they will die.
After working with it in top-down view for so long, I decided that it was really the best view to appreciate how it plays out and so left it like that. However it still felt pretty barren so I decided to add a load of cubes to represent the floor that were coloured based on their position. This meant it was possible to see the part of the noise texture that satisfied my rules for which cells can start the game alive. To my surprise however, it ran like shit. I was confused because although every cube ran the noise function, they only did so at the start, because they didn't need to change their colour any later. I disabled the colouring script and yet it still ran shit, with just a load of white cubes dotted about. I tried changing them to quads, maybe the vertex count was to high. But that seemed like bullshit, this is a professional game engine; there was a lot of cubes, sure, but there can't have been that many vertices that the game couldn't handle it? Even after moving to quads, it ran like shit. I couldn't have this. If it was my own engine, I'd simply have a square and unload the colouring to the GPU. I was going to have to do that here... But I hadn't really delved into shaders in Unity. Hell, I hadn't written a shader in well over a year. I tried looking into it and started realising it wasn't something that would just click for me, not something I could do within the time I had for the jam. I'd need a GPU version of the noise function and some way to call it. It'll definitely be possible in unity but the fuck if I had the time to work it out. Fortunately Unity strives to make life easier for developers. I came across a function which would allow me to set the individual pixels in a texture and then assign that texture to a mesh renderer. I didn't have the time to work out how Unity manages to make the rendering side of things so slick. But this worked, I was able to get my texture image to render with no noticeable impact to performance. And even higher resolution than my boxes, ironically. There was a slight bit of faffing about so that I could increase the size of the texture beyond the play area so that it went passed the edges of the screen but overall it was pretty painless.
The final thing I added was to display statistics once all the life ran out. By this point I knew this was just a sandbox for people to play with, but as it's personally interesting to me to know statistics about the things I play, I added them in. it notes how long the game went on for (although it doesn't account for when the game wasn't being played - for example when the player is on a different screen) and how many generation (steps) the game managed. It also says what the most amount of active cells were and which generation. Not surprisingly, it's usually the first or second generation, but that's when left alone, if the player's messing about they might create a really full board.
My ProcJam submission can be found on itch.io and I uploaded a video of it being played.
What Did I Actually Do?
I took part in the 2015 week long game jam, ProcJam. The majority of the work on the game though was done over the course of 3 days. I created a procedurally generated "toy" based on John Conway's "Game of Life".