Also I wanted a number of "many element Enum to/from string"
I just cast the enum to an int (or whatever base type, almost always int) and serialize that.
(the best way I could figure out to do that was to translate planets to PlanetIndex, then export/import the planet indices)
Oh, goodness, sorry that wasn't obvious. Yea, we always serialize those by index. And if something has a PrimaryKeyID (GameEntity, PlayerAccount, ControlGroup), we use that.
In short, all serialization is primitive types, no binary/blackbox serialization of complex types.
One caveat is that some of the primary-key-id fields are Int64, and serialize without a specific type named in the code (the CLR automatically knows to use the Int64 overload) but in the deserialization you have to do ReadInt64(), not ReadInt32(). On the bright side when you try to actually deserialize in-game it will immediately cause an error if you try to use the wrong one because the type is encoded in the stream, but you won't know until that actual moment of testing because you won't get a compile error assigning "Int64 someLong = buffer.ReadInt32();"
That could be solved by converting from the "Int64 someLong = buffer.ReadInt32();" pattern to the "Int64 someLong; buffer.Fill(out someLong);" pattern, but the latter is less intuitive (I do use it in the XML stuff).
I suspect if I'd written my code from the beginning to account for the Serialization code paradigm you use then it would have been pretty straightforward.
That was my thought as well.