Bit of background. I’m a few years into working on a mobile kid’s app, developed in Unity, that is essentially a collection of toys. Quite a few audio assets are used in a number of the toys, and since each toy has a different camera setup, unique events with their own spatializer settings are required.
Recently, instead of adding the same assets directly to each event, I’ve started building 2D events with these assets that can be referenced by unique 3D events in each toy. Organizing the 2D events into a “library”, using folders, has made navigating the sprawling project much easier.
Now for my question: is there a storage savings by working this way - referencing the same assets via the 2D events vs assigning the assets discretely to each events? I’m wondering if selecting “Build metadata and assets to separate banks” in the Build Preferences might be beneficial in this use case.
I hope that all made sense. Any thoughts?
We’ve beaten you to the punch, I’m afraid: FMOD’s built-in optimizations already avoid duplicating content in your banks, so the extra layer of events you’ve added won’t reduce your banks’ size at all.
When you build your project’s banks in FMOD Studio, FMOD Studio avoids adding redundant copies of asset sample data to any given bank. Which is to say, even if multiple events assigned to a bank use the same audio file, FMOD Studio will still only include one copy of that asset’s sample data in the bank.
So, FMOD Studio will build exactly one copy of each asset’s sample data into your banks, regardless of whether you split your assets off into separate shared events as you have. In addition, each additional event in your project has metadata that will be included in your banks, increasing their size; but as metadata is usually tiny compared to sample data, the increase is likely to be negligible.
If you’re trying to reduce the size of your banks, there is one thing that might work: If multiple events that use the same asset are assigned to multiple different banks, then each of those banks will contain exactly its own copy of that asset’s sample data. This is done so that you never have to lod multiple banks to play a single event - but also means that if you’ve currently assigned different events to different banks, you may be able to reduce your banks’ total size by consolidating your banks together.
It won’t. This option splits each of your banks into two banks: One containing sample data, and the other containing metadata. It doesn’t otherwise alter how many copies of your project’s assets are in each bank that contains sample data, so it won’t help you reduce the total size of your built banks.
Thank you for the detailed reply. I’m currently using separate banks for each “toy” so they can be loaded/unloaded as needed, but it turns out the dev team aren’t utilising that, which means I can consolidate the banks.
I still like the idea of having a library of events that can be referenced where they’re needed. Is there any downside to this approach?
Thanks again, Matt
If they’re all using the same assets, that’s probably for the best. When you load banks at run time, the FMOD Engine only loads one copy of each asset into memory, even if you load multiple different banks that contain that asset. This is another optimization designed to reduce resource costs, though this one reduces your game’s memory consumption rather than the size of the bank files on disk.
This is exactly what event instruments were designed for, so it should be fine in most cases. That being said, there are two potential disadvantages.
First, using event instruments rather than putting content directly in the parent events means consuming a very small amount of additional CPU time and memory at run-time. The extra costs are tiny, but they’re not zero, so it’s something to keep in mind if your resource budget is tight.
Second, depending on your game’s bank loading code, the assets for an event instrument may not be loaded into memory until an instance of that instrument is triggered. In some cases (especially if the assets in question are large), this may result in a small amount of latency between the instrument being triggered and its content beginning to play. In many cases this isn’t a problem, either because the timing gap isn’t important or the latency is too small to be noticeable; but if the precise timing of a nested event is important to your game, it’s easily fixed by explicitly loading the nested event’s sampledata into memory prior to playing the parent event.