Monday, 21 March 2011

HS: JSON item loader

I've spent most of today fighting with json.net in order to be able to load items out of on-disk json. You might question the wisdom of storing items in scraps of json, but I was considering using XML and remembered that my adventurous editing of Civ4's XML are still throwing a handful of errors because I have presumably failed to line up some closing tags somewhere or other.

JSON looks nice and clean by comparison:

{
"name":"Colt 1911",
"description":"Classic slimline .45ACP with single-stacked 7-round magazine and auto-loading action.",
"available":"1911-01-01 00:00:00",
"obsolete":"2010-01-01 00:00:00",
"matrix": "11-10",
"mass_kg": 1.1,
"image_offset": [64, 0, 64, 64]
}


Unfortunately, actually getting that loaded up was less than simple, in two areas - first, "image offset" is actually an XNA Rectangle in code, but neither C# nor json.net is clever enough to be able to turn a 4-element array into a Rectangle. There isn't even an array-parameterized constructor for Rectangle, which really is rubbish.

The other problem was the "matrix" key, which started life as a multidimensional array. Unfortunately, json.net can't parse multidimensional arrays, infuriatingly. So I've actually made it a cleaner, more compact string-based format that is turned into an array after load.

What really had me stumped for a long time was how to parse only bits of a json object into my C# object. I eventually marked matrix and image_offset as [JsonIgnore], used JsonConvert.PopulateObject to fill almost everything in and then made a JObject of the input string and used that for the few extra bits in a totally non-intuitive way, thus:

int[] r = JsonConvert.DeserializeObject(job["image_offset"].ToString());

See? Anyway, I think I've got the hang of it now.


You can also see that items clone themselves nicely, and shade in the boxes that they occupy in inventory. They're also loaded and saved depending on which person you select. That all sounds like quite a lot of progress, actually!

No comments:

Post a Comment