Posted by Data in Cortex Command - July 14th, 2006

Ok, after a few days of thinking hard and long about what to do with the data file reading/saving system, I’ve finally come to a decision and plan for what to implement.

The CC engine originally used a very simple way of exposing every single object’s variables to the data files by serializing out their values in a certain order. The order of these values determined which variable they belonged to. It looks something like this:

MOSParticle
 MOSprite
  MovableObject
   Object
    Fire Ball 3
   5
   Vector
    0
    0
   Vector
    0
    0
   # Scale
   1.0
   # The rest threshold in ms
   500
   # Lifetime, 0 = unlimited
   250
   # Sharpness factor
   0.1
   # Whether or not this hits other MO:s
   1
   # Whether or not this gets hit by other MO:s
   0   

  ContentFile
   Base.rte/Effects/Effects.dat#Fireball03
  11
  # Sprite offset
  Vector
   -9
   -9
  # Horizontally flipped
  0
  # Rotation angle in radians.
  0
  # Angular velocity in radians / s.
  60
  # Entry Wound Emitter
  None
  # Exit Wound Emitter
  None
  
 Atom
  Vector
   0
   0
  Material
   %Air
  Color
   0
   0
   0
  # Trail Max Length
  0 # Initial framerate in fps. If 0, will be animated over the lifetime
 0  

Note the use of indentation to keep track of the class hierarchy, and # to mark line comments.

This is a very rickety and fragile way of storing game data. Leaving out or mixing up any values would make the order, and therefore the reading procedure get messed up in sometimes hard-to-catch ways. As soon a member variable is added to a class, the data files had to be updated with values for this added variable – Bad. But this old crappy way worked on the small proof-of-concept scale of the current CC Test build!

So what I’ve been thinking about is wheteher to completely replace the current system with something new and probably XML-based, or to just improve upon the existing code, or do something in between. I started going down the path of replacement with an article and sample code of Frederic My’s article in Game Programming Gems 4. It’s a very robust and complete system for custom RTTI (real time type identification, or reflection) and properties-based data persistence. Its files look like this:

<xml>   

<class name=’CRefCount’ base=”>
</class>

<class name=’CPersistent’ base=’CRefCount’>
  <prop name=’Name’ type=’String’/>
</class>

<class name=’CEditorSceneItem’ base=’CPersistent’>
  <prop name=’Deleted’ type=’Bool’/>
  <prop name=’Expanded’ type=’Bool’/>
  <prop name=’Prev Parent’ type=’String’/>
  <prop name=’EditorObj’ type=’SP’/>
  <prop name=’Subitems’ type=’Fct’/>
</class>

<class name=’CEditorObj’ base=’CPersistent’>
  <prop name=’Selected’ type=’Bool’/>
  <prop name=’Deletable’ type=’Bool’/>
  <prop name=’Draggable’ type=’Bool’/>
  <prop name=’DropTarget’ type=’Bool’/>
  <prop name=’Renamable’ type=’Bool’/>
  <prop name=’EngineObj’ type=’SP’/>
</class>

<class name=’CEditorNode’ base=’CEditorObj’>
</class>

<data class=’CEditorNode’ id=’0x16C4D50′>
  scene root
  false
  false
  true
  true
  true
  0x16C3080
</data>

</xml>

Note how he definies how the classes and properties are structured before describing the values. He also uses the current pointer addresses as the unique identifiers for the object instances saved out.

It took some pondering to conclude that I’d probably spend more time gutting my existing code and replacing it with an adjusted and adapted version of My’s sample code to make it worth it. I also don’t have much use for some of the benefits of his techniques, since I’ve already engineered my code to work around the shortcomings of my original techniques.

After reading this excellent thread by the Moonpod guys on XML, I had to reconsider once more whether I should go with my own format or some XML flavor:
http://www.moonpod.com/board/viewtopic.php?p=15369#15369

Although the DTD’s are a compelling and really interesting feature, I’ve decided that readability and ease-of-editing are my highest priorities. XML just isn’t very readable or convenient to edit with all those closing tags and different ways of formatting things. I prefer to keep things simple and with little room for my formatting obsessive-compulsiveness to freak out when I change my mind about pointless conventions.

