Memory usage

Managing the amount of memory used is important to ensure a wide range of hardware can run your project. This is particularly important on mobile where limited memory is available. Reducing memory use can also in some cases improve performance.

Images

Usually object images (including sprite animations) are the most memory-consuming part of a project. For this reason Construct 2 estimates the memory use from images and displays it in the status bar. You should keep an eye on this number while developing your project, but it should only be regarded as a rough estimate since export-time optimisations could change it. Remember this is based only on images, so your project will need at least that much memory to run. To ensure your project can run on the broadest possible range of hardware, aim to keep memory use under 100mb. The blog post Remember not to waste your memory has advice on how to best design games to minimise memory use, and common memory-consuming mistakes.

The estimated memory use is based on only the single layout with the largest memory requirement, because only images for one layout are loaded at a time. In Construct 2 this is called layout-by-layout loading.

Layout-by-layout loading

Construct 2 only loads the images for the current layout. This avoids loading the entire project in memory which would be slow and consume a great deal of memory. When starting a layout, all images for the objects placed in the Layout View are pre-loaded. This includes all frames in all animations of any Sprite objects. (In other words, Sprites are either fully loaded in to memory, or not at all - they are never part-loaded.) When the layout ends, all images that are loaded but not used on the next layout are released from memory.

If an object is not placed in the layout view, but events create it at runtime, its images are not pre-loaded. The Construct 2 engine is forced to load the object images at the moment of creation, which can cause a momentary pause in the gameplay, or in extreme cases a constant stuttering (also known as "jank"). In order to avoid this, simply place any objects that will be used by the layout in the layout view. If they are not immediately needed then they can be destroyed in a Start of layout event. They will then not exist when the layout starts, but Construct 2 will still have pre-loaded their images, ensuring that they can later be created at runtime without any jank.

Calculating image memory use

First of all it is important to note the image format has no effect on memory use. You can save on your project's download size by setting some images to PNG-8 or JPEG format in the image editor. However this does nothing to memory use: compressed images cannot be directly rendered, so upon loading all images are decompressed in to a 32-bit ARGB bitmap format. This means each pixel takes four bytes for the alpha, red, green and blue channels.

Consequently, the approximate memory use of an image is simply its number of pixels multiplied by 4. For example a 100x100 image would use 100 x 100 x 4 = 40000 bytes, or about 39kb. A HD-sized image at 1920x1080 would take 1920 x 1080 x 4 = 8294400 bytes, or about 7.9mb. Therefore a good technique to minimise memory use is to use smaller images. As the Remember not to waste your memory blog post highlights, using lots of large images will quickly add up to a huge memory requirement and should be avoided. Export-time spritesheeting and power-of-two restrictions in some GPUs mean the actual memory use per image can vary, but this calculation serves as a good rule of thumb.

It is also important to note that the memory use is based on the source image - that is, as it appears in the image editor. If the object is stretched in the layout view or at runtime, it does not use any more or less memory. It is simply rendering the source image in memory (which is always at its original size) at a different size on to the screen. A good way to create memory-efficient fills or gradients is to have a very small image (e.g. 32x32) with a fill and then stretch that very large in the layout view.

Don't mis-use 'Downscaling quality'

When exporting, Construct 2 runs several optimisations including spritesheeting to save memory. Setting the Downscaling project property to 'High quality' forces spritesheeting to pad out all sprites to power-of-two sizes, negating the memory saving of spritesheets. This can significantly add to the memory requirement of your project. Since 'High quality' mode exists only to address two relatively minor rendering issues (edge fringing on sprites, or altered quality on the last animation frame), it should not be used unless one of these rendering issues has been specifically observed and the issue is resolved by choosing this option. Otherwise your project will be paying a very high price in memory usage for no reason.

Audio

Usually images take up the most of a project's memory use. However it's worth noting how audio is loaded in to memory.

It's important to categorise audio between the sound and music folders because they are loaded differently and therefore have different memory usage.

Sounds

Audio in the 'Sounds' folder is fully decompressed in to memory. This allows sound effects to be played instantly without any latency from having to first load or decompress the audio, ensuring sound effects are heard at the appropriate time. Like with images, the compressed size helps reduce the download but does not reduce memory use: the sound will be decompressed in to PCM wave buffers.

By default the project 'Preload sounds' property is set to 'Yes', meaning all sounds are downloaded and decompressed while the loading bar is showing. As a result all sounds in the project will be decompressed in to memory on startup. With a common playback configuration of 16-bit samples at 44.1 KHz, one second of single-channel audio will use 88000 bytes (about 86kb), and double that for stereo (about 172kb). For one minute of audio, that is about 5mb for single channel and 10mb for stereo. This is the primary reason music tracks should not be categorised as "sound": if you have 15 minutes of stereo music, that will consume 150mb of memory. On some platforms, decoding a full music track can also be quite slow, adding a lot to the startup time.

If 'Preload sounds' is set to 'No', sounds are not loaded during startup and the game can start quicker. However the first time each sound is played may be delayed since it must first download and decode it in full. Using the 'Preload' action in the Audio object can help mitigate this. However Construct 2 never releases sounds once loaded to ensure they can always be played again quickly in future. Therefore setting 'Preload sounds' to 'No' will not save memory if the player plays through the game and every sound effect is heard; it will still accumulate over time to the same memory use that preloading everything would have had. For this reason turning off sound preloading should not be used as a way to save memory.

Audio in the 'Sounds' folder should be short, latency-sensitive sound effects. Consider cutting down any very long duration sound effects - or, if playback latency is not important, consider categorising it as 'Music'.

Music

Contrary to sound effects, music is streamed. Generally this means the audio engine will have a small playback buffer of a fixed length, and while the audio is playing it is loaded, decoded and played in small chunks that connect together seamlessly. This means the memory use is low regardless of the length of the track, and it can even start playing the audio before it has finished downloading. This is why music is not pre-loaded while the loading bar is showing - there's no need to wait for it to finish downloading before starting the game. However playback cannot always start immediately, since it may need to wait for the download to finish buffering, or for the first chunk to load and decode. In terms of memory use, the main consideration is simply to make sure long audio tracks (typically in-game music) is categorised as music and not sound.

Tags: