stylised trees

Game a week challenge - building a complete Roguelike in only one week

Jul 25, 2020

Blog GameDev Game a week Roguelikes

I have been delving into game development for some time now, coming up with basic ideas, dreaming about the ultimate game I would like to make. Experimenting and learning. I have noticed myself getting stuck in a bit of a loop where I create assets for a few weeks, then work on gameplay logic for a few weeks, then ultimately decide I want to remake my assets and vice versa.. After stumbling across an article Game A Week: Getting Experienced At Failure I realized I had never actually created a finished game. I had many prototypes and ideas but nothing I could call a completed project. So I set myself the challenge to create a game in one week!

I adjusted the rules a little to reflect my life situation. I am employed full time and have a young son so time is limited. I figured I could allow 2-3 hours in the evening before bed and maybe if I was lucky a little extra on weekends. If I gave myself 8 days I would have a total of around 16 -21 hours to finish the project. With my supportive partners' blessing I set forth to build my game.

I ultimately decided to build a roguelike for a number of reasons. I had experimented and created prototypes in this genre. It is one of my favorite genres. And although I would be using Godot + C# and not Python, I could use the complete roguelike tutorial as a kind of reference to help plan my time. There is also a 7day roguelike game jam that happens yearly, though I was too late this year I thought it would be fun to do anyway.

So what is a Roguelike exactly? It is a role playing game genre based upon the 1970s game Rogue which used ASCII characters to represent the world items and enemies. There are now many different types and sub genres of roguelike games however some common themes include randomly generated content, usually the dungeon you will be exploring and permanent death, once your character dies you need to start the game over.

So Whats the Plan?

I set out with a basic plan loosely based on the Complete Roguelike tutorial from RogueBasin I would be using Godot to build this game so some parts would be made much easier.

  1. On day one I would do parts 0-2 of the tutorial. Render my character on screen, and create a room for him to move around in.
  2. Day two I would tackle part 3 Random dungeon generation. Although I have done it before there are always issues that crop up with this and I knew I needed to specifically set apart a whole session for this.
  3. Day three I would skip part 4 of the tutorial and do 5 and 6 adding enemies and combat
  4. Day four I would do parts 7 and 8 create player inventory and interface
  5. Day Five Would jump to part 10 saving and loading games
  6. Day six would be player progression 11, 12 and 13
  7. Day seven would be playtesting and adjusting difficulty
  8. I allowed myself an extra day for polish and whatever else I could fit in.

Did I stick to the above plan and implement all of this? Not likely! But did I create what I set out to do? Absolutely!

Day One

Okay let’s do this! I set off to a flying start as is usually the case with a new project! Filled with optimism and creative juices I fired up Godot and got to work. First on the agenda was the player character, I knew I needed a simple tileset and would be okay with using free assets for this challenge. After perusing OpenGame Art for a couple of minutes I settled on Kennys micro roguelike pack. This map includes a bunch of monsters, characters, items and wall tiles. Everything I needed!

Kennys micro roguelike pack

Godot made the rest of this task simple, I created a Sprite node and texture atlas from the above asset and set the region for my desired character. Running the game and I have my character on the screen!

Next step was to create some controls. Godot also had my back in this department. I opened my project settings and created input events for movement up down left and right. I attached a script to my character and updated his position on button press. At this stage I also decided to create an autoload script to hold game settings. I added my desired tile size here (would end up being the only setting) and added this to the amount my character would move.

Last on the agenda for the night is a room to move around in. I created a TileMap node and some autotiles which was something I had not used previously. I assigned a texture atlas and created a basic room. Time to call it a night!

Day two

As predicted, random dungeon generation was more complicated than initially thought. I opted for a simple random room placement algorithm, this part was easy, I simply used a random number generator to create Rect2D’s with random width, height and placement. Then a basic check to ensure they don’t overlap with one another. Next I fed this grid to my tilemap and boom a bunch of rooms appeared on my screen. What use is a room with no corridors to connect them? I don’t know why but I always struggle with corridor logic. I have tackled this problem a number of times but was determined to do it mostly from memory. I did not get this working correctly at this stage.

A pitiful attempt at a random dungeon

The good news from day two is I got player collisions with walls working! I simply added collision areas of the desired tile size to the north south east and west of my character. Then before moving I would check that they do not overlap with a wall.

Day three

The plan today was to get enemies placed on my map. I put this out of my mind and re-examined my corridor logic and got an implementation working in a very buggy fashion. I also added a temporary goal in the form of a treasure chest that would appear in the final room.

I Did not get to the enemies as planned.

Day four

It was around this stage that I began to forget to take notes. Up until this point I had my trusty pen and paper, a word document and my plan/roadmap sitting in front of me. This regrettably has now been thrown out the window.

I got straight to creating some enemies and having them appear at random locations on the map, while I was doing this I also added some random pick ups in the form of health potions… the enemies and potions currently do nothing.

My tilemap needed some work as I had not set enough tiles for auto tiling. This led to weird corner tiles in some layouts as well as unexpected collision errors. It was possible to exit the map and walk off into oblivion!

Some enemies appear

Day five

I added a basic AI to the enemies allowing them to move. I use the term ‘AI’ very loosely here as all it really consists of is picking a random direction, and if there is nothing in the way moving there.

