I'm still doing the derp thing but I think I have a reasonable way of doing it in the code.
Since I'm outputting to XML, I figured why not just have the objects set up the XML structure on their own, right? (also yes, I noticed the spelling mistakes, will be fixing that in one of the next revisions).
<OutpostHD_SaveGame version="0.01">
<properties planetname="Planet Name -- DUMMY" sitemap="maps/mars_04" sitemapname="Sitemap Name -- DUMMY" tset="tsets/mars.png" diggingdepth="4" />
<view_parameters currentdepth="0" viewlocation_x="183" viewlocation_y="30" />
<mines>
<mine x="33" y="121" age="0" depth="0" active="0" exhausted="0" yield="1" />
<mine x="126" y="76" age="0" depth="0" active="0" exhausted="0" yield="0" />
<mine x="273" y="124" age="0" depth="0" active="0" exhausted="0" yield="1" />
<mine x="10" y="55" age="0" depth="0" active="0" exhausted="0" yield="1" />
<mine x="255" y="49" age="0" depth="0" active="0" exhausted="0" yield="0" />
<mine x="113" y="21" age="0" depth="0" active="0" exhausted="0" yield="1" />
<mine x="283" y="101" age="0" depth="0" active="0" exhausted="0" yield="1" />
<mine x="270" y="103" age="0" depth="0" active="0" exhausted="0" yield="2" />
<mine x="123" y="32" age="0" depth="0" active="0" exhausted="0" yield="1" />
<mine x="76" y="60" age="0" depth="0" active="0" exhausted="0" yield="1" />
<mine x="105" y="36" age="0" depth="0" active="0" exhausted="0" yield="1" />
<mine x="79" y="48" age="0" depth="0" active="0" exhausted="0" yield="1" />
<mine x="260" y="95" age="0" depth="0" active="0" exhausted="0" yield="2" />
<mine x="81" y="110" age="0" depth="0" active="0" exhausted="0" yield="1" />
</mines>
<tiles>
<tile x="184" y="36" depth="0" index="0" />
<tile x="186" y="34" depth="0" index="0" />
<tile x="189" y="36" depth="0" index="0" />
<tile x="189" y="37" depth="0" index="0" />
<tile x="189" y="38" depth="0" index="0" />
</tiles>
<structures>
<structure x="185" y="35" depth="0" id="64185312" age="48" state="1" type="2" direction="1" />
<structure x="185" y="36" depth="0" id="64412400" age="0" state="0" type="13" direction="1" />
<structure x="186" y="37" depth="0" id="111595704" age="0" state="0" type="13" direction="1" />
<structure x="187" y="37" depth="0" id="111596032" age="48" state="1" type="11" direction="1">
<production common_metals_ore="196" common_minerals_ore="30" rare_metals_ore="8" rare_minerals_ore="16" common_metals="0" common_mminerals="0" rare_metals="0" rare_mminerals="0" energy="0" food="0" />
</structure>
<structure x="257" y="8" depth="0" id="111596360" age="35" state="2" type="8" direction="1">
<production common_metals_ore="0" common_minerals_ore="12" rare_metals_ore="8" rare_minerals_ore="8" common_metals="0" common_mminerals="0" rare_metals="0" rare_mminerals="0" energy="0" food="0" />
<storage common_metals_ore="130" common_minerals_ore="154" rare_metals_ore="96" rare_minerals_ore="120" common_metals="0" common_mminerals="0" rare_metals="0" rare_mminerals="0" energy="0" food="0" />
</structure>
<structure x="187" y="35" depth="0" id="111599096" age="48" state="1" type="0" direction="1" />
<structure x="186" y="36" depth="0" id="113860920" age="48" state="1" type="6" direction="1" />
<structure x="188" y="36" depth="0" id="114327688" age="25" state="1" type="12" direction="1" />
<structure x="186" y="35" depth="0" id="114353432" age="0" state="0" type="13" direction="1" />
<structure x="242" y="53" depth="0" id="114428832" age="41" state="1" type="8" direction="1">
<storage common_metals_ore="0" common_minerals_ore="0" rare_metals_ore="0" rare_minerals_ore="8" common_metals="0" common_mminerals="0" rare_metals="0" rare_mminerals="0" energy="0" food="0" />
</structure>
<structure x="187" y="36" depth="0" id="114429208" age="0" state="0" type="13" direction="1" />
</structures>
<factories>
<factory x="185" y="37" depth="0" id="114429536" age="48" state="1" type="3" direction="1" production_completed="0" production_type="0" />
</factories>
</OutpostHD_SaveGame>
Which is precisely what I expect and want. This is prone to breaking though as I'm using implicit conversions of enumerated types to integers, something which can cause subtle (and not so subtle) errors if the enumerations change. E.g., if I have a structure enumerator as such:
enum StructureType
{
STRUCTURE_AGRIDOME,
STRUCTURE_MINE_FACILITY,
STRUCTURE_WHATEVER
};
And later on down the line add a new enumerator in between what's already there:
enum StructureType
{
STRUCTURE_AGRIDOME,
STRUCTURE_ATMOSPHERE, // new enumeration
STRUCTURE_MINE_FACILITY,
STRUCTURE_WHATEVER
};
Mine Facility and Whatever will now be assigned different integer values and loading in an older save game will lead to the wrong structures being instantiated.
I see three solutions, none of which I particularly like. I can either explicitly define the numeric value of the enumeration (don't like this idea as the point of the enumeration is to be able to treat it as a type vs. a distinct value), I can only add new enumerations to the end of the enumerator list (still don't like this idea because I'm really picky about alphabetizing enumerations) and the final which is what I'm probably going to settle on, every time the enumerations change, update the version string and have the game either fail to load the game or tell the player that their game will behave funny.
I think the last of the options is the least of the evils because it avoids dealing with first two problems but also allows for 'conversion' tools to be written to 'upgrade' a savegame from an older version of the game, something I hate doing (because what if someone saved a game in v0.6.0 but never picked it back up until 1.2.1? Undoubtedly there would be LARGE changes between all those versions so you'd have to run the save game through a chain of upgrade tools).
There's also a fourth option of defining all structure I think I may use or just setting several aside as 'reserved', but I really don't care for that either.
I dunno... thoughts?