Tuesday, November 20, 2012

Binary Save Games vs. JSON

I was recently writing some game saving code and I decided to use JSON as my save format (except it was Lua based instead of Javascript). About half way through the project I realized that some of the things I was saving were better saved in binary form. At first I handled this by packing these items into strings but I realized that this was just asking for trouble if someone opened the save files in a text editor. Ultimately I decided to spread the saves into multiple files and mix 'n match the formats to the content. Here are my thoughts on how to save what.

World State (Lots of mostly bits)
A bit here for an opened treasure chest. An integer there for progress in a linear subplot. This is another example where binary shines. Heck, even as something as complicated as WoW quests can be simplified into some bits and items in your inventory.

Map exploration flags (a 2d array of bits)
I can't imagine anyone ever needing to manually tweak this in a save file (aside from setting it to all 1s). This is a prime candidate for binary formats.

Items (varies)
There's two way to do items: fixed or randomized/customized. When your items have optional properties in varying quantities (a la Diablo II) JSON comes in handy because of its flexibility. Fixed items can go either way. If your items are just a collection of static fields binary wins. If you items resemble hand made Diablo II items then JSON is better.

Character data (a hand full of non-optional fields)
Here is an example that lends its self strongly to a binary format, yet has nothing that precludes it from JSON. In the simplest case, you can just "memcpy" from the file into the data structure and run with it. Stats, experience, and gold are all just simple numbers. Equipment and inventory are where this can get tricky. If you have Diablo II style items, you may want to save your whole character as JSON. Another option is saving an item list as JSON, and have a binary character file reference the item file.

In Summary:
Binary Forms are good for

  • Rigidly defined types.
  • Computer use only fields.
  • Efficiency.

JSON is good for

  • Variable length arrays.
  • Optional properties.
  • Data that naturally lends its self to human editing.
  • Changing definitions as the game evolves.