This blog post is about the voice chat system in the game Suspects: Mystery Mansion by Wildlife Studios. We are Leo Perantoni (technical sound designer) and Felippe Lopes (audio programmer).
We were in charge of replacing the existing voice system API with GME. The main reasons were to improve audio quality and the possibility to have control over what is being sent by the voice channels using the Wwise internal signal flow and spatialization structures, and its effect chains.
Suspects is a social deduction game that features native voice chat, many unique game modes, and regular content updates.
The voice chat in our game was a challenge to set up correctly because it has a lot of situational rules that affect its functionality. For example, mixing and matching 2D and 3D chat with players listening to different channels based on their state: a dead player listens to living players in 3D with attenuation and listens to other dead players in 2D with no attenuation, while living players can only listen to other living players. It can get very confusing!
We’ll go through how we implemented voice chat using the Tencent GME plugin for Wwise.
Multiple Ways to Use GME
In Suspects, there are many systems that control the state of the voice chat:
- Player actions such as muting and unmuting themselves and others
- Gameplay actions such as the start and end of an emergency meeting
- System actions such as trust and safety
All these systems can attempt to change the voice chat state at the same time. Example: The player wants to mute their microphone, the silence system says that they should not listen to other players, and the trust and safety system says that no one should be able to talk.
Therefore, to solve this layered system approach, we used an intention design. Each system declares its intentions of the desired state of the voice chat. These desired states are then merged and applied to the voice chat control using a single channel/room.
While in the lobby or in an emergency meeting, the players can talk with one another in a 2D space. For this, we call the normal receive and send events. In this game state, players can mute and unmute other specific players (using the state system) or themselves.
We used the AddAudioBlockList and RemoveAudioBlockList GME events to handle these player actions, and locally stored the muted players list so we could apply the same actions in all other voice chat types.
Ghost Chat Game Mode
When a player is ejected or killed by an impostor, the player enters the ghost mode chat with all other dead players. Ghosts can hear other ghosts (and other living players depending on the game mode), but if an emergency meeting is called, they can only hear the living players' discussion in the meeting.
To do this, we only unmute the dead players during the match so they can talk to each other in 2D, and we mute them again if an emergency meeting starts.
Chit Chat Game Mode
In the Chit Chat game mode, the players can talk to other nearby players. To implement this feature, we did the following:
1. Called the SetRangeAudioRecvRange GME event method with the proximity radius value.
2. Created a 3D receiver event with attenuation in Wwise.
3. Called this event for all other living players in the lobby.
4. Called the SetReceiveOpenIDWithGameObjectID GME event with the same userID we used in the SetUserID method.
After these steps, we were ready to start a Chit Chat match. Every time the player moves, we update the local position in GME using the SetSelfPosition method.
Emergency Meetings in Chit Chat Mode
The difference between an emergency meeting in the Chit Chat game mode and the standard game mode is that we have to toggle between 3D receiver events (Chit Chat mode) and 2D receiver events (standard mode) before we unmute the players. The same thing happens when the meeting ends, and we call the SetReceiveOpenIDWithGameObjectID GME event with an empty value.
Ghost Chat in Chit Chat Mode
This was the trickiest thing to do. The ghosts can talk and listen to other ghosts in a 2D space and listen to the living players in a 3D space with attenuation at the same time.
To implement ghost chat in Chit Chat mode, we did the following:
1. Called the 2D receiver event.
2. Stopped the 3D receiver events only for the dead players.
3. Called the SetReceiveOpenIDWithGameObjectID GME event with an empty value only for the dead players.
Because the muted list was handled locally, the living players would never hear what was being talked about in the ghost chat.
The image below is a very common example of the Suspects voice chat. All the interactions are running in a single channel and are controlled on the client side.
- Players A and B are alive and can only talk to each other.
- Players C and D are dead, can talk to each other and only listen to players A and B.
- Players E and F are alive, outside the attenuation range of players A and B, and can only talk to each other.
The Wwise setup for the GME audio effects was very straightforward. After importing the plugin to our Wwise session, the work unit created was almost ready to use. We only had to customize it a little bit since we had different needs for situational voice chat.
The basic structure works like this, from top to bottom:
- Audio object with the Tencent GME Send effect instantiated at the end of the effect chain
- Audio object with the Tencent GME Receive effect (this is your ‘listener’ that receives from the Send effect)
- Main System audio device with the Tencent GME Session effect (this creates rooms and user IDs)
The voice quality achieved from the factory setup alone is already pretty great, but since we were dealing with rooms of up to 10 players who could all be listening to one another at the same time, we had to control those dynamics in some way. One of the main issues when dealing with voice chat is its unpredictable behavior. Players can be very quiet or very loud, be in a quiet room or in a very messy sounding environment. We decided to use some Wwise plug-ins to help manage these unpredictable situations.
From our tests and direction, we decided to use a Wwise Parametric EQ to handle certain harsh frequencies that were constantly popping up, and boost the high end to deal with muffled microphones. We also used the Wwise Peak Limiter in multiple stages of our signal path on this system to handle situations in which multiple players are shouting at each other. And lastly, right before the GME Send, we use the Wwise Meter to control a glowing visual effect around the character sprites based on the volume of their voices, so players can easily recognize who they are listening to.
In Unity, we read the Wwise Meter value with the GetRTPCValue method and send the value to the server, where it is replicated to the other player's client, feeding the glowing highlight.
After the GME Send, there are two audio objects with the GME Receive effect: one for 2D chat with no attenuation or speaker panning, and one for 3D chat with attenuation and positioning, which is treated like a common emitter. The last step is the GME Session effect in the main system output object.
One thing we are considering doing in the future, and that is made possible by the GME system, is the usage of more creative audio processing in the voice chat signal path. For example, adding some delay and reverb to the GME Send if you’re in the Ghost Chat (dead players channel). GME enables us to very easily implement things like this.
To cite another example of the creative use of voice chat: you could blend a clean voice and a radio voice based on distance from a teammate. This could be easily done with GME by controlling an effect’s dry/wet parameter with a distance RTPC. On the RTPC threshold to change between clean and radio voice, you could trigger a radio click sound to make it more immersive.
And that covers the Wwise side of the implementation.
GME is very useful for fast iteration with voice chat, and having all the tools to do that inside Wwise is really helpful to control voice quality in real time.
We would like to thank the Wildlife audio team for all the support and voice chat playtest sessions, the Suspects team for engineering and QA support, and our beloved Suspects community. We hope you all enjoy the new voice chat.