Hello, it’s the lead programmer of Headless Hobo with another post. A little delayed, but here it is.
This time I’ll talk about our old combat system in our game Molith.
Figure 1: Simplified overview of the combat system
When you damage someone in our system, you damage through lots of different damage types. As we can see above. There are two main damage types. Base, and the elemental types.
Base always damages the enemy defense. Elemental types only damage, if the defense has a weakness for that elemental type.
In our example above we can see that there also is STR (for strength), which just add extra damage to base.
When the damage reaches the defense, the defense checks if anything goes through and if it does, it sends the damage to the life which then subtracts it.
Figure 2:Overview of the combat system with modifiers
What is a modifier, you might ask? Well it’s anything, that needs to modify the damage. Its most common use is in the different attributes, for our equipment. E.g. we have a broken sword attribute, which modifies the swords damage, by subtracting damage.
In the example above we can see that first the player attack sends the damage to the modifier manager, which then sends it to all its modifiers. Then after the damage has been modified, its sent back to player attack, where the damage is used (as seen in previous example).
As we can see it’s no longer “Damage” its “Copy of damage” and why is this?
Well it’s because that when we modify the damage each frame, we need to have something that is unmodified, else we would keep modifying something, that is already modified. E.g. If we had a modifier, that adds 2 damage each time, then if we don’t make it a copy, the damage would grow by 2 each time it runs. Therefor we need to save the unmodified damage and modify it each frame.
We went to work on getting the system implemented.
Figure 3: Overview of our first idea of the modifier system
So basically everything inherits from the modifier class. What does inherit mean?
Well, it means that if a class inherits from another class, then it gets everything from that class, and can do anything that class can. It has a Is a relationship. Let’s say we have a dog and a cat class, which both inherits from the animal class.
Every animal eats, drinks, mates and so on. Without inheritance, we would have to write the dog class and cat class from the ground up, but with inheritance we only have to write, what they do differently and can save a lot of code by that. The downside to inheritance is, that you lose a lot of flexibility. So if there a day existed an animal, that didn’t eat, then since, we assumed that all animals eat, then we either have to write this new animal class from the ground up, or make a hacky solution.
Using inheritance removed a lot of code that would else be duplicated in the modifiers classes, but also removed a lot of flexibility. We ran into a problem, when we wanted to implement a new change to the system and because we could see that without reworking the code, we would have to implement a hacky solution, we decided to rework the system and make it more flexsible.
Figure 4: Overview of our current combat system.
So previously which class the modifiers inherited from, decided which modifier it was. This was the biggest problem and what changed in the new system. As we can see each modifier has a modifier type, which is now what identifies the different modifiers. Because of this, we could make our modifier class into an interface. What is an interface?
It’s when you need all classes that inherits from it, to do something, but not specify how it does it. E.g. all animals eat differently, so if the animal class was an interface, you would make the interface say that the class should eat, but not how it should eat.
With this new system, we added our feature and in the future it would be easier to make a change. So lessons learned is, be careful about using inheritance, it's good at removing duplication, but it can make it hard to change things, if you don’t use it right. Remember composition over inheritance.
As always I hope you have enjoyed the post and learned something you can use.
Philip Ullersted – Lead programmer at Headless Hobo