Version
The Default memory pool contains the structural metadata related to the sounds and Events loaded into memory. It contains all the properties of the objects in your project necessary to implement the behaviors defined in Wwise. It also contains all the registered game objects and their related information, including game sync values, position, orientation, and so on. As more banks are loaded into memory, more metadata is added as well, requiring a larger default memory pool size. The size will ultimately depend only on the amount of sounds that can possibly be played in one scenario, level, map, game area, and so on.
Note | |
---|---|
The default memory pool does NOT contain any media. |
Each sound structure and Event combination takes on average about 300 bytes of memory in the default memory pool. If, for example, your project had 50,000+ sounds (including dialog), this would require approximately 15MB of memory for the structural data only. As you can see, you can't load it all into memory at once, so you need to load and unload structural data in the same way as you load and unload media.
Based on the Wwise projects we have seen to date, sound structures account for the biggest part of the default memory pool (anywhere between 25-50%) due to the sheer number of them loaded into memory. Of course, the less sounds you have loaded, the smaller the default memory pool will be. The next biggest user of memory is the Event metadata, which usually takes about 10% of the pool. Events are very small, so even though you may have many, they don't take up that much space. The Random/Sequence Container structure is probably the biggest single user of memory taking about three times the memory of a simple sound. However, since there are generally far fewer random/Sequence Containers than either sounds or events, these take up much less of the pool's memory as a whole.
As a general rule, open-world games tend to have a larger memory requirement because more sounds need to be ready to play. Such games will need anywhere from 5 to 8 MB for the default memory pool. Other types of games can get by with a much lower usage, for example 2-3 MB. Please note that these numbers have been provided to give you an idea of what other games using Wwise have required, but in no way guarantee that your particular game design will fit within these memory ranges.
The following best practices can help you reduce the memory used by the default memory pool:
Split big banks with lots of sound structures and Events into smaller banks. Load and unload banks dynamically, as needed. Make sure that your banks are not only organized per-character, but have more situational divisions.
Reduce the number of Events by using the ExecuteActionOnEvent API. Play/Stop pairs can be replaced by a single Play Event and a call to ExecuteActionOnEvent for the Stop. The same is true for Pause/Resume, for the same Play event.
Tightly manage your game objects. Unregister them as soon as their role is finished. Avoid keeping a pool of unused game objects alive; there is absolutely no gain in doing this, but it can cost in memory. For example: when an NPC dies, you should unregister its game object. Don't re-use it for something else. Register a brand new game object when one is needed. As a general rule, if you have thousands of game objects alive, it is too many.
Use Virtual Folders to organize sounds and not Actor-Mixers. Virtual Folders don't take memory, actor-mixers do. Only use actor-mixers if the objects actually share similar properties other than the default. In this case, you save memory using the actor-mixer because the property is there once only. Of course, this also depends if the Actor-Mixer is referenced by Events, such as Set Voice Volume or Set Voice Pitch.
Try to reduce the size and complexity of large hierarchies. A common example of a large hierarchy would be an Impact hierarchy or a Footstep hierarchy. With lots of variables, it can grow large and unfortunately can't be split (the media can be, but not the structure data). Here are a few ways to reduce such a hierarchy:
Use RTPCs if the only thing changing is a simple property (same samples but different volume/pitch/randomizer and so on.).
Replace some levels (or all) of the Switch hierarchy with a Dialogue Event with equivalent State Groups. This is useful for variables that change often. For example, in an impact hierarchy, there is no pre-determined surface that will be hit, you only know when the Event occurred. Instead of using a Switch Container, which needs to keep the Switch value, you could use a Dialogue Event with a State Group with the same possible state values. One of the advantages is that the Dialogue Event can easily re-use the same samples or sub-structures. Also, the Dialogue Event uses no memory per-game object. Also remember that you can link a path to a Switch Container, adding another level of variables.
An example where this can be used is for footsteps. The Dialogue Event would have maybe one or two State Groups, such as Step Type (Walk/Run) and Surface Type, and each path could link to a Switch Container for 'Footwear Types' with values, such as 'Boots', 'Civilian shoes', 'Barefoot'. The logic being that the 'Footwear' doesn't change often in the life of the game object but the other two variables do.
Another advantage to this method is that Dialogue Events can live in an event-only bank without the associated sound structures that it plays. This means that you can split the complex sound structures associated with the Event between many banks. Using the footsteps example, this would mean that you can have the footstep Dialogue Event in BankEvent, have the Concrete-related structure and media in BankConcrete, the Dirt-related structure and media in BankDirt, and so on. For this to work, you would simply have to load and unload SoundBanks dynamically as the surface types are about to be encountered.
Split your Switch Container hierarchy into multiple SoundBanks. When you add a Switch Container to a SoundBank, all of its sub-branches are also included automatically. You can, however, exclude some of these sub-branches manually on either the Game Syncs or Edit tabs of the SoundBank Editor. Let's say, for example, that you have a Footstep hierarchy, where the top-level Switch variable is the surface type. If not all surface types are required at all times in your game, you could split the Switch Container hierarchy across different banks and then load only those surface types that are necessary, depending on the context in game. For example, you could have a main Footstep bank containing the surfaces that are encountered everywhere in the game, such as Concrete and Metal Stairs, and then have other contextual banks for specific surfaces that are only used in one scene or section of the game, such as Mud, for example.
Replace impact-type WAV files used to create variations of a sound with a SoundSeed Impact equivalent. Replacing 10 different 'clang' sounds with one is not only economical, but it will give you more than 10 possible variations. Don't neglect this possibility, as it can really make a difference.
Questions? Problems? Need more info? Contact us, and we can help!
Visit our Support pageRegister your project and we'll help you get started with no strings attached!
Get started with Wwise