Effect Architecture

I’ve been working on a roguelike game for a few months now and I’ve gotten to the hardest part yet, effects! I’m talking about everything from an effect that represents fire by continuously damaging an object to an effect that summons a creature, to an effect that modifies the stats of an object. So obviously there are a lot of potential effects. The question is how to go about implementing effects in an object oriented manner.

My current approach is to have an Effect class that is really broad. It contains multiple hashmaps that can contain game objects, simple values, locations, and other effects. Most instances of the class won’t utilize all of these hashmaps. Each effect also has a list of types. These define how the game interprets the effect.

Examples Types: damage, healing, armorModifier, summon, etc.

For example, when an agent suffers damage the game will look for effects on that agent of the type “armorModifier”. If an effect with that type exists on the agent, the game knows there should be a key/value pair in one of the hashmaps that tells how much armor should be added/subtracted. This would be for a passive effect, however many effects are active. Such effects have an activate() method that is called. The Effect class then acts based on the types of the effect. So if its a damage effect it will look for a key/value pair for how much damage, what targets to damage, what damage type it is and so on.

So if it wasn’t complex enough for you already, there are also effects that really only modify other effects. For example, the activateOverTime type of effect just activates another effect at a certain frequency. The onHit type of effect applies a new effect to whatever an Agent attacks.

Here are some examples of effects and what types they would have:

  • Fireball: damage, aoeBurst
  • Vampirism: damage, healing
  • Alien Parasite: damage, activateOverTime, onTargetDeath (would create the Summon Parasite effect)
  • Summon Parasite: summon

So, I’d like your input on how to best implement this system. My current method can work, but its getting more and more complicated. I’ve considered creating a child class for each “type” of effect, though that would be a lot of child classes.

Thanks for any help,
Nathan

That sounds like missing design. One class for all ? Do you mean instances or inherited classes ?
Create separate effect classes.

Let each effect handle itself or create according effect handlers but “the game” should not interprete them all.
Ideally, adding new effects should not require to modify other parts of the game but only add the new effects classes.

For each entity in-game, store a list of their effects.

Then each frame, call a “tick” function in each effect that does: a) check that it’s active, and b) if it’s active, apply its changes to the entity/world.