Pixel Perfect Posted September 19, 2012 Share Posted September 19, 2012 Just wondering what mechanisms others are using to implement game saves and loads. C++ doesn't inherently support serialisation so I've been looking at some of the options out there from the Boost Libs to jsonCpp and Google Protocol buffers. Straight serialisation seems like a nice option but there are some immediate considerations to take into account such as: How do you cope with changes to design of class objects and patched games with respect to backwards compatibility of save files. Is any given solution able to span multiple platforms (not required by me personally at the moment but always worth consideration from the outset). Any other issues I may not be currently aware of. Any heads up/advice would be gratefully received at this point. Quote Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++ Link to comment Share on other sites More sharing options...
tjheldna Posted September 19, 2012 Share Posted September 19, 2012 Hi Pixel, I have recently done saving and loading. I didn't need to save object states in the level, more the players things like health inventory etc. The solution I came up with works very well using ostream and istream which is just in the std library so I believe it will be compatible. Here is basicly what I did First Created a template to overload the extraction operators template<class derivedTp> class Packable { public: void Write(std::ostream& os) const { static_cast<const derivedTp *>(this)->Write(os); } void Read(std::istream& os) { static_cast<derivedTp *>(this)->Read(os); } }; template<class derivedTp> std::ostream& operator<< (std::ostream& os, const Packable<derivedTp>& s) { s.Write(os); return os; } template<class derivedTp> std::istream& operator>> (std::istream& is, Packable<derivedTp>& s) { s.Read(is); return is; } If you want the object to save load just add the <Packable> template to the class in the .h and override the read/write classes class Player : public Packable<Player> The way I cope with changes are as follows each written object has a header and a terminator line at the end then breaks. If it finds the value good, if not it just goes onto the next header void GamePlayer::Write(std::ostream& os) const { short i = (short)(index); os << 'play' << std::endl << 'plid' << std::endl << i << std::endl << 'pcht' << std::endl << playerCharacterType << std::endl << 'term' << std::endl; } So I just loop through the lines and search for the header if the header matches any one of the cases it assignes the value else it just keeps on looping until terminated. void GamePlayer::Read(std::istream& is) { std::string line; long type = 0; while(type != 'term') { is >> type; switch(type) { case 'plid': { is >> index; break; } case 'pcht': { is >> playerState.playerCharacterType; break; } } } } Does this help? 2 Quote Link to comment Share on other sites More sharing options...
Pixel Perfect Posted September 19, 2012 Author Share Posted September 19, 2012 Many thanks tjheldna, yes that definitely helps. I had considered just saving the data rather than the actual objects which can always be reconstructed and re-populated with the data. That's a fine example of doing just that, and nicely implemented. I like the header (key) type method of ensuring backwards compatability. Use it or ignore it and presumably cope with anything not supplied if loading old save files. Avoids dependancy on external libs too which is an advantage and less likely to cause cross platform porting issues in the future. Quote Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++ Link to comment Share on other sites More sharing options...
Roland Posted September 19, 2012 Share Posted September 19, 2012 Yes. That is a good and solid way to solve it. In my own code I use SQLite3 which in essential is just one c-file with cross platform code, but I have used the approach show here in many projects at work without any problems. So go for it Quote Roland Strålberg Website: https://rstralberg.com Link to comment Share on other sites More sharing options...
Pixel Perfect Posted September 19, 2012 Author Share Posted September 19, 2012 Thanks for the feedback Roland. I'm seriously thinking about using SQLite for storing my configuration data, I'm not so sure about save game data though. The only issue I might face with the 'save the data' as opposed to 'save the objects' is the amount of data some of my objects store and would need to save and load, well more specifically how much work it would be to code the save and load routines for individual member data items. Going the serialisation route would have me believe I could avoid a lot of this but then I don't currently know how much work is involved in setting that up! Anyway, it's all good food for thought. I kind of like implementing my own solutions rather than rely on external third party solutions because then you are totally in control of it should you need to change aspects of it. We shall see. Quote Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++ Link to comment Share on other sites More sharing options...
tjheldna Posted September 19, 2012 Share Posted September 19, 2012 Glad you like it! I had considered just saving the data rather than the actual objects which can always be reconstructed and re-populated with the data. That's the way I see it and it's worked for what I need. I can provide you with more code. I'm happy to share it, the basics are all there I'd just have to isolate what you need. I think sqlite is a great way to store data too. I think you can also encrypt the data in the database too. I'll update my previous post with a more complete solution when I have a chance. I thought about using boost, but for no real reason that I chose not to. I also decided against using xml format because although I'm not worried about security I'd like it to be as unreadable as possible (also using the binary flag). I will look at doing some kind of encryption later, but I'd be learning that from scratch so it's going to have to wait. I think there is a relatively easy way to encrypt using the binary shift. Quote Link to comment Share on other sites More sharing options...
Pixel Perfect Posted September 19, 2012 Author Share Posted September 19, 2012 I can provide you with more code. I'm happy to share it, the basics are all there I'd just have to isolate what you need. No, that's fine. The current code and description you've provided illustrates the process well. I did my own binary file export and import routines for my path finding data, which literally just saves and loads predominantly structs along with a few headers and counts, and that's worked well for me. So I'll probably go with this type of solution. Like you, I prefer binary file output. Thanks again for your help tjheldna, it's appreciated Quote Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++ Link to comment Share on other sites More sharing options...
xtreampb Posted September 27, 2012 Share Posted September 27, 2012 for basic encryption i use xor encryption. not the safest but i don't see a real need to do AES-256 bit encryption on my save files. I can post the encryption function if you like. it just uses iostream.h Quote bool Life() { while(death=false) { if(death==true) return death; } } I have found the secret to infinite life Did I help you out? Like my post! Link to comment Share on other sites More sharing options...
tjheldna Posted September 27, 2012 Share Posted September 27, 2012 I haven't had a look into this just as yet so yes I would be very keen to take a look and save some time! Quote Link to comment Share on other sites More sharing options...
gamecreator Posted September 27, 2012 Share Posted September 27, 2012 I use a heuristic canonical method involving elementary degradation coresistance with perpetual injected data persistence. That way the ball coordinates and the paddle y values are saved properly. 1 Quote Link to comment Share on other sites More sharing options...
Roland Posted September 27, 2012 Share Posted September 27, 2012 I use a heuristic canonical method involving elementary degredation coresistance with perpetual injected data persistance. That way the ball coordinates and the paddle y values are saved properly. Hahaha... yeah I was thinking about that to, but with the addition of singular abstraction layers of induced proxy values Quote Roland Strålberg Website: https://rstralberg.com Link to comment Share on other sites More sharing options...
gamecreator Posted September 28, 2012 Share Posted September 28, 2012 Well now you're just showing off. I'm not sure that's entirely necessary. 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.