Key Contributions
- Project setup
- ECS via EnTT
- Player movement and combat systems
- Audio via FMOD
- User interfaces
Overview
Warlock Activities is a top-down game inspired by Death’s Door. You play as a warlock’s apprentice tasked with delivering groceries as the castle is overrun by monsters! The project was built with ECS in C++ with The Game Assembly’s in-house engine (TGE), and Unity for level design. I was mainly responsible for the movement and combat systems, as well as integrating audio via FMOD, which was made in collaboration with sound design students from another school.
ECS via EnTT
We decided to use ECS (Entity Component System) for this project, though we are mainly used to working with OOP (Object-Oriented Programming). Since we’d be building our own engines soon for coming projects, we wanted to at least try it once.
Since this was a shorter project, building and debugging our own ECS would have taken too much time. Our goal was to learn the principles of ECS and how to work with it, so we decided to use EnTT, a well-known library for ECS, which let us focus on learning the concepts rather than fighting with bugs.
There was definitely a learning curve, and took a while to get used to, mindset change and all. However, it made us think about our code in a different way. It encouraged us to write more modular code, and to think more about how a component could be reused across different systems.
Collision system upgrades
I didn’t build the collision system itself, but I spotted a major design flaw: We had a single collision system handling every interaction, which went against the entire point of ECS.
I proposed the idea of adding a CollideEffect component to entities that collide.
It’s just a component which contains a list of other entities that has been collided with that frame.
So simple, yet it made our collision system so much more flexible.
Systems could now just check for the CollideEffect component and react to it accordingly,
without having to dig around in the collision system to add new features.
struct CollideEffect
{
std::vector<entt::entity> collisions;
};Player movement and combat systems
ECS opened up some really elegant posibilities for our player movement and combat systems.
The dash system was my favorite. Instead of burying dash state in a player class,
I could just add a simple component.
The movement system checks if there is a DashComponent present,
and applies the multiplier!
I built a separate system for handling duration and refreshing the component.
struct DashComponent
{
float directionMultiplier;
float duration;
bool bufferNew;
float bufferResetTime;
};With this method, anything that moves can dash. Even the enemies!
Audio via FMOD
In this project we collaborated with sound design students from another school. I still had to implement the audio system as well as integrate the sound effects and music into the game, but I didn’t have to create any of the audio assets myself.
Our music was dynamic and changed based on whether the player was in combat or not.
It was controlled via a simple intensity parameter which was set to 1 when the player was in combat,
and 0 for everything else. We initially wanted to gradually change this value based on how intense the combat was,
but we didn’t have enough time to implement it, so we opted for the simpler approach.
The audio system itself was implemented via the same wrapper that we were provided with in Iris,
but we had some issues with the way the FMOD library was reading our banks.
It would sometimes silently fail to load certain events, and it was really frustrating to debug.
We eventually pinpointed the issue: Renaming events to change their casing
(e.g. playerFootstep to PlayerFootstep) didn’t update the banks properly when exported,
which caused the events to load but not play any sound, with no error messages at all.
User interfaces
We reused my View Controller from Iris for this project, which helped us get a basic UI up and running immediately. Due to time constraints, we had to keep the menus from Iris. However, the in-game HUD still had to be rebuilt in order to match the features of this game:

Conclusion
This was my first time working with ECS, and I really enjoyed it! It pushed us to write smaller, more focused components, which made it way easier to keep track of things. I definitely prefer having 3 focused components over a single bloated player class.
However, that strength became a weakness. As we added more content, finding the right system became increasingly difficult. Each system got its own source file, and we ended up with so many that it almost turned into an eye exam to find the right one:

Still, I’m glad we got to try it out in a real project, and would love to use it again in the future!
Working with the sound designers was great too. They were really talented and easy to work with. Fate brought us together again on our next project, Spite: Blood and Gold, and it couldn’t have gone better!
