23 Mar, 2010, Runter wrote in the 1st comment:
Votes: 0
So far I've been dumping object serializations and loading them directly from that format. This brings me to a problem: Once a game goes out of production using this they'd have trouble making changes to object structure, i.e. multiple versions, without losing the original data. This problem extends to more areas than just objects in game. It's also player files, etc etc.

So my question is how do you guys suggest handling this? Any version system seems like it's going to be ugly, but it sounds like a feature that will be useful for post production games.
23 Mar, 2010, Idealiad wrote in the 2nd comment:
Votes: 0
Wait, didn't this get discussed recently…? In any case, I think the conclusion was (a) save data, not objects, and (b) use a key:value system such that unrecognized keys in the save file are ignored by the object structure, and keys in the object structure with no corresponding value in the save file get some sane default.
23 Mar, 2010, Runter wrote in the 3rd comment:
Votes: 0
Idealiad said:
Wait, didn't this get discussed recently…? In any case, I think the conclusion was (a) save data, not objects, and (b) use a key:value system such that unrecognized keys in the save file are ignored by the object structure, and keys in the object structure with no corresponding value in the save file get some sane default.


Thanks. If it was discussed I must have missed it. :)
23 Mar, 2010, Runter wrote in the 4th comment:
Votes: 0
Linked for anyone following.

Looks like this is perhaps what you meant.
23 Mar, 2010, JohnnyStarr wrote in the 5th comment:
Votes: 0
If you are using Ruby and Yaml then whats the problem?
I mean, if you are removing a bunch of stuff from your objects then sure, I can see that.
But if you use the ||= idiom for values during initialization you can conditionally
set your default values to nil or what have you. Worst case scenario you would have to add a thing or two
to old files, but with a simple version value this could be done pretty easily.
23 Mar, 2010, Runter wrote in the 6th comment:
Votes: 0
JohnnyStarr said:
If you are using Ruby and Yaml then whats the problem?
I mean, if you are removing a bunch of stuff from your objects then sure, I can see that.
But if you use the ||= idiom for values during initialization you can conditionally
set your default values to nil or what have you. Worst case scenario you would have to add a thing or two
to old files, but with a simple version value this could be done pretty easily.


I'm not really convinced that it's safe or flexible post production, but I'll put some thought into it.
23 Mar, 2010, quixadhal wrote in the 7th comment:
Votes: 0
The LpMUD people have tackled this problem. I'd suggest taking a look at the Gurba mudlib for DGD, or perhaps the Phantasmal mudlib (also for DGD). Those are both persistent worlds which have object managers to deal with on-the-fly updates to not only objects, but inheritance trees.

Essentially, you provide an upgraded hook that the object manager can call when an object is loaded, so you can write code to handle migration from the original to a new version. Once upgraded, it sets its version so a future call to upgraded becomes a no-op.
23 Mar, 2010, Runter wrote in the 8th comment:
Votes: 0
JohnnyStarr said:
If you are using Ruby and Yaml then whats the problem?
I mean, if you are removing a bunch of stuff from your objects then sure, I can see that.
But if you use the ||= idiom for values during initialization you can conditionally
set your default values to nil or what have you. Worst case scenario you would have to add a thing or two
to old files, but with a simple version value this could be done pretty easily.


Well, I'll tell you a few problems I'm having with this approach. It's not flexible when it comes to dumping references as alternative data. I.e. you may not want to save it like the object is written in another place. You may just want to save the reference to the lookup. Also, there's a problem when you decide at some point down the road to save classes/merge classes/change your data structures. It specifically maps them to classes based on their constant name. Also, I find the way you must use conditional initialization unintuitive and a poor convention.

So the direction I believe I am going to go is making objects configurable with maps/hashes. This should make the data flexible to any changes in the future from version to version. Two basic methods can be defined for any object that needs to save. We could do Player#configure(map) and Player#make_configuration(map). Then we simply serialize the map of data and write it. Then when we load the map we check the version and do any conversions needed step by step to get it in compliance with the current version. Then we simply pass the map to Player#configure and all should be good. This gets rid of the ugly conditional initialization/forced call to the initializer.
23 Mar, 2010, Runter wrote in the 9th comment:
Votes: 0
For completeness, here's what I settled on straight from my documentation:

Quote
Each class may mix-in CORALMUD::FileIO to define the methods #configure and
#gen_configure. #gen_configure will construct a map based on all instance variables by default. If #to_configure_properties
is overloaded it should return an array of instance variables. #configure will take this map as an argument to initialize
its variables. #configure allows you to overload #version_control and #data_transform_on_load which allows you to hook
into the way it translates the hash into variables. #gen_configure lets you overload #data_transform_on_save to accomplish
the same thing to transform the hash before it is returned.
24 Mar, 2010, JohnnyStarr wrote in the 10th comment:
Votes: 0
The conditional init was something Tyche did in RocketMud which I found helpful. But I don't remember
claiming it as my idea. I'm sure your idea will work just fine. It seems like a lot more work on the surface though.
24 Mar, 2010, David Haley wrote in the 11th comment:
Votes: 0
Conditional initialization like that works well if you're only adding fields, and that these fields have reasonable defaults. If you ever find yourself renaming fields, you can easily lose information unless you have some kind of update hook, as has been mentioned.
0.0/11