There are generally two approaches of coding the item’s properties in a roguelike. For convenience I’ll call them NetHack-like and Angband-like, although maybe other names would be more appropriate. Both those roguelike use a hybrid approach, which is a mix of the two techniques, but they seem to be on distant parts of the spectrum.
In the NetHack-like approach, you’ve got all sorts of special cases coded into the game as... special cases. So, if you want an axe to be especially deadly against plant-like creature, you add a check in the combat code for “axeness” of the weapon and plantness of the monster – then add some bonus or special behavior. There are several ways of actually implementing it – some more messy than others, but the idea is pretty straightforward: Special cases in the game are special cases in the code.
The Angband-like approach is more clean
. You identify the behaviors you want, and generalize them in a set of attributes, like various kinds of damage, magical and non-magical bonuses, speeds, factors and probabilities. This way the behaviors are a result of some simple math, and the whole resulting game mechanics is very smooth.
Now, in this article I’d like to point out that being on the extreme of either of the two approaches is a Bad Thing (tm) for your roguelike. Maybe it’s not a very revolutionary thought (most extremes are at least weird), but it might not be that obvious – especially when there are so many simulationists
going to the Angband-like extreme.
The disadvantages of special cases seem to be clear: messy code, high maintenance costs, inconsequency in game mechanics, lots of potential exploits, hard to polish rough edges. Especially with checks like if the weapon name is such-and-such then do this
it’s going to break a lot when you change something. And tracing interactions of the rules is a mind-boggling process.
Of course, you can add some layers of abstraction to clean that up, some flags and symbols and what not – in other words, you can go towards the Angband-like design.
The disadvantages of the smooth game play are less obvious, because they are connected with human perception more than technical details. Players like special cases. Special cases make the game interesting. On the other hand, it seems wasteful to have a variable that is only nonzero for a single item or monster. This often results in lack of truly unique items and monsters in game – all of them become some variations of each other.
Ok, but with careful game data design and some self-control you can still make it interesting – so it’s irrelevant. Is it? Let’s face it – to get to the complexity and interesting behaviors you had in the NetHack-like approach, you need a large number of variables, that are in fact really rarely used. This not only makes the data entry and management hard – it also makes you merge
some unique behaviors together. You’ve got an invisible ghost monster and a chameleon monster that can look like a piece of wall? Let’s simplify things a little and just make both of them invisible! It’s not a big difference.
But in the end, the differences add up and you end up with much less than you thought of in the beginning.
And there’s a third pitfall. The attributes are easy to scale and compare to each other. That often leads to thinking: well, the halberd is very similar to an axe, only bigger, so let's give it the same attributes as axe, and increase the damage slightly
. The end result is that you can add an auto pickup and equip stronger weapon
option to your game. Or just replace the inventory with a much simpler system of power ups.
As I said, both Angband and NetHack are in fact pretty far from what I described here. But is your game too? Where would you like it to be on the spectrum? How do you want to minimize the problems I mentioned?
Think about it today!