Posted February 22, 2025 by Good Faith Company
Hi, Ivan is here again. I am the Team Leader, Project Manager, and Senior Developer on our game Return to Divinity.
One of the key features of our dungeon crawler game is items that grant passive status effects to the player's squad of heroes. Those items serve as a way for the player to "level up" as they play; otherwise, the player's squad would be no more powerful toward the end of the run than they were in the beginning - in fact, likely weakened and exhausted after all the battles.
Items and the inventory system have already been implemented (I wrote a devlog about it). It was time now to handle status effects.
Before we get to solving the problem, let's first assess it. What do we know about the feature of status effects, and what are some specifications we have to follow?
You may remember I enjoy drawing diagrams to design and visualize the technical architecture of systems. This time was no exception.
Here is a diagram of the structures that will implement the status effect system:
And here are a couple of flowcharts to describe its operation:
With this, we are ready to attach the component to our units! After that, we will only need to implement the consequences of status effect types.
Voila! Now, we can buff up our units to deal 999 damage, have 999999 HP, and be 10000% faster (only until we start balancing the game, sadly).
We now have a robust, scalable status effect system that can be applied to any unit in the game - and, in truth, any actor.
Applying or removing a status effect from a unit can be done in one line of code:
Creating a new status effect type merely requires adding a line into the list of status effect types (EStatusEffectTypes) and handling it in the target actor (like in UBaseSquad::HandleOnStatusEffectTotalValueChanged()).
And a remarkable convenience: the entire backbone of the status effect system is contained only in 4 files (StatusEffect.h/.cpp, StatusEffectComponent.h/.cpp)! It makes it strikingly mobile, as any project needing status effects would only need to copy those four files and they would be good to go.
Initially, I considered a rather rigid system controlled entirely by a custom GameMode with a predefined, limited set of status effects, only applicable to the player's squad.
But when my teammate Keegen proposed the idea of a support enemy that casts status effects onto its allies, it made me think: why limit status effects only to the player's units?
And I realized that all I need is a well-constructed Actor Component that reliably manages active status effects.
This is a bright example of the value of considering possible applications of your systems: while you may not have to implement them, designing an architecture with modularity and scalability in mind can lead you to robust, flexible systems.
I hope you found this reading insightful.
Thank you for your attention,
Ivan Shyika
Team Leader, Project Manager, and Senior Developer of Good Faith Team