Alberth wrote:
I mainly posted to update the thread in case someone was looking for the same problem.
However, I noticed too that my original question was different from my current answer while re-reading the topic. My ponderings seem to have shifted in time.
I think I made progress though. While writing the first post, I had no idea of how to solve the problem in a somewhat nice way in actual code.
My post above at least gives a solution (I think). I agree however with you that it is a solution with a lot of duplicated code.
I see however also problems with the solution you posted where you have several versions of an API available during playing. Suppose I have 5 icecream shop versions, and I change the API of the guest.
Then in your solution you need to change 5 shop objects. In my solution, change the API of the current shop, and that's it. That is, I have 4 less classes to change. Note that this holds for every type of object that the guest interacts with.
Testing also may become an interesting exercise, trying all versions of eg a shop sounds already very complicated. Trying all combinations of all versions of all objects is..... well, no idea, but it does not look right to me. Reproducing a bug may also be a problem, as the reporter may have used an old save-game (and thus have old shop objects), which you don't use when making the same setup from srcatch.
So, while it may solve the duplicated loading code, I fear it will explode in other areas.
I currently don't see an easy solution to the duplicated code problem. The solution by FelipeFS goes in that direction, but I am not convinced all edge cases work properly, and I don't want to risk problems. Mistakes that you make here will haunt you forever due to old versions that keep lingering around. With the version number, I can reproduce the field-names if necessary, so I should have sufficient information in the save game to reproduce things, should the need arise.
The current conclusion seems to be that I will re-visit this topic again somewhen in the future, when I have a bit of experience with the subject, and some actual versions with messy code that needs a clean-up.
Albert
Hi Albert,
Below is a quick summary of what i thought you were after;
Summary wrote:
During the development cycle, You would like to be able to save game states. In order to save game states, you need to record the internal details of objects.
The problem then arises that these internal details may change when implementation details change within your code. You wish to be able to support backward compatibility to these game states.
There are two reasons why a Class would change;
1) The implementation details of the class change
When you change the implementation details of a class, you break compatibility with your game states. So you need to keep a revision of the Old Class implementation. - You dont want to maintain these classes, They will not exist in your final project, They are for history purposes only. It is in fact unlikely that you can maintain them as you may change implementation details, destroying backward compatibility.
You could even wrap them up in a preprossor like;
Code:
#define COMPAT_MODE
#ifdef COMPAT_MODE
// Store old versions of classes here
#endif
2) The Interface (/Public Methods/API/"messages) change
If the interface changes, it is impossible to remain backward compatible without altering all versions of the class. You must extend your old classes, Id recommend inheritance to keep duplicate information to a minimum.
If you want to be able to support game state backward compatibility (Which i think is a good idea), your going to need to manage it in a way that is not too taxing on you. I feel not keeping this historic information in one central place (classes), you may find yourself spending large amounts of time on managing this feature (Debugging, large code edits).
In the bigger picture, you may need to "update/convert" game state files. Having the two versions side by side may aid with the design of that tool. Once a version is no longer needed, you want to be able to clean up your code fairly easily.
A revisit seems like a good idea, Maybe once you've got a complete list of classes and their interfaces, and a reconsider if you require this feature just yet.
Cxzuk