A Simple Solution to Game Serialization Nightmares

If you’re a game programmer, you’ve almost certainly written code to save the state of a game to disk. Basically, your code has to convert every important aspect of a game entity in a format that makes it easy to load the entity again. This is called Serialization. I’ve written many games, and this problem always seems trivial to start when the entity being serialized is not too complex as shown in this code snippet:

// assume the file stream is already open etc..
void Entity::SaveToFile()
{
  Filer.Write(this->ID); // save the entity ID
  Filer.Write(this->Position); // save the position of the entity
}

void Entity::ReadFromFile()
{
  ID = Filer.ReadInteger();       // read the entity ID
  Position = Filer.ReadVector3(); //read the position of the entity
}

No problem right? This is easy enough but this method breaks down if your game entities are constantly evolving as you get further in development… which is almost always the case in a complex game. If you add another property to your Game Entity that must be saved, you have to create a new save format and you break any levels that have been previously saved. The easy solution is to add version numbers to your save/load routines, but this means after a couple of iterations your code looks something like this:

// assume the file stream is already open etc..
void Entity::SaveToFile()
{
   int version = 3;
   Filer.Write(version); // save version number
   Filer.Write(this->ID); // save the entity ID
   Filer.Write(this->Position); // save the position of the entity
   Filer.Write(this->Name ); // save the name of the entity
}
void Entity::ReadFromFile()
{
   version = Filer.ReadInteger();
   ID = Filer.ReadInteger();
   Position = Filer.ReadVector3();
   if ( version ==3 )
     Name = Filer.ReadString();
   else if ( version == 2 )
   {
      ReadInt(); // read an old deprecated property
      Name = "DefaultName";
   }
   else if ( version ==1 )
      Name = "DefaultName";
}

Not pretty, and this is a simple example. A typical game will have dozens of different entity types or components, and you have to maintain new version numbers every time you add anything to your file format. This is a nightmare if you have to maintain backwards compatibility with your old levels.

Thankfully, smart people have solved this problem before, and thankfully I read a book written by one of these smart people. The solution is to use key-value pairs instead of just writing the values themselves to disk. So instead of just writing numbers to disk, you would write something like the following file to disk:

ID=1234
Name="My Entity Name"
Position= 18.2,3.4,1.6

Then when loading the data, you read the ‘keys’ (eg. ID,Name, Position), and determine if you have a use for them in your current format. For example, if we got rid of the “Position” property, we would just simply ignore it the next time we read and old level from disk. You can easily encapsulate all these concepts into a separate Property class, that holds the name, type, and address information of each property. So when you’re all done your code looks like:

Entity::Init()
{
      PropertyTable.Add("Object ID",&ID);
      PropertyTable.Add("Name", &Name );
      PropertyTable.Add("Position", &Position );
}

Entity::SaveToStream()
{
      PropertyTable.SaveToStream();
}

Entity::LoadFromFile()
{
      PropertyTable.LoadFromStream();
}

This code is easier to read, and more importantly MUCH easier to maintain. You can add/remove properties at will, and you don’t have to maintain version numbers. As long as each property’s key is unique, you will be fine. Another nice side effect of this system, is you can use the key/value pairs as data for your in-game tweaking system. In our games, clicking on a game entity automatically brings up it’s properties and allows the level designer to change them at runtime.

Our level editor. The properties on the right are edit and saving-friendly.

Performance

Yes saving everything as key/value pairs is slower and more memory intensive. But usually the difference is not noticeable during development, and is worth the amount of time you’ll save not dealing with save-game version issues. When your game is ready to ship, you simply ignore the keys and save the values in binary format as you always have, with no performance hit to speak of.
Happy Coding!

Why Procedural Worlds have More Drama

I’ve always wanted to create a Role Playing Game. Mostly for financial, practical, and sanity reasons it is not going to happen any time soon. You see to make a vibrant, rich, fictional video-game world takes an insane amount of content creation (art, audio,scripts) and that sounds very expensive.  This doesn’t prevent me from fantasizing about the type of RPG I would make, and so I do.

Procedural Goodness

My ideal RPG world would be entirely procedurally created. The story, the characters, and the landscape would all be created by a computer algorithm instead of by a game designer. I don’t know exactly why I think this is a good idea, but I think one of the main reasons is the unpredictability of the world, and the drama that this causes.

oblivionIn normal RPGs, you enter a dungeon, or a boss fight, or an enchanted forest,  and you know you’re going to beat it eventually and receive a reward. Even if you’re not powerful enough now, you know if you level-up enough and you have enough patience you’re going to beat that part of the game one way or another. There is no drama because the end is a foregone conclusion, you will be victorious.

In a Procedural World, there may be a forest, that is so full of tough enemies, that it is literally impossible to beat. The key is that you don’t know if it’s beatable. That’s what makes it interesting. You’re fighting and it’s hard, and in the back of your mind, you might think this is literally impossible. That’s what makes it dramatic when you actually achieve your goal. You could be the first person ever, including the game’s developers, who have ever done what you have done.