I parented the camera to the player and set it to active. This meant the player would remain in the center of the screen and enabled the ability to explore larger maps.

I scrapped the idea of having the ability to load and save games.. However, a title screen has made an appearance!

day six

Having the player and enemies jump around by a full tile each move was a little jaring so I decided to smooth the movement. I did this by creating a target position each move and updating the current position in each frame until the target was reached. This looked a lot nicer but caused some headaches later when I tried to introduce combat.

At this point I noticed that my code base was getting a little messy and enemies, the player and pickups were starting to share similar logic. I experimented with a base entity that enemies and items would inherit from. I set myself a timeframe to get this working but was not quick enough so scrapped it. Time is of the essence so a simple but messy system is better than a robust non finished system.

I moved onto creating level transitions and replaced treasure chests with stairs. I briefly forgot about clearing the existing tiles and entities which led to an interesting effect of multiplying rooms, players and enemies. I actually quite enjoyed the fact that if you traveled far enough into the dungeon you would end up in a single giant room jam packed with enemies! I fixed the bug anyway.

It was time to think about a theme or story and how I can roll this into a passable game with start beginning and end. As I had already implemented treasure chests I settled for the premise that you were sent to this dungeon to retrieve x amount of treasure, culminating in a boss fight with the treasure thief. Surely I can pull this off in the remaining two days... can't I?

The title screen

Let's implement some combat mechanics! If the player is within x distance of an enemy, the enemy will stop being random and follow the player. A simple implementation for sure but a small typo in my algorithm caused me some headaches. By this time I was getting very tired and called it a night with enemies jumping all over the place.

day seven

Remembering the pains of the previous evening I promptly ignored fixing the combat and AI moving straight to the graphical user interface. I added an icon for player health player attack power and treasure collected as well as a global system for updating these values.

Pickups now have a purpose: potions heal health. Swords add attack power(damage) treasure chests are collected and add to the players total score. The win case for the game is to collect a set amount of treasure. Upon reaching this amount a you win screen is displayed.

Graphical HUD

Against all my expectations I managed to Iron out the combat and added a basic movement effect where if an enemy and player converge on the same tile they bounce back to their previous tile and deduct some health. Created a game over screen and went to bed.

final day

The final day! By this time I was getting a little over the project but was determined to see it through. So what can I achieve to polish things up? I perused Open Game Art and found some fun music for my title screens and game over screen. Some basic sound effects for combat and item pick ups really pulled things together. Item pick up sounds posed a challenge due to the item being removed before the sound had finished (or even started) playing. To solve this I moved the sound to the player sprite and reused a signal that updates the GUI to also play the sound.

And that’s the project. Done!!

Postmortem

Things I liked about the project

The way sound/music bought it all together in the end and how easy it was to implement using Godot was very cool.

I really liked the way that a time constraint caused me to think creatively and objectively. The way I had to pivot or outright scrap ideas but still build out a finished game was actually very fun! I learned new features of Godot and bent some rules to fit my project's needs.

And in the end, I had completed a game!

Things I did not like about the project

The core gameplay loop is fairly boring. Pushing direction keys to move around (sometimes large) dungeons is not very fun. I really wish I could have spent more time ironing out the level sizes and balance out the move / interaction ratio.

The progression is also somewhat dull, roguelikes are fun because you are constantly finding new gear, leveling up and fighting new monsters. The only progression present is picking up swords for attack power and going to slightly larger levels. This however was something I expected as designing a good progression system is not easily done in a matter of hours.

The project and code got really messy towards the end this led to things becoming a bit unwieldy towards the end.

I do plan to revisit this project at some stage to address the above issues.

Roadblocks and what set me back

Although I had planned extra time for dungeon generation it set me back even more than I initially expected. None connecting corridors, random island rooms that were not reachable or that the player would get stuck in. Strange gaps in wall collision areas allowing enemies to wander out of bounds. It all added up.

AI and combat also took longer than expected. Although I went for a simple system, Switching to a smooth transition of tile movement made it harder to tell when a monster should / could attack the player. Add some simple typos to the equation and strange unforeseen behaviour was rife!

Conclusion

Letting go of Expectations

Many places I knew I needed to clean up and refactor my code, many times I thought it best to forge ahead with features rather than spending time refactoring, at times I regretted this and the software engineer in me was rather unhappy with this choice. But I think it was the right choice to make in order to bring everything together. After a breather maybe I will revisit this project for some much needed cleanup and refinement.

I really wanted to add more progression in the form of gear pickups and level ups and I wanted a more cohesive gameplay arc with a proper introduction, mid game and conclusion. I dropped the final boss battle due to time constraints and I think this would have helped immensely.

All in all I am very happy with the way things turned out and Funnily enough, although I have yet to beat the game, it has grown on me :)

Latest Games

Sentinals of Cyrux
Sentinals of Cyrux

A short rogulelike game

Play Now

Hive Mind
Hive Mind

A dystopian stealth game

Play Now

Minotaur Madness
Minotaur Madness

Medieval wave shooter

Play Now

Wizards Treasure
Wizards Treasure

A short rogulelike game

Play Now

The Flight of Ajax

Cyberpunk Stealth Mahem


Sign up to be a Beta tester