top of page

Game Description:
Freak Show is a 3D, first-person horror game you are an unlucky contestant on a game show with your life on the line. With real life spectators able to affect your run, explore the circus and collect enough funds to escape.
​
This was created within one month as a pre-production prototype, then taken on to be a full project the following semester.
​
Responsibilities:
For this project, I was responsible all of the audio in the game. Including:
-
Sound design and implementation
-
VA casting, review, and direction
-
Dialogue recording, editing, and implementation
-
Integration of Wwise's spatial audio system
Dialogue
I had my hand in every aspect of the dialogue for freakshow. On top of it being handy for relaying specific cues to the player, it helps push the game show aesthetic and make the make the overall experience a bit more memorable.
Concept & Casting
I worked with the producer to detail what we wanted out of the dialogue in the game. The character we landed on was "The Announcer", who is the figurehead of the show. After a lot of writing, editing, and discussion, we had a core set of lines to record for the character. We just needed a voice actor.


1/1
I was in charge of putting together the casting call for the role. Especially since this would be an unpaid position, I wanted to make sure there was full transparency in the role requirements, time commitment, and compensation. I set up the audition, sent out the casting call, and advertised it to those who may have been interested.



1/2
By the time the deadline hit, we had 5 auditions! I listened through them, took notes on the performances, and passed my thoughts along to my producer. We came to a decision after some discussion, then I emailed out the results and feedback to everyone who applied.
Recording & Editing
Prior to our first recording, I did some pre-session work to help speed up the process when we got to the studio. I set up my Reaper project, did some final edits to the lines we were recording and numbered each, created a version of the script to make it easier for the talent to read, and mocked up a take sheet for in-the-moment notes to help during the editing process.


1/1
Once the gear was set up, I took levels, got talent warmed up, then dove right into recording. Primarily, I was the engineer for the session, but I also helped the producer in giving voice direction, answering questions, and keeping morale up. I kept the recording to one rolling take, then adding a maker with the line number whenever we started a new line. After 2-3 good takes, we'd move on to the next one. In total, the session was around 2 hours with having 50+ lines recorded.


1/1
While editing, I went through two passes. The first was for performance: I keyed in on getting one really solid take for each line. Through comping and the use of the SuperGlue Reaper scripts (for non-destructive clip gluing), I was able to lock in really solid performances with the flexibility of tweaking them later.


1/1
Editing these lines were a little bit slow at first, so I put some time aside to learn about and leverage Reaper's customizability. I remapped my hot keys to those I found myself consistently using/needed, then made a custom action to automate one of the most time intensive parts of the process. Doing this sped up my workflow considerably and allowed me to focus a lot more on crafting great performances from the lines.


1/1
The second pass was for cleanup. Due to my focus on getting quality recordings during our session, there wasn't a whole lot to fix up! I applied a little bit of EQ, some compression, and made any tweaks and spectral edits needed for export. I used Reaper's wildcard feature to automatically name and sort all of the files into folders when rendered.


1/1
Implementation
Since I had the folder structure set up from the Reaper render, importing directly into Wwise was very straightforward. I organized all of the lines into their respective random containers and ran them through a dialogue bus with some effects to give them more of an old speaker/radio vibe.


1/1
I made a dialogue manager in Unity where all lines play from I set up a callback in Wwise to flag when a line has ended so that a random line can be cued up with a variable delay. If a more important line needs to be ran (like the player winning or losing), it overrides the next in queue so that it plays instead.


1/1
Wwise Spatial System
By far, the largest and most exciting challenge technical challenge on this project was to learn and implement Wwise's spatial audio system. Since one of our major goals was to have an immersive horror experience, I felt this system best gave me the tools to accomplish this within the short timeframe we had for development.
Prototype
With us having 5 weeks to make the prototype, I started working on getting it implemented right away. I spent a good amount of time studying Wwise's Spatial Audio in Unity livestreams and the documentation to get an understanding of the major concepts at play and how to set it up in Unity. After taking detailed notes and practicing within a test scene, I felt confident enough to work it into the game itself once we had the map blocked out.


1/1
The final level was big and had relatively complex meshes. I separated each hallway section and room into its own AkRoom and gave each a unique name for future troubleshooting and profiling. For the geometry, applying the AkSurfaceReflectors directly to all of the meshes used a LOT of resources during runtime. So to cut down on this, I used Probuilder to create more simplified meshes for Wwise to read instead.


