Saturday, 13 March 2010

Resource Management : A Package Based Approach

Hello And welcome to my new post on Resource Management in games.

I decided to write this as all games require various resouces,
yet there are supprisingly few articles
or tutorials on good approaches to the problem of managing them.

firstly a resource can be defined as any exteral asset that can be loaded into the game, for instance sounds, 3d art, textures, and to a certain degree even game scripts can all be considered as resources.
Unfortunately all of these assets take up a lot of storage space and memory, they also have an irritating tendancy to stay in memory after the game has closed down, and most programmers will put a great deal of time into reducing the memory overhead and leaks caused by these resources.

A naïve way to approach resource management, is to not see it as a problem at all, since finding a watertight approach can become quite complex, if a person is just starting and has limited programming knoledge, this approach is perfectly acceptable,

But for an actuall game, these resources must be tracked and released again. 
Any C++ programmer know's and fully understands the usage of the "new" and "delete" operators:

Type * variablename = new Type(); //allocate memory and assign it to a pointer

this method of allocating memory has many advantages to the standard one but has the disadvantage of not being automatically freed when the variable goes out of scope, basically the programmer needs to take controll and delete it again manually:

if(variablename ) 
{
 delete(variablename ); //clear the allocated memory
 variablename =NULL //ensure the pointer is not pointing to arbitary memory
}

when a texture or other resource is loaded in this way it also must be released.

and chasing after every allocation, even in a game the size of tetris can quickly turn into a massive headache.

A better method of getting around this is to create a linked list, of an abstract "resource" type, then create a manager for this list.

any resource type, for instance "texture" will then inherit from the abstract type and define a custom Release method:


 now, I create an instance of the resource manager:

Resource-Manager* resource_mgr = new Resource-Manager();

then I can simply add the resource on creation:

resource_mgr->Add_Resource(new Sound_Resource("beep.wav"));
resource_mgr->Add_Resource(new Texture_Resource("face.bmp")); 

and then on release I simply call the resource managers Release_all() function:

Resource-Manager->Release_All();

and the manager will then call the Release for every resource in the list.

Personally I take this further, and use an xml document to script the resource loading:

 Note: I usually add an xml parser to my projects just because it has so many potential uses, this could just as easily be a simple association list



and add a "name" parameter to the base resource type, now when the xml is parsed the resource manager can be populated, automatically.


since traversing a linked-list is trivial I can create a simple "GetResource()" function that takes in a name string, searches the linked-list for a match and returns a Resource pointer to that node now all I need to do is:

 face_texture = (*Texture_Resource)resource_mgr->GetResource("Face");
 
whenever I need the texture. The massive advantage to all of this is that any new resources can be added without requiring the game to be rebuilt. 

My own system also includes an abstraction over zlib, meaning that all the resources can be loaded from an archive automatically, this archive can then be compressed, password protected, and even encrypted.

Obviously for a tetris clone most of this is overkill but for a project with more than one developer I would strongly suggest looking into this more intellegent system.

In a later post I will go into more detail about the zlib integration (since I found very little on it) and explain some of the other features I have added to my own system.

note: I chose to add zlib since it met my own requirements, this is however not strictly neccisary, if you wish to simply package all of your resources together, a far simpler implementation would be to load all of the resource data into a "flat-file" or an xml file as raw data and then just store the offsets in the linked list, if you do this however it would probably be best to write a tool to make things easier.

As allways, if you have any questions, feedback or comments, please feel free to email me. I also have source code if anyone would like to see it.



Thanks -Ant








No comments:

Post a Comment