Soul of Darkness

A gritty 2.5D action-platformer set in the collapsing world of a cyber-gothic future.

My Roles: Game Designer, C++ Programmer, Level Designer, and Sound Designer

A futuristic digital art scene with a male warrior holding a glowing sword, standing on a metal platform in a dark cityscape with tall, damaged buildings and a red and black sky. The text "Soul of Darkness" is displayed at the top in neon blue style.

About

This project was made alongside Richard Kim (Programmer/Producer), James Zawko (Artist), for our client Gameloft Brisbane.

Cleave your way through neon lights and gothic architecture as you race to defeat the AI overlord responsible for plunging this world into chaos and depravity.

This project is a reimagining of a 2010 Gameloft IP, also entitled Soul of Darkness, revamped for a modern audience using Unreal Engine 5.

My Contributions

  • GDD

  • Music composition

  • Creation, manipulation, and integration of sound effects

  • Level design and implementation

  • Simple gameplay mechanics (lasers, electrified grids, message triggers, UI)

  • Implementation of dynamic music system

  • Playtesting plans and reports

  • Boss encounter

  • Gameplay balance

Planning

Game concept poster for 'Soul of Darkness' featuring platforming obstacles, art style collage, and weapons. Includes gameplay instructions, enemies, rewards, and loadout options, with visual elements like a HUD, background layer, and character sprites.
A comic-style sequence illustrating a tech cultist attacking a player in a dark, urban environment with a full moon in the background and a large eagle emblem at the top right corner.

According to a note scribbled in my diary early this year, Soul of Darkness began with this pitch:  

‘Soul of Darkness is a gritty, cyberpunk Metroidvania that explores a world infested by techno-vampires.’

We established three player experience goals of excitement, curiosity, and awe. However, it should be noted that as production went on, we began to lean further into the excitement and awe aspects of the experience. This was due to repeated reductions in scope that required us to pivot away from the Metroidvania genre and strategically cut content. 

In our first pitch meeting, we were given the additional requirement by Gameloft to include an interesting use of the 3D perspective. They wanted the 2.5D element to be more than just an artistic choice, but something mechanical the player could interact with. 

With this requirement in mind, I spent the next week trawling through YouTube watching gameplay of other titles within the platformer genre to find interesting mechanics or ideas. I wanted to update myself on the current industry trends, what had already been done, and how some of these old ideas could be innovated upon to create something new. Some of my personal favourites were: 

I decided to go with the idea of traversing the foreground and background. It was simple but effective and satisfied Gameloft’s request to utilize the 3D element of our gameplay. However, I had some weirder ideas that didn’t make the cut, like the spider drone, and nanite mist. 

The spider drone was a companion that shifted the game into a 3rd person shooter. Kale would remotely control the drone up to a certain distance and could use it for reconnaissance and light fighting with its laser gun. Nanite mist allowed the player to enter electronics, flow through the wiring, and control systems. Ultimately these were both cut, the first due to scope and second as it was too similar to the core mechanic of teleporting between foreground and background.

Originally, the enemies were far more difficult. They had more health and the player moved slower. There was also no way to cancel out of an attack once the action had started, meaning the player was locked in until the animation was complete. To make matters worse, the player would come to an immediate stop when performing the attack…The pacing was completely off. However, it took a while to figure out that those were the reasons why.

As development continued, there were two moments I kept coming back to that I felt captured the core fun of our game: quickly teleporting between the foreground and background and destroying things with your sword. I decided to follow the fun and focus our experience on the excitement and awe of being a powerful, cyberpunk badass with a sword. The enemy's health was reduced dramatically, making most a one hit kill. I made it so all actions could be cancelled. I added a very forgiving life-steal mechanic, whereby the player would gain health upon damaging enemies. Finally, I increased the number of enemies, as it was exhilarating carving through hordes of tech cultists and made the player feel almost unstoppable.  

Development

Most challenges I faced surrounded how best to integrate design concepts in a collaborative setting using Unreal Engine’s workflow. For example, the level design needed to be easy to manipulate for fast, iterative improvements based on playtesting feedback, but also modular so that the artist could create ‘lego bricks’ that we could assemble the high fidelity version with. 

The first method was to use primitive shapes to block out the level. This was painfully slow for me as a designer. It didn’t allow for even small changes to be made to the architecture without considerable time and effort readjusting the rest of the level to fit. 

