top of page
Modular Technical Design
Soulslike games have several interwoven systems that can easily turn into a mess of dependencies when programming them. To prevent this, I prioritized Unreal Engine's set of modular tools (namely actor components, interfaces, and event dispatchers) to ensure that key classes and blueprints remained independent of each other.
Shared Actor Components
The player and the boss share many fundamental mechanics despite being different at a higher level. In particular, they both have a defined set of stats (e.g. health), and they both needed a way to deal damage with their melee weapons. Rather than writing this logic twice, I wrote singular actor components that could be applied to both my player and boss actors.
The "Trace Component" was a prime example of this. It used a box trace (synced to attack animations) to damage an opposing actor. To get the length of the box, I wrote an array of structs that used the FNames of bones as data. I then called GetSocketLocation() on the skeletal mesh (using the FNames as parameters) and calculated the distance between their locations as the box length. The array of structs also accounted for my boss's dual wielding; it simply had two of these structs to derive data from instead of one.
Linear Algebra Application
Leveraging vector math was also a key component of creating this system. The "Block Component" on my player actor (used for blocking damage from the enemy) worked by calculating the dot product upon collision with the player (while their shield is raised). Any negative dot product of the player and boss's forward vectors results in a successful block from the player.
This application of vector math also worked for the boss's projectiles; The projectile's forward vector is used instead.
Applying Event Dispatchers
This system made heavy use of event dispatchers to decouple classes and components from each other. The workflow for this involved writing a C++ function that broadcasts a delegate at the end, then listening to that delegate in a separate blueprint.
My "Stats Component" used this technique to communicate with my UI Blueprint. Whenever a stat was reduced (e.g. health or stamina), it would broadcast a delegate that my UI Widget blueprint would listen to and update accordingly.


Trace Socket Setup on the Boss Actor

Trace Component Demonstration (with debug boxes)
Dot Product Math Visualization, Courtesy of maththebeautiful.com


Update Health Function (on UI Widget Blueprint)
Soulslike Combat Framework
bottom of page