Another big priority is to keep things very self-documenting, and that was why I actually didn’t like My’s way of keeping the property definintions in a separate place in the file. When I’m editing something, I’d like for the documentation to be right there in some way so i don’t have to look it up in the code or somewhere elese. This’ll be even more important for any modders who want to change things around in these files and don’t have the code to refer to.

Finally, the last important benefit I’m seeking is to be able to omit as much redundant data as possible in these files. I found that even in the CC test, I ended up with really long files to scroll through, and much of it was just default value filler to keep the order intact. If I can just keep the defaults of an intialized and read object by omitting those values in the data files, I’ll be much better off. This’ll also help keep old data files working with new versions of the code since they’ll just define their old values and leave loaded objects’ undefined properties with safe default values.

Anyway, if you’re still reading this, here’s the way the new format I’ve come up with will look like:

 Effect = MOSParticle
 Parent = MOSprite
  Parent = MovableObject
   Parent = Object
    InstanceName = Fire Ball 3
   Mass = 5 # kg
   Position = Vector
    X = 0
    Y = 0
   Velocity = Vector
    X = 0
    Y = 0
   Scale = 1.0
   RestThreshold = 500 # in ms
   Lifetime = 250 # ms, 0 means unlimited   
   SharpnessFactor = 0.1
   HitsMOs = 1
   GetsHitByMOs = 0
  SpriteFile = ContentFile
   FilePath = Base.rte/Effects/Effects.dat#Fireball03
  Frames = 11
  SpriteOffset = Vector
   X = -9
   Y = -9
  HorizontallyFlipped = 0
  Rotation = 0 # radians
  AngularVelocity = 60 # radians / s
  EntryWoundEmitter = None
  ExitWoundEmitter = None
 Atom = Atom
  Offset = Vector
   X = 0
   Y = 0
  Material = Material
   %Air
  AtomColor = Color
   R = 0
   G = 0
   B = 0
  TrailMaxLength = 0
 InitialFramerate = 0 # fps. If 0, will be animated over the lifetime

# are still comments. Everything before an equal sign is the property’s name, and everything after is the corresponding value. % means to set the entire object’s data to that of one which is already defined. Properties can be in any order, or omitted. The big constraint is that the tab indentation now matters, so that’s a source for errors, but I think it’s a good tradeoff to having some kind of nested opening and closing brackets (e.g. { and }) all over the place. 

That’s all for now… my tired brain going to bed. Tomorrow is all about retrofitting the old code with this crazy new system.

You can follow any responses to this entry through the RSS 2.0 feed.
Both comments and pings are currently closed.


7 Responses to “CC’s new data file structure”

  1. Fat Zombie - # July 14th, 2006 at 3:43 pm

    Ah. Yes. Of course. *pretends to understand*

    So this will make the game easier to code? It looks neater, therefore it must be better!

    Yes.

  2. Data - # July 14th, 2006 at 5:53 pm

    It’ll make the game content easier to make and to mod, for you! Wanna change the weapons or the way the vehicles and guys work, down to the smallest detail? Just find the corresponding Weapons.ini or Actors.ini, open it up in notepad and the rest should be pretty self-explanatory!

  3. Ikkonoishi - # July 15th, 2006 at 7:50 pm

    Will this support any form of inheratance? For instance could we create a new pistol type and set it to use the standard pistol art and object, but shoot a different type of ammo?

  4. Data - # July 15th, 2006 at 10:35 pm

    Yeah, that’s what the ‘%Instance Name’ syntax is going to be for. It has to be placed before all the other properties, and will make the object you’re defining get all the values of the Instance Name object previously defined.

    Then the additional properties set will override the ones copied from the referred to object.

    So, in your example, it could look something like:

    HDFirearm = My New Gun
       %My Old Gun
       AmmoSprite = ContentFile
           Path = IkkoPack.rte/NewGunAmmo.bmp

    and that would be everything necessary to define this modified gun called My New Gun, which is exactly like the other weapon called My Old Gun, except it’s got a differnt ammo sprite.

    I’m still working on the details as I go along.

  5. gnat - # July 17th, 2006 at 11:47 am

    A pretty sexy system you have there dan 🙂

    Looking forward to seeing it implemented in the new versions of CC

  6. ZoeJane - # July 22nd, 2006 at 11:30 pm

    *can’t even pretend to understand….* but Good Work! Hope your revamped code makes the gameplay better for all involved.

  7. Alex - # April 25th, 2007 at 10:05 am

    Thank You