Systematic Gaming

June 25, 2009

Asset Management – Runtime

Filed under: asset management — Tags: , , — systematicgaming @ 1:00 am

The runtime layer is the lowest level of asset management encompassing:  file loading, reference counting, instancing and even procedural asset generation.  To meaningfully discuss handling assets at runtime we’ll need to define the different types of assets.  Here’s a few basic types of assets:

  1. Raw data
  2. Instanced data
  3. Procedural assets
  4. Composite data

Raw data refers to data that is static, meaning it doesn’t change during the game’s execution, and loaded off disc when needed.  Textures, sound, music, mesh data, character dialog, and many other types of content would be considered raw data assets.  I’d say that most data – when measured by bytes – falls into this category.  Raw data is the simplest type of asset to manage – it’s either in memory or not, and since it’s static you know it won’t be changed during gameplay.  This means raw data only needs to be loaded once and can be shared trivially.


Instanced data is similar to raw data, in that it represents a single piece of content.  The key difference is that some (or even all) of the data will be modified during game.  This means we can’t simply share this asset; some part of the data will be different each time we use this asset.  Which is where the term instanced data comes from: each instance of this data is slightly different.

A common example of instanced data is an animated model: the polygon data can be shared, but the animated pose of the  joints would be different for each character using the model.


Generated data is an asset that is generated by the game engine.  This type of data includes everything from 100% procedurally generated content to customized data, such as a texture that is re-coloured after loading.  Pretty much all user-generated content can be considered generated data.  Engine-generated data, such as shadow maps or particle vertex buffers, can be considered as generated assets.  The key point is that not all assets are necessarily loaded from disc, where raw and instanced data are usually represented by file, generated data can be more abstract.

It should be mentioned that generated data can also be static like raw data, or act like instanced data or be completely dynamic – as the case is for shadow buffers.

Composite data is an asset that references other assets.  Many assets are almost always build from smaller pieces of data.  Take a simple level from most games: it’s composed of sets of geometry, materials, textures, ambient sounds even gameplay scripts.  A level asset is really just composite data that tells the engine what other assets are needed.

In fact, most game content is composite data in some form, and proper management of these references that forms the goal of any asset management system.


An important point to note is that these asset classifications aren’t mutually exclusive.  You can have instanced generated assets, composite instanced assets, or just about any combination that makes sense.  It’s probably best to think of the above categories as asset properties.

For example you could have a composite generated asset.  It’s even possible to consider instanced assets as a combination of raw data – for the static portion- and a generated asset for the instanced portion.

Low-level Management

Now that we know the basic types of assets, we can figure out how to handle them in our runtime. Our goals are simple: we want to minimize resources (memory) while supporting the various asset types described above.

If we look at our description of a composite asset above, we can best picture it as an acyclic directed graph of data usage – one asset references one or more other assets.  The leaf nodes of our graph are the raw and instanced assets.

It’s now possible to design out system as a simple referenced counted graph.  When an asset is needed we load the referenced data and increment the count.  When we delete an asset, we decrement its references and unload data with a zero count.

This gives us nice and simple system.  To load an assets you just have to load or generate the associated assets and increment the reference count for each shared asset.  You continue recursively until you have no links and only raw data.  Each reference will performs the appropriate action for instanced assets, copying data as necessary.

An asset dependency graph doesn’t just allow us to track which assets need to be loaded, it allows us to reduce load times between levels.  Assuming that two levels have one or more assets in common, we can keep them in memory by loading intelligently:

  1. Increment the refcount of assets in the next level
  2. Decrement the refcount of assets in the current level
  3. Remove all assets with refcount = 0
  4. Load assets from the next level

That simple procedure will keep the shared assets in memory between levels.  The order is important – we must unload the unneeded assets from the current level or we may not have enough memory for the assets in the next level.  Also, loading and unloading assets this way can cause memory fragmentation, so we may choose to handle assets in groups or if possible defragment memory after step 3.  This also requires we have some way of knowing which assets are needed before we begin loading the next level.  We’ll look at these issues in the next article.

As we can see, basic refcounting provides a very simple, yet powerful, way of sharing assets.  Combined with proper data instancing we can manage our assets at runtime with a minumum of overhead and waste.


Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

Blog at

%d bloggers like this: