The “Roguelike” genre of video games originated from a dungeon crawling game built in the 1980s on a Unix system called “Rogue”.
In “Rogue”, you were tasked with fighting your way through a dungeon, with enemies and monsters trying to stop you from reaching the end. Since the original game was made before we had allocated much time toward video games in general, especially with graphics, “Rogue” was made with a simple user interface that used letters to indicate monsters and obstacles.
Nowadays, we can use much more vibrant graphics and sound effects, but the core gameplay hasn’t changed much over the past 35 years – you, the player, must travel through a dungeon, past obstacles and enemies, in order to reach the end. A roguelike game contains two important aspects to it – Randomized gameplay, and “permanent” death.
The first element, randomized gameplay, refers to the fact that levels are not hard-coded into the game – when the game starts, the game rolls a random seed and uses it to determine factors such as size of the dungeon, shape of the dungeon, what elements will exist inside it, what powerups you may find, what enemies you may find, etc. This helps to up the replayability of the game, as you will never have the same level twice.
The second element, permanent death, refers to the fact that the are no “extra lives” or “1-Ups” or anything of the sort – your hitpoints reach zero, you die, end of game, start over from the beginning. This ups the difficulty factor of roguelikes, ensuring that you actually care and pay attention to each run through the game.
With all of this in mind, what was the goal of this tutorial series? What was I eager to learn? For starters, I am not new to the Unity scene. I have been working with Unity since my senior year of college, using the program to create our end-of-year capstone, a space shooter which was also inspired by roguelike genres.
My goal here was to make – or at least put together the framework for – a cohesive game which I might be able to pick up in the future as a full product if I so chose. I used the Unity tutorial series found here on the main Unity website.
The project itself started pretty straightforward – import assets, make character and controller gameobjects, and create prefabs. The only portion of this content I had no familiarity with whatsoever was animator controllers – a set of predetermined states that would define what animation a sprite would play at what time. I had not worked with animated objects before, so this was a minor challenge for me.
All was going well, however, as I neared project completion, strange issues started to arise as I started writing the Enemy AnimatorControllers. For one, the Player AnimatorController suddenly slowed itself down to the point where the chopping animation wasn’t smooth at all.
To date, I still do not know what caused this significant delay, as it was not the case during development and initial testing.
Another fairly major issue that arose involved player movement. Since the player is technically not locked to a grid and moves via movement vectors, if the player received input too fast, he would move in a strange pattern toward his actual destination, or worse, get stuck inside walls and enemies.
My initial solution was to speed up the player drastically, but by hammering the directional keys really fast I could still end up off grid. The eventual solution I worked up was to completely ignore any input at all while moving.
Another issue arose with the enemies themselves.
As enemies did not have proper pathing, they could not detect walls in their way and as such could not properly chase the player around them unless the player was standing right next to them. The tutorial was not meant to have such an advanced AI, however, implementation of such an AI is a challenge I would love to take on in the near future.
Overall, the project, while quite a bit buggy in the state that the Unity tutorial had left it in, was worth the time it took, as I still learned quite a bit about development and the quality of thorough testing and playtesting.