Unexpected Orcs

Posted on Feb 6, 2020

Unexpected Orcs is an unfinshed (and sadly abandoned) bullet-hell Action RPG with roguelike elements. It is the spiritual successor to the unreleased flash game of the same name created by the same team of me and my cousins (circa 2011).
The project is written in a custom Java engine that uses Processing to handle the graphics side of things.
You can find the code for the project on GitHub.

Below are a few screenshots that I took over the course of development with a few brief notes sprinkled in for taste.

Note: The most recent pictures are in the screenshots section!


Screenshots

Here are a few screenshots from the game as it currently stands. There are currently 5 dungeon types, all with very imaginative names. The first three are generated using a cellular automata approach whereas the Cellar and the Grass Dungeon both generated with more advanced custom dungeon generators (the generators are discussed more a bit later!)

The Cave


The Cave

The Desert


The Desert

The Blood Dungeon


The Blood Dungeon (but for some reason we made it purple not red…)

The Cellar


The Cellar

The Grass Dungeon


The Grass Dungeon

The cellular automata dungeons (Cave, Desert and Blood Dungeon) have the possibility to generate treasure rooms filled with XP and goodies!

A treasure room in the cave


A treasure room in The Cave


Development

Initial dungeon generation

The first thing we worked on was getting some level generation started. We knew that there would be two main area types; “Cave” type levels and “Dungeon” type levels.
The cave type levels needed to be more open, allowing for better long range combat and freer movement and dodging. The dungeon type levels were made to be more restrictive, encouraging the player to get closer to enemies.

The cave dungeons are all generated using a cellular automata approach. Basically what that means is that, initially, tiles in the map are randomly set to either be a WALL or FLOOR (black tiles and white tiles repspectively). Then, based on its surrounding tiles (and what the tile is itself), the tile is set to be either a wall or a floor in the next generation. The technique we used is heavily based on the approach outlined on roguebasin, so definitely go and check that out.
There are a bunch of parameters to tweak with this technique so you can usually get the generator to give you levels with the feeling you are after.

Later in development the cave generator was also given the ability to check for rooms that are separated from the main cave and, if they’re the right size, turns them into treasure rooms (otherwise they get filled in).

Early cave generation


Example of early cave generator output

For the dungeons we initially explored two different techniques, one of which is still used for the Grass Dungeon and I’ll talk about it first. The basic premise behind it is to randomly place some rooms and then generate a maze in the space left. You then add doorways from each of the rooms into the maze and then remove all the dead-ends of the maze. This gives us a really nice, windy dungeon that is perfect for a hedge maze inspired level!
I found this technique on Bob Nystrom’s brilliant website (there are so many great articles on there!), so if you want to learn how this was done in more detail, go and have a look at that.

Early maze dungeon generation


Example of early maze dungeon generator output

While perfectly suited to an organicly styled level, we knew that those extra-windy corridors would not suit a dungeon that was supposed to have been built as apposed to an organic structure. As such we made our own rudimentry “hand-made” dungeon generator. The basic premise behnid this was to randomly place some rooms like before, but then instead of creating a maze between them, just randomly connect them together with “L” shaped corridors. This lead to an okay (ish) dungeon, but one with a lot things that didn’t make sense. We knew we’d have to come back to this one to fix it up (keep reading to find out about that!), but it was more than enough to get the project underway.

Early hand made dungeon generation


Example of early hand made dungeon generator output


Tile textures

While making the generators I got pretty sick of looking at black and white squares all the time, so we figured it was time for an upgrade. None of us are particularly artisticly inclined (being a group of three programmers, this is hardly surprising!), however we started cobbling together some okay looking pixel art.

Our first attempts left a bit to be desired. As you can see here, the colours are a bit off (the floor is basically red and the walls were far too green) and it all just looked a bit flat.

First dungeon tiles


Our first dungeon tiles

To combat this, we gave the wall tiles some dimension and worked on balancing the colours better to make a more cohesive scene. You can see in these next screenshots just how effective adding some shading to the wall tiles can be. To achieve this effect, we had to check if the wall tiles were on the “bottom” (has a floor tile below it) and assign the sprites accordingly.