1/1
By the end of the 5 weeks, I had a solid implementation of the system!
Production
Once we moved from the prototype, we decided that the game would be more replayable and engaging for the player and audience if we introduced randomization in the level layout. Adjusting the system for procedural level generation made me have to change up my approach a little bit.
Every room was created in prefabs for ease of work and generation. With the amount of rooms we were planning, I worked with the artists and designers to make sure they were using prefabs whenever they could. Being able to apply reflectors to commonly used objects helped speed up the process a bit more. I also made Wwise specific prefabs of the common room sizes for me to quickly make rooms.


1/1
Once a room was fully blocked out, I did my initial pass for spatial geometry. Because I worked with programmers to have portals instantiate during level generation, I only needed to focus on creating the AKRoom and reflectors to the prefabs themselves. To preemptively save time (and CPU costs) I analyzed each level layout and only applied reflectors to meshes that I knew would matter in the propagation of the audio.

Rough Blockout - Unity

Rough Blockout - Wwise

Rough Blockout - Unity
1/2
Even so, due of the amount of geometry present in these blockouts, it was very expensive at runtime during testing. Since artists planned on making a simplified mesh pass on the rooms, I decided to hold off on hand-making simple meshes for Wwise until I knew I needed to. Unfortunately, though, this meant that running (and profiling) the game was very hard with how intensive the system's raycasting was.


1/1
What I opted to do instead was adjust the default spatial audio settings to give a better balance between performance and quality for the time being.


1/1
Crash Troubleshooting
A little bit after I begun adding spatial geometry to the generated rooms, programmers started to encounter a problem. Whenever we would generate a new level after the first, the game would crash. Eventually, they narrowed it down to it being caused by Wwise. From there, I took up the reigns to troubleshoot and fix the issue.
Looking at the native stack-trace told me that the crash was coming from Wwise's low level sound engine. It seemed like it was having a segfault from trying to raycast to a reflector that wasn't accessible in memory anymore.


1/1
My initial thought was that reflectors or active events may have not been deleted before regenerating the level, but explicitly deleting them didn't solve the issue. I thought maybe there were too many reflectors for Wwise to keep up and some were slipping through the cracks. However, slowing down the rate they got unregistered and deleted didn't work either. I did the same for all of Wwise's main spatial components, but the crash consistently happened.


1/1
I spent some time talking to my peers, combing through Wwise's and Unity's documentation, and searching through forums and help channels to help me get closer to the answer. After the game loop included the main menu, though, I found that the amount of memory blocks that Wwise's geometry didn't deallocate to a consistent level when going back to the main menu. This was not the case when loading a fabricated version of the level with the same cleanup.


1/1
Using Unity's Memory Profiler, I took captures of the game between level generations and the fabricated scene to narrow down what the issue could be. My next theory, was that it being due to us using a scriptable object to hold the room prefabs, which kept one copy of each (and all the spatial geo) loaded at all times when referenced.


1/1
Changing the level generator to reference prefabs instead made the crash happen less often, which was progress. The profiler identified some leaks and helped me narrow down the cause to the level generator script. I sat down with the programmer who wrote it and spent time troubleshooting together. While we were able to rule out other possibilities, we ran out of angles to try.


1/1
With the end of the project on the horizon, I had one more hunch to try: prefabs may have been loaded into memory through the level generation script but not instantiated. So, I implemented Unity's Addressable's system to be able to explicitly define what prefabs were to be loaded when. Although it cleaned up the project's memory considerably, the leak still happened in Wwise.


1/1
At this point, I've been troubleshooting for almost two months. The deadline was coming up and I needed to move on. I talked with our producer and programmers to figure out how to proceed, and we compromised on cutting level generation and instead using minor randomization in fabricated scene. While I had a few more backup plans to ways to approach the problem, it was in the game's best interest for me to finish some of the other audio work that needed to be done!
Finish & Polish
I went through my optimized geometry pass of all of the finished levels that were in the fabricated scene. On top of not applying reflectors to unneeded geometry, I tagged meshes that I did not want Wwise to use when raycasting for audio propagation. This resulted in the system being significantly more performant than it was before.


1/1
Some meshes at this stage were either too complicated for me to directly plug in the system, or optimized in a way where Wwise had a hard time using it in the system. For these, I took the FBXs of the models and made optimization copies for Wwise to read specifically.


1/1
bottom of page