Muramasa Burden – Sound System

About

Fast-paced hack-and-slash where you lose time instead of health. Inspired by Japanese mythology.

Context

Type: Semester Project
Role: Sound Programming, Sound Management, Art Direction
Size: 5 Developers + 3 Soundies
Time: 4 Months (May-Sep 2024)
Engine: Unity

Introduction

I had some experience with sound before and wanted to create a system for effectively controlling all music and sound effects within the game. My idea was to layer music to ensure smooth transitions between tracks. I wanted to divide music into levels, each represented by a separate track that could be activated and layered over the previous one. This way, music changes should be less noticeable to the player, creating the impression of a single, responsive soundtrack.

Preparation

In this project, I wanted music to adapt to the game state. I segmented the levels into distinct phases: start, exploration, combat, death, respawn, and the cycle's repetition. Then, I provided to our sound designers two Excel spreadsheets: one listing all sound effects and another detailing the desired musical mood transitions for each level phase.
I knew Unity has some good built-in audio tools, like Audio Sources for changing volume, pitch, and 3D sound, and an Audio Mixer to control different types of sounds. Therefore, I focused on organizing the music, implementing a smooth transition system, developing in-game controls, and adding a track trimming feature for future flexibility.

Libraries

I started by organizing all game sounds into different arrays within a class, separating music and sound effects. Then, I turned these arrays into scriptable objects to create a shared sound library that everyone on the team could use. Grouping sounds this way made things easier and helped to save space, but the libraries ended up pretty big. Hiding setup parameters helped to reduce size, but next time, I would split them into smaller pieces referenced by one library object.
> Code - Sound Lidrary
> Code - Music Library

Sound Manager

Then, I developed a standalone sound and music manager class to centralize audio control. This class accesses the sound library scriptable objects and returns sound by type, picking a random one if there are multiple options for a sound type. To prevent music from overlapping, I implemented a crossfading system using current and previous track volumes. This ensured that only one music track played at any given time. Then, I also added a track-trimming feature to make some tracks shorter.
In the process I learned that sound playback time isn't tied to delta time, requiring careful management to avoid issues like delayed music transitions during time dilation, such as slow-motion effects or game pauses.
I created special classes to handle spawning music and connected them to the mixer for global control. To optimize performance, I added simple garbage collection and turned most sounds to 2D, except for environment sounds. We later noticed some micro-freezes when the music was loading during gameplay, so I made all the music files load in the background while the game was loading.
> Code - Sound Manager

Additional Features

Once the main sound system was working, I added a way for the music to change as the player progressed. The music smoothly transitions when things happen in the game: it keeps going if the player keeps fighting, goes back when the fight is over, fades out when they die, and then fades back in when they respawn. The music also changes quickly in certain situations, like when the player goes back to a checkpoint or starts a new game. Then, I started fixing bugs and making small adjustments. More functions were used to ensure global music control and a fading effect when the menu opened.
Later, we ran into a problem when some of our sound designers left the project or were unable to continue until the deadline. This slowed down testing, and I ended up having to create the music myself. Fortunately, my teammate sourced royalty-free tracks, which I quickly mixed and segmented into music levels for different game states.

Exhibition and Steam Release

We got great feedback in the game exhibition and even had a speedrun tournament with a cool prize! After that, we decided to put our game on Steam. We found an awesome musician who wrote great music. But my sound system needed some rework to handle it. The musician didn't like smooth transitions at all, and I hadn't included any ways to turn them off because I always used it. I also realized some timers were still tied to delta time, which I had to fix to keep the music playing consistently. It was a bit of a headache, but it taught me a valuable lesson: even if it turns out you're the only one using your system, it has to be flexible and expandable enough to handle changes later on, or you'll have problems.

Conclusion

It was a great project. I learned a lot about sound, developed and supported my system until the release, and had a great time working on it and the art of the game. I also learned not to try to know better than artists what system they need and that systems should be flexible and expandable. Next time, I would try to separate parts of the system so that there would be no limits for artists or game designers to use it. Also, after a recent optimization elective, I got lots of ideas on how to optimize it in the future.

My takeaways

  1. If I’m creating a system that artist would use, I always need to think about their needs first.
  2. The system should be flexible and expandable even if it seems that you wouldn’t need it.
  3. I learned a lot about music programming and would enjoy improving my system for the next project.