Procedural Worlds will have Asymmetrical Rewards

Maybe if you fight through that dungeon w/ 1000 monsters in it there is no treasure at the end. Why did you go in there in the first place? In the real world, danger doesn’t equal treasure. I don’t jump into a river full of Piranhas expecting an extra large pot of gold do be buried at the bottom. This adds more drama of the situation. You don’t know what’s going to happen at the end.

Creating a procedural world that actually works, and is interesting is a mind-boggling, huge, programming task which is why it hasn’t happened yet. But it will happen. It’s already happening on a smaller scale with Indie games like Dwarf Fortress, Minecraft, and Spelunky. As computers become more and more powerful, these types of procedural games will become more common, which is a Good Thing.

 

A Simple Custom Animated Crowd System

All 4 of our previous games so far have featured some sort of crowd cheering on the athletes or fighters or office workers during gameplay. As a result, I’ve had the task of programming 4 different crowd cheering systems, making adjustments and improvements with each new game. Our last-released game, NLL 11, had the most refined fan system and I’ll describe it here so you can get some ideas in creating your own screaming fans.

The Problem

Suppose you want 10,000 animated fans in your stadium. If you attempt to use normal vertex-skinned models, you’ll quickly become limited by both the CPU and the GPU. The CPU will have problems updating 10,000 different animations (updating the transform of each bone in each model), and the GPU will have problems rendering and blending the bone weights of all those vertices.

The Solution – Billboard Fans

In a nutshell, this solution requires animating and rendering a full-sized model, but instead of rendering it to the screen, you render it to a texture. You then place that texture on a very simple piece of geometry, in our case a quad, and render the quad so that it always faces the camera. Finally you render the same quad again for all 10,000 fans that you want to draw. I used this approach for our Lacrosse game as well as our Beach Volleyball game (which used XBox 360 Avatars as the models). Below I’ve rendered part of our stadium with and without the billboards showing.

snip1snip2

This approach has some huge advantages:

  1. Each fan only requires 4 vertices to be processed by the GPU.
  2. The CPU only has to animate one model.
  3. The animation can be as smooth as you want it to be since you are no longer limited by the number of models to animate.
  4. You can put all of the fans into 1 giant model, so you only have 1 draw call to render all of your animated fans.

Capture2

All of our problems are solved! Not quite, there a few issues that need working out.

Camera Angles

When you render your fan model  it’s from a certain point of view, however the fans in the stadium are all facing different directions and should be rendered from differing camera angles. For example a fan on the baseline of a stadium (behind the net) should not be rendered from the same angle as a fan looking at the action from the sideline. In practice, I found that separating your fans into broad sections such as sideline, baseline, corner etc… and rendering the model from those 3 or 4 angles that you choose worked well enough. This causes some noticeable artifacts along the borders of the sections:

Capture3

But depending on your game, it’s not too noticeable.

Animation Variety

It looks really goofy when all the fans are all clapping or cheering  at the exact same time. The solution for this is to render more models with different animations to get some variety. However, the more models you render the bigger the performance hit, so you have to find the sweet spot between quality and speed. This is still a problem that I’ve noticed in many AAA sports games, fans are often doing identical animations at the exact same time.

Color Shading Variety

Since you are not rendering each fan individually, they inevitably all look exactly the same. You can alleviate this by some GPU Shader trickery. For every vertex in every fan quad, in addition to the usual info (Position, Texture,Normal), you can also add a couple of extra colors to each vertex representing the pants, shirt or skin color of that individual fan. Then in the pixel shader you use those vertex colors to alter the colors of the original texture by multiplying them together with the original texture. You’ll want to separate the shirt/pant colors, so you’ll have to use some sort of mask in your original texture. For my implementation, the original texture had a red shirt and blue pants, so I replaced all the red texels with my desired shirt color, and all the blue texels with my desired pant color.Capture

Optimizations and Details

Texture Swapping

You will end up having a few different renderings of your fan model. If you have 5 different animations at 4 different viewing angles that’s already 20 times you have to render the model per frame. You’ll want to put all of the renders on one big texture, so that you can draw all of the fans in one draw call with no texture swapping.

Draw Order

All the billboards are rendered with alpha blending turned on, so that you only see the fans not the actual quad. This can lead to some funky draw-order bugs depending on your view angle. I found that if you order your fans top-down, so the fans higher up in the arena will be drawn first and the fans close to the field will drawn last, that solves most of these problems.

Given more time and more money, we could really optimize and beautify this fan system more. However, this approach is fairly straightforward (if you’ve done some shader programming before), and it will hopefully get you headed in the right direction in your own creations!

If you want more details or have any questions don’t hesitate to ask in the comments section.

Cheers

-Andy K.