March 01, 2007

Prototyping a renderer in seven days - Content Pipeline

In the last days I did a small experimentation on prototyping : prototyping a 3D renderer as complete as it could be in seven days but as I was overloaded by homeworks and exams (midterm) I didn't forced it to be seven consecutive days. It took me around two weeks to complete the experiment and have a basic prototyped renderer.

The goals of the experiment were mostly to try new things that I had in mind but couldn't scale to the current design of what I was working on and to see what I could achieve under such a short deadline. In the next days I'll present what has been done during that experiment in a way that looks like a postmortem ;).


Content Pipeline

One of the thing I wanted to experiment the most is the content pipeline. I wanted something flexible/extensible to drive all the content of the game, something that would be easy to read and modify by artists. To achieve this I based everything on XML using the TinyXML library. All content objects were XML files describing all that is needed to load the resources.

Every content file was assigned to a loader for the resource to be loaded. Every content loader loads a IContent object which is a loaded resource and can be casted to its real type later.


The ContentManager class was designed to choose which loader to use to load a certain content file.


Once the content loader is created you need to register it with the ContentManager which will read the type of content its loading and the ID of the loader. It will use that information later during the loading to choose the right loader for the content (by using the loader ID in the content's XML file).


What went right

The concept itself was great : all the content the engine uses was data driven. In other words, if a game was using a content model which was called "models/monster" anyone could go and replace the mesh and texture that the content file was loading and the engine will just load those files instead (no need to recompile).

It's easy to add new functionalities to this system. If you need a loader that is not already there, just create a new class inheriting the IContentLoader class and register an instance with the ContentManager. Once the loader is registered the system is ready to load that new type of file.


What went wrong

Lack of time to make proper tools. Because of that I had to bypass the system and directly load the texture files and the mesh files. I wanted everything to be driven by the XML files, the ContentManager just loading XML files and using the proper loaders to load the content. Proper tools is probably the most important thing for easily integrating the content into the engine and seven days prototyping without any plan didn't allow me to work on tools (for example I had to rely on what is already available in the .X format for the models).


How to improve the design


Having a tool that creates packages (like pak of zip files). Creating the XML files for the content could be linked with that process and those could be part of the same archive. Using package files is often to solve performance issues and it should be an obligation for the release build but during the creation of the game the system should be able to load content from the folders directly.

Content hotloading would also be a great feature to add to the content manager to ease the job of the artists. Hotloading is done by monitoring the filesystem for changes and notifying the ContentManager of any changes in the loaded assets. The ContentManager then reloads the modified content and updates the other systems (like the scene object database).

0 comments: