Thursday, February 9, 2006

C# Serialization Part 2

If anyone has worked with the Unreal engine at all you notice that it has a very robust serialization system that stores objects in package files. A little of the magic behind it can be figured out by browsing the public Unreal/UT source used to build C++ based mods. If anyone has taken a look at the source you would see John Carmak doesn't have anything on Tim Sweeney. The engine is amazingly well designed.

The basic theory of unreal packages is every object in the engine exists in a package. That package could be in memory(if not saved yet) or on disk. When an object is created it is created a part of a package. When the package is saved all the object in the package are serialized in the stream. If any objects in that package reference objects in other packages then a record is saved that tells the deserialization process where to find the object in another package. All this information is rolled up in to the package file.

This brings me to the reason for the post. I've been working on a system for my game engine for managing resources. Since I don't know exactly how it was done for Unreal just the basic theory behind it I've has to fill in the blanks with my own ideas. So this is how it works.

Package cubePkg = Package.Create("MyCubeMaps");
Package texPkg = Package.Create("MyTextures");

CubeMap cm = cubePkg .CreateObject("MyCubeMap");
cm.Faces[0] = texPkg.CreateObject("MyTexture1");
cm.Faces[1] = texPkg.CreateObject("MyTexture2");
cm.Faces[2] = texPkg.CreateObject("MyTexture3");
cm.Faces[3] = texPkg.CreateObject("MyTexture4");
cm.Faces[4] = texPkg.CreateObject("MyTexture5");
cm.Faces[5] = texPkg.CreateObject("MyTexture6");

cubePkg.Save();
texPkg.Save();
Package.UnloadAll();
cm = null;

//Now to load and create the object from disk just call.

cm = Package.LoadObject("MyCubeMaps", "MyCubeMap")

The last call will load all the textures for the cubemap from the MyTextures package when it constructs the MyCubeMap object.