Improved cave tiles


Improved cave tiles

Improved dungeon tiles


Our first dungeon tiles

While this drastically improved the overall look of the levels, it still wasn’t quite enough. To help better define the walls, we started doing some very basic texture bitmasking, which is essentially an upgraded version of what we were doing by checking for wall tiles being on the “bottom”.
Bitmasking tile textures means checking a tiles neighbours to figure out which ones are of the same type, and assigning a texture based on the pattern. There is a really great tutorial for this over here so take a look at that if you’re interested.

First we implemented the simple version: only check the tiles in the four cardinal directions (no diagonals), meaning there are 16 textures to make per wall type. As you can see when comparing the images below between the simple and final version, this leaves little gaps on the inside corners of wall tiles.

Simple bitmasking


Simple bitmasking, not checking diagonals

Final bitmasking


Final bitmaksing, checking the diagonals

We fixed this by implementing a system that is able to generate the bitmasked textures on the fly, which massively simplifies adding and modifying tile textures. Because this new system makes it so easy we were able to make the bitmasking now check the tiles diagonally adjacent too it as well, fixing the issue with the corners. We also decided to add the bitmasking to the floor tiles as well, which you can see in the image below.

Final bitmasking


Final bitmaksing, checking the diagonals


GUI

Once we had some nice looking tiles, we needed some way to see all the character’s stats and inventory on the screen. Below on the left, you can see a little mockup that we made and on the right you can see an early version of the GUI with basic health and mana bars as well as a very basic inventory.

Very bad GUI mockup

First GUI implementation

The final GUI matched fairly closely with what we had planned it to be, the main differences are the lack of XP bar and the map position changing. We changed the XP bar for two reasons. Firstly, we ended up making each stat level up individually so we gave each stat its own mini level up bar. Secondly, we needed a bit of room for some extra GUI elements that were not always present, namely item bag inventories and portal entry buttons.

Final GUI implementation

We also custom built a menu UI system that has a fair bit of functionality (as you can see, the title is currently being workshopped since, let’s face it, Unexpected Orcs sounds like a bunch of 12 year olds came up with it when creating a Lord of the Rings inspired flash game in 2011!)

Title screen

While the game has perma-death, you don’t have to play a run all at once, you are able to save the progress of your characters and load them back in at a later time. If you want a real challenge, there is the more hard-core “guest mode” where you can’t save. And of course there is a settings menu to change all the basic things like controls, sounds, graphics etc.

Load game screen

Settings screen

All of the UI controls seen here made from scratch. We made everything from the buttons to the scroll boxes to the tabs by hand!


Dungeon generation revisited

As I mentioned before, we needed an upgrade for the “hand-made” dungeons. This generator has quite a bit going on under the hood so I won’t go into detail here, however these next three images show some of the steps taken during the dungeon generation.

Step 1: Level graph

Step 2: Level graph with corridors laid out

Step 3: Final dungeon

If you want to learn all the nitty-gritty details, I made a separate post that goes a lot further in depth here.

The general gist of it is that you give the generator a bunch of room pre-fabs (including a spawn room and a boss room), and it will randomly place them down and path find between connected rooms to connect the corridors.


Conclusion

If you made it this far, thank you so much! That’s all for the moment, I hope this page gave you a bit of insight into what goes into making even a fairly simple game like this (admittedly made harder by making almost everything from scratch). This is by no means an exhuastive collection of all the systems the game uses, I haven’t touched anything to do with items, enemies, or any gameplay (this is mainly because I wasn’t as heavily involved with that stuff).

If I were to make this game again, there would absolutely be a lot of things that I would have done differently, however I learnt a lot while making this. I really found the hands-on aspect of making everything from scratch rewarding and I will definitely be doing it again in the future.

As for why the project got abandoned, my cousins and I did the bulk of development during our uni summer break. We had loads of time so we kept up quite a bit of momentum. This dwindled drastically once we all started classes again and then final ground to a halt. We may have finished it if we’d had more time, but honestly the amount of feature creep we had was quite impressive so who knows?
I would do it all again in a heart beat.

If there is anything you’d like to know more about or if you have any questions, feel free to get in touch!