So it’s been a little bit since the last update on my hobbyist game development efforts, but a lot’s been going on whenever I can snatch some time in between the constant, endless presentations I’ve had to prepare for recently on the academic side of my life.
My focus in the last few weeks has been on some core gameplay systems. Originally I was going to work on the dungeon environment, but I figured that fancy dungeons wouldn’t be that useful if the player couldn’t do interesting stuff in them, so I went for under-the-hood gameplay systems instead:
Hunger systems are a classic feature of roguelikes — since the original Rogue, in fact! The idea is that the player needs to seek out food within the dungeon and eat it regularly, otherwise they gradually begin to starve to death. Since food is limited and can only be found within the dungeon and not created by the player, it serves as a time pressure mechanism; the player has to keep moving further down the dungeon to find food in order to stay alive. Currently my system is very basic: the player starts with three rations, and can find two different types of food items within the dungeon that refills their hunger meter. If at any point your Satiety stat dips below 50, you start getting warnings, and at 0 begin taking damage every turn. At -50 you’ll die of starvation. I’ve added an indicator to the interface that shows this stat directly, unlike Rogue and some other games that keep it hidden and only warn you shortly before death:
In order to make monster fighting more interesting, I wanted to add a system for variable attack and movement speeds between different creatures. This is kind of a weird thing to implement in a turn-based game, and I wasn’t sure of the best way to go about it at first. Eventually I settled on a central turn scheduling system in which all monsters (and the player) schedule their next turn each time they take an action. The number of turns they have to wait until they can move or attack again depends on their Speed stat.
It sounds simple, but it turned out to be a big pain to get right! I had a lot of weird bugs where certain monster turns didn’t register, or the game would suddenly stop running in turn-based mode and let monsters run rampant while the player was unable to move, and all sorts of other problems. Eventually I got all that ironed out, and finally had fast-moving wolves and bats, slow-moving zombies, etc… only to find that in certain circumstances the player would encounter invisible and invincible enemies after moving to a new dungeon level.
After a few days of annoyance I worked out the problem — monsters were dying in combat, but a reference to them was remaining in the turn schedule, meaning that memory was still being allocated for their monster data by the program. In certain situations that meant the scheduler would find that reference, say to itself ‘hey this here says there should be an orc doing something’ and the player would end up fighting a ghostly remnant of a previously defeated enemy!
I was able to fix that relatively easily once I figured it out — this is why we keep backups, kids. Also it was a useful reminder to be more careful about my coding practices in some parts of the game, so I did quite a few bits of refactoring of the code to prevent anything like that happening again.
Combat System Changes:
Again in service of making combat more interesting I made some significant changes to the combat system to better differentiate enemies. My favourite series of Japanese RPG games is the Shin Megami Tensei series, which are known for being set in a dark demon-infested version of Tokyo and for being really difficult. What I love most about these games is that the combat system encourages tactical thinking by having weapons and spells deal a number of different types of damage, which demons can be weak to, immune to, or resistant to depending on their nature.
I implemented something similar to this, where each monster has weaknesses to certain types of physical damage (in this game they’re called Phys for general slashing attacks, Blunt for hammers/clubs, Pierce for arrows and spears, alongside numerous magical damage types like Fire, Ice, Thunder, etc.). Hitting a monster’s weakness will do double damage to it, while hitting if it’s resistant you’ll deal only half damage. Some monsters are immune to certain types of damage entirely — Skeleton Warriors, for example, aren’t bothered at all about being poked by arrows given their total lack of fleshy bits.
The idea is that this will push the player to experiment with different weapons, spells and items in order to dispatch enemies more quickly — particularly when they reach later dungeon levels, where monsters start appearing in large swarms and have powerful attacks. I want damage types to be a major focus for the player, and for good attack choices to have significant rewards (and for bad choices to have a big impact!).
To make things a little easier for the player, I’ve added a Look command so that you can see some details about monsters in visual range:
Other than these big changes, mostly I’ve been squashing bugs and adding bits and pieces of content. At this point, the player can face about 300 different monsters, collect 50 different weapons and items, and visit 15 different dungeon levels. As time goes on I’ll keep adding new monster types, then randomly-generated weapons and items, and finally some super-tough boss monsters including a final boss. At that point I think I’ll be ready for a playable alpha release to get some gameplay feedback.
This week has marked the official start of the academic year, so there’s been a ton of things to do at the university — which means there hasn’t been much time for game development! I’ve been keeping careful track of all my additions and to-do lists and such, so when I have time to get back to things I’ll remember what I’d planned to do next.
All in all it’s a hell of a lot of fun so far, even when I’m getting frustrated by weird bugs. I’m definitely gaining some major Python proficiency thanks to all this, and it’s forced me to tighten up my coding practices and embrace proper version control.
After some more work on damage types and attack variety I’ll be modifying the game UI and sprucing up the general look of things, so hopefully I’ll have some more interesting screenshots next time 🙂
I’ll leave you now with some game recommendations:
SDL Rogue: a well-done Windows port of the original Rogue, with some nice additional options (including a graphical tile option). Type ‘?’ to see all the commands (there’s a lot of them!). The same site also has similar ports of other classic roguelikes, including Hack (the predecessor to Nethack), Larn, and Moria (predecessor to Angband). Check ’em out.
DoomRL: This is a fantastic free game that combines two of my favourite things — the original Doom (in my opinion the greatest computer game of all time, and one I still play regularly), and roguelikes. It masterfully combines frantic Doom-style demon-blasting with turn-based roguelike gameplay and character progression, and to top it off has the original Doom music and sound effects, and some fantastic 2D graphical tiles. Download it!
Some enterprising fan has developed a server for DoomRL, too, so you can see how you stack up against other players and even play in your browser (or via a Telnet client). ASCII text mode only though!
Crypt of the NecroDancer: This game kicks my butt all over town, but it’s incredibly creative and fun. It’s a turn-based roguelike with a twist: the entire game world is tied to the rhythm of the music for the level, and making your moves along with the beat gives you various bonuses (and moving out of time leaves you open to attack!). All the items and monsters play on this theme. The graphics are incredibly charming, the music is by Danny Baranowsky (of Binding of Isaac and Super Meat Boy fame) and is absolutely fantastic, and it’s packed to the brim with cool features and secrets to unlock.
It’s also 50% off on Steam right now, so now’s a great time to take the plunge!