In my final year of university I was tasked with researching a subject in the computer science field that I could use for my dissertation. As a gaming fanatic I instantly thought about the opportunities close to heart, and also close to personal experiences.
At the time I’d spent a ridiculous number of hours, and I mean almost seriously ridiculous, into a couple of procedural generation games by the names of Spelunky and The Binding of Isaac.
These were games I knew very well and had a large working knowledge of the mechanisms at play. So I thought on procedural generation and what role it had had in games beyond those two. I came to learn about it’s role in recent AAA games such as Borderlands’ gun system, the Shadow of Mordor’s ‘Nemesis System’, the item placement in Left for Deal; Also it’s rich history in things such as procedural spooling when games used procedural generation to create levels such as in Darkstone or texture certain games due to memory limitations.
I had my subject matter now I just needed a question to research. I took another look at the number of hours I’d put into my procedurally generated games, these were indie games, well done but indies all the same. They didn’t have necessarily the polish a AAA studio might have, so was there something about procedural generation that left me more immersed than just a normal static game experience? I now had my question and could begin work on my paper: Procedural Generation & It’s Affect on Immersion.
I won’t go into the study itself, I’ll leave that for a blog post, but I will go into games I made to test my theory of procedural generation prolonging immersion. I had to make a static game and a procedurally generated game as near to the same as I could possibly make them to be fair, and I’d had previous experience in the Unity game engine so I decided to make them in that. Due to the time constraints on the project I had to make a less elegant version of the game I decided to base it on – Spelunky.
The most important aspect of the game was getting the level to generate, I knew from Spelunky that the designer Derek Yu split a level into 9 sections and loaded prefabs into those sections. I reasoned that I should make my game smaller in scope again due to the project constraints and my abilities at the time with Unity. In the end my levels ended up being split into 4 corners each with a list of 10 prefabs to be loaded, this meant that there was a possible 10,000 combinations open to me.
There is a small issue however, half the two top corners had a player spawn point and half the two bottom corners had an exit point. It wouldn’t do to have 2 players or 2 exits on the map, that’d be confusing. So the possibilities had to be whittled down, now only 5 top left corners would work with 5 top right corners and vice versa, so the top half went from 100 possibilities alone to now 50. The same is true for the bottom half which meant that the total level possibilities were now 2,500, substantially less but still plenty of options.
By this point I had my options laid out quite neatly, things like score, lives, level transitions were all simple, now I just needed to get a pseudo-randomness going within the game to generate the 4 numbers that would correspond to map prefabs. Thankfully Unity has a random class where you can call upon a value between 0.0 and 1.0, I reasoned that maybe I could use that, multiply by 10 and round down or up to get values 0-9 or 1-10. However I knew that asking for a random value would simple just ask for values from a list with no order but it would be the same every day, instead I needed to create a seed value, again thankfully Unity uses such a function.
A popular way of creating a seed value is to take the systems time value, that way every second of every day you would reasonably get pseudo-random values. At last I had a way to create a seed value, I knew which corner prefabs would work together, and I had a way to create objects in a scene. In my GameManager script variable I put this all to use, at the start of every level it would run it’s ‘Start()’ function which I used for my level generation.
At the top of this block of code is the creation of the seed by using the systems own time value. Then the top left (tl) and top right (tr) corner values are created by getting a random value and multiplying by 10 and rounding. Next is a while loop, this is where the error correction jumps in, instead of generating two random numbers again and testing to see if they’d work. I instead say that if the top left value is below 5 as is the top right OR if the top left value is above 5 as is the top right, regenerate the top right value until it’s either above or below 5, opposed to the top left value.
After that is the exact same process for the bottom left and bottom right values, and the same error handling while loop. Then at the very bottom I utilize Unity’s own instantiate function to load prefabs by name (the “TopLeft/[tl]” part), a position on the map, and a rotation value (since the rotation never changes the “.identity” value is always used).
From that point forward the code added to the game was fairly typical game code, saving score in prefabs so they could be carried across levels, destroying objects and increasing score, player control and animation, etc.
That’s how I handled procedural generation in the Unity engine. Looking back at the project, it could have been set up a bit more elegantly, and given a larger time-frame I would have liked to create a more robust system with larger levels. If you’re interested in the findings of my dissertation I’ll make a post over on my normal blog, and if you’re interested in playing my game, I warn you it’s not polished but you can do so if you’d wish. Just leave a comment on this post and I’ll set up another post with a link to download a zip file containing the executable and data folder.
Until next time, keep designing, have an awesome day and thanks for reading.
Recently I decided in order to make some of these articles more jazzy when I finish a game, I should give you a demo! Now there are some caveats with that, right now I’m not doing any downloadable content but that will come in time, I’m undecided on giving source files or just the game. Regardless, right now I’m putting my games up on Itch.io, this means that if you’d like to play my games through your browser, you’ll need to be using
A) The latest unityweb plugin
B) Firefox, Internet Explorer, Safari, Opera (you can use Chrome if you’ve certain extensions allowing certain APIs that were removed a while back I believe)
Without further a-do here is my dissertation!
In the event it doesn’t load, there are several simple solutions – clear your cache with CCleaner, simply reload the webpage as the game can timeout if the loading is taking too long, or just try another one of the browsers mentioned above.