Our new sound engine has shipped, giving game developers a more robust system for playing in-game sounds and laying the groundwork for exciting updates and features that are on their way. Building this new sound engine was an arduous process, but the end goal was always quite simple: synchronized cross-server sounds that play every time they’re called, no matter what. I’m going to use this article to walk you through how the Client team achieved this, talk about upgrades yet to come, and offer tips and suggestions to get you acclimated to the new engine.

This chart illustrates how our sound system used to work:

With this method, the sounds you hear in ROBLOX are based off of “Play Calls” to sound objects. As you can see, there are two events

The finding and asynchronous loading of the Sound ID, and… If the sound loads in time, the playing of the sound.

The problem with this method is there is no forced ordering of these events, meaning if/when they happen in an undesired order, you won’t get the results you want. This is a flawed system that has caused pain for developers, who often have to add artificial delays to their Play Calls in an effort to ensure sounds will play as desired. Artificial delays work less than 100% of the time and are hacky and time consuming. We want everyone to hear every sound, every time they’re called to be played.

So, we developed a new system that looks like this:

Calling play now initiates a different series of events, in which the Play Call remembers to play rather than trying to play as soon as possible. This is an important distinction. The internal callback that takes place after the asynchronous load of the sound checks to see what sound is being asked to play. As always, if the sound is loaded, it will play immediately. The most fundamental difference is that if it’s not loaded, it will wait until it has loaded, then play. This forces an ordering of events — an invariant — that makes it so there’s no possibility of any sounds being out of sync, because the system is built to wait until the sound is loaded before it plays. No sounds are forgotten, and every sound in the queue must play. Ever use Chat Voice by Mad Studio and notice that sometimes your commands don’t create audio? That’s a thing of the past.

These changes shouldn’t abruptly change your ROBLOX development experience, but there is something we’d like you to note. If a sound object exists in your Workspace or underneath a part and is in a “Play” state, players will hear that object every time they join your game. Be mindful of the sounds you have loaded in your game and make sure to call Stop to, well, stop this from happening.

As I mentioned earlier, this update lays the ground work for exciting projects in the ROBLOX world of sound. The Client team has been working on new properties you can set in Studio to give you even more fine-grained control of your sounds — two of these properties will be called TimePosition and TimeLength. I don’t want to give too much away (though some of our more experienced builders will already know what the implications of such properties entail), so stay tuned to the blog, as I’ll be sure and post about these updates as soon as they happen.