Today we will be looking at (and listening to!) many of the sound improvements we have been working on for 2.0.
The sound an entity makes when it is active is usually a single looping main sound, some entities might have sounds that play when they become active or when they stop working and go idle. In addition there are several properties and modifiers that can be used to control working sounds a little bit more. But there is only so much one can do creatively with a single looping sound when it needs to work in all situations.
The ability to synchronize the sounds of a machine to its animation was very high on the list of requested audio features. What I came up with was the concept of Sound accents. Shorter sounds which get played at a specific frame of a specific animation. Initially I expected a machine would get two or three sound accents to complement its main sound and that would be it. But Ian had other ideas.
Starting with the foundry, besides its main sound, there are twelve sound accents to emphasize individual components and sections of the animation. And he didn't stop there, there are now machines with an even more complex sound set. We might show them at some later date, but now let's get back to the foundry.
Working sound visualization on the right, bigger box represents the main sound, smaller boxes represent individual sound accents.
Trying to speed up or slow down a sound of a machine to match its animation speed (modules, beacons, low power) doesn't work very well (slowing down especially). That's why in 1.1 it's used rarely and we only speed sounds up, for example steam engine sound works like this. But having many shorter sounds directly tied to specific animation frames solves this problem in a natural way.
Fast foundry on the left and very slow foundry on the right.
Now that we have multiple sounds for one machine in the form of sound accents, could we do something interesting by having multiple main sounds as well? As it turns out, yes! If we combine it with some other tricks of ours. Mainly activity matching, the ability to match a sound's volume or playback speed to the machine's activity rate. Activity rate is the way a machine reports how fast it's doing whatever it's doing, it could be as simple as reporting 1.0 when it's working and 0.0 otherwise. It could be a vehicle's speed, or something a little more creative.
Let's look at a couple of examples with vehicles to see what we can do with it in 2.0.
In 1.1 a car has one main sound which plays faster as the car goes faster. This is serviceable but we can do better. Let's use two sounds, idling sound and driving sound. As the car's speed increases, the idling sound's volume quickly decreases until is completely silent, at the same time the driving sound's volume increases from silence to its maximum volume. At some point the driving sound's pitch starts to increase as well, though this is scaled so it doesn't go too high.
The tank received the same treatment, together with a separate sound for its tracks.
And of course trains couldn't have been left behind. This includes different sounds when the train is on elevated rails.
Did you notice the different sounds when the car was going over different tiles or resources, or the sounds that cargo wagon doors made in the previous videos? They don't work well as working sounds, so a different approach was needed.
We could add special logic into each entity's update to handle additional sounds and we've done that for some things in the past, for example artillery turret had its rotation sound in the update logic. This is fine only as long as the number of entities with additional sound logic is very small, but becomes inefficient and wasteful when you try to add sounds to entities there is a lot of (like mining drills and robots).
We really wanted it, so a new system, creatively named Additional sounds, was born. A bunch of old and new entities already take advantage of this system, let's take a look at one of them, the big mining drill (last time it was shown it had only placeholder sounds).
We had many ideas for 1.0 that we weren't able to implement at the time. One was having a more immersive ambient system, rather than just one wind sound. I devised a wind system that played a different wind track when you are zoomed in, one that was quite basic, then a more interesting one as you zoomed out (with a cross-fade between the two). This evolved into the idea of having a semi-persistent ambience, for example on Vulcanus you can hear the sound of distant volcanos at a low level, with pauses of varying lengths.
But how about adding more specific ambient sounds based on the players location? For this we couldn't use the usual game industry approach of ambient trigger boxes or pre-painted regions, because our maps are generated, not handmade. So we came up with the idea of adding sounds to tiles and entities based on specific conditions.
Once we had this tech in place, I started to add sounds such as a gentle water-lap to bodies of water and leaf rustle to trees. I then realised that we could have invisible creatures, for example small non-hostile alien birds in the trees, that only play if the player is within a certain radius of trees numbering above a specified threshold. There is also a random pause between each sound. Taking this idea further, we are able to specify whether they play according to the time of day, or the zoom level of the camera.
Next time you're setting a forest on fire, remember it might be someone's home.
When we released 1.0, Kovarex told me that it was his wish to have item specific inventory sounds in the game. At that time we only had one sound for moving items, and it was okay, but maybe a little bit boring, and it didn't give you any special feedback. He explained that they needed to be a bit like the wire connect and disconnect sounds, and this helped me to understand what he meant.
Through trial and error, I worked out what sounds could be grouped together (e.g. small and large metallic items) and which needed to be unique. Some needed more iteration than others, as it was sometimes hard to figure out what the sound should be. After all, what is the sound of a Speed module? In that particular case, I ended up using a synth sound as it needed to be abstract.
It was mentioned that ambient sounds have some more control over their volume. When this was done, Ian would start asking if it could be used for other sounds as well. I didn't see any reason why not so I took all of these parameters and put them together into Advanced volume control properties. They let us do some neat things.
The attenuation with distance can be changed from the default linear to a more natural sounding exponential curve. There is also the option of logarithmic, cosine or S-curve or no attenuation at all if you want to do something different. We can change how the sound attenuates with the zoom level in a similar way. It's possible to specify a darkness threshold in order to have certain sounds play only at night time. Last tool in this toolbox are Dynamic sound modifiers. These allow us to change the level of a sound just for a specific game context. There can be dynamic volume modifiers which are applied only when in the menu simulation or when in tips and tricks, when driving a vehicle or when a train is on elevated rails.
In certain situations, there can be a lot of sounds wanting to be played at the same time. Combat with many biters is a typical scenario, biters and turrets attacking create a lot of sound. If there wasn't a hard limit on the number of sounds that can play at a given time, it could quickly turn into a wall of noise.
Sound aggregation is one way to deal with this, when a sound would be playing many times, instances of it that exceed a certain limit can be culled or have their volume reduced. This system is already in 1.1 but it can be used only for handful of sounds in specific scenarios. For 2.0 the system was greatly improved to be usable by most sounds and more control over which sounds will be adjusted was added. With these changes the soundscape of those problematic scenarios is now under control.
Related to the problem of having too many sounds is that sometimes there wouldn't be enough resources left for more important sounds, for example GUI effects or certain player actions. The obvious solution is to introduce a priority system for sounds and that's exactly what we did. To kick things off, many player actions like building were given higher priority and several biter sounds were deprioritized.
We like tests around here. Soon after I started working on various sound related issues and features I also began building up our audio test suite. Starting with creating a simple framework to be able to test at least basic audio features, like checking a sound is playing when it's supposed to. The suite grew over time, covering existing features and fixes for various bugs, as well as covering brand new features (and fixes for brand new bugs).
Having such a test suite proved extremely helpful when redesigning or expanding different parts of the audio system and is very helpful to make sure those pesky bugs won't creep their way back in.
I am sure you all want to hear about the new music coming in Factorio: Space Age, but we are saving that for a future FFF, stay tuned!
All of these new or improved features, with the exception of the custom logic of additional sounds, are available in prototypes, modders will be able to use them in the same way as we do in-house.
As always, sound out your thoughts at the usual places.