The second method was to use Unreal Engine 5’s ‘CubeGrid Mesh’ tool to block out the level. This was very fast for me as a designer and allowed for rapid prototyping, but was unsuitable for use in a final product. 

The solution we settled on was a combination of the two. I created blockouts of prototype levels where I playtested my level design hypotheses using the CubeGrid tool. Effective designs were then pulled from those to create a ‘Master’ level that the artist could create modular models from the recurring geometry. The CubeGrid mesh was then gradually replaced by these high fidelity models and textured appropriately. 

In relation to this challenge was avoiding merge conflicts within the master level. By default, only one person can make changes to the level at a time which is very inefficient. It became especially important to introduce a solution when the artist had tasks related to the environmental art or lighting while I needed to modify geometry, entity placement, or anything else. To make matters more precarious, the version control we were using (Git LFS in combination with Azure) had a bug where it would recognize a merge conflict but automatically resolve it. This auto-resolve would corrupt the file. 

The solution we settled upon was to make use of Unreal Engines sublevels system and have them set to always stream. This effectively creates multiple levels that are layered on top of each other to create one master level, meaning changes made to one sublevel won’t conflict with changes made to another as Unreal treats them as separate files.  

Another challenge faced was improving my music production pipeline. It became quickly apparent that the workflows I relied upon to create standalone compositions did not translate well to game development. 

My first attempt was identical to my usual workflow. I recorded improvisational ideas on a piano and transcribed these with Musescore. I then converted the notation to midi files so they could be interpreted by synthesizers. Whilst the process is fine when the sounds used are relatively similar to the original recordings, this was not the case for Soul of Darkness’s sound font. The cyberpunk style of grating saws and electronic effects was a few too many steps detached from the traditional keyboard, making it difficult to determine what musical ideas were worth keeping without the relatively involved process of recording, transcribing, and importing. 

In addition, the composition needed to dynamically respond to the action on screen. The solution I opted for was to create standalone musical loops and transitions that would be triggered by areas of the level to coincide with the current intended player experience. To ensure that the music triggered on the beat and transitioned seamlessly, I created a Music Manager that utilized Unreal Engines Quartz subsystem; a system that can trigger events on bars and beats with great accuracy. 

As for sound effects, in all previous projects, I’d source sounds from different libraries and use them unchanged. However, with the increased fidelity and scale of this project, I found it difficult finding sounds for everything. I decided to try combining (mixing), pitch shifting, modulating, and clipping different sounds together to create new sounds. This proved to be very effective at generating unique, highly-specific sounds that provide valuable feedback to the player. In future, I’d love to work more with Meta-sounds, as this was something I only found late into the project that seems really useful.

In Retrospect

I really enjoyed my time working on this project. It's something I'll look back on fondly for years to come. It was stressful at times as deadlines loomed and inevitable issues hindered our progress, but we had a fantastic support network and a strong team. I'm very proud of the work we were able to produce, and it's been very affirming to see our hard work pay off. I feel so appreciative to everyone involved in guiding us throughout the development of this project. There was consistent, quality advice, week after week that helped align our focus, reignite our passion, and improve our approach. To have access to something so valuable feels like a rare thing. ​

As I reflect upon where we started and how we tackled various challenges, I have a few key takeaways I'll be applying to my future endeavors. 

The most significant I have as a designer is to trim the fat, quality over quantity. Try to distil a game concept down to its essentials and don't clutter your design with unnecessary fluff. Demand that your ideas justify their worth.

In addition, let the fun lead you. Allow the design the freedom to gravitate towards it even if it wasn't what you originally had in mind. Sometimes we have these ideas about how our game is supposed to be played and can be frustrated by players not engaging with it. But playtesters don't play your game the wrong way. They play it the fun way. So keep an eye on what they repeatedly choose to do - even if it's technically a bug or not your design intent. 

This project has taught me more than any other the importance of understanding why you're undertaking a project, so you know what to prioritise when you inevitably aren't able to complete everything you set out to do. If you've only got five minutes to impress a potential stakeholder at a showcase, like we did, you better let them see the best part within that time. It's so easy to get caught up in tangential content that only serves to waste time if not aligned with the purpose of the project. Everyone knows scope creep can destroy a projects potential, but through understanding the purpose of the project can you better determine what aspects are scope creep.

I've been challenged, grown, and came out the other end inspired to create even better games.

Outcomes

A photo of the Soul of Darkness team showcasing the game
  • Showcased at QUT Capstone Event

  • Developed foundational skills in Unreal Engine and C++