Wednesday, December 26, 2012

Binary Save Games vs. JSON Revisited

There’s a glaring omission in my original article: "Which format is better when the file format is in flux?" If you use the spiral development model, things are always in flux and this can lead to problems. One big issue with binary files is that there’s very little syntax checking. If your alignment is off by a byte, say you write a byte but forget to update reader method to read it back, then you could wind up crashing or even worse successfully loading data that’s corrupt. This happened to me...
I lost half a day chasing down a bug where I wrote an int but read back a short because the compiler promoted the short I was intending write to an int before writing it. Because the data I happened to be writing was an array of zeros all the shorts looked like they read correctly, but that left an extra 16 bytes of zeros. These zeros were read back as length bytes for the next two sections which were successfully loaded as empty sections without error. The bug I was chasing was why these sections look wrong but technically loaded correctly instead of why the previous section is loading incorrectly but looking correct.

Programming errors aren't the sole source of problems with this either. Another way of causing the same issue is not properly versioning your file. Versioning can be a pain with binary files so I have a tendency to update version numbers only right before a release. That means potential undetected corruption until that point. This is because there is no backwards compatibility in binary files unless you explicitly code it in. JSON fixes this issue because it has a way of detecting missing fields, which you can fill in with default values.

I should mention one last trick. You can always pack binary data into a string in your JSON file and have it both ways. You can use Uuencoding or UTF-8 if your parser is zero-clean(Lua style JSON is). Be sure remember to escape out your control characters. If you have any of your own tips please leave them in the comments.