Jump to content

Game saving and loading


Pixel Perfect
 Share

Recommended Posts

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.

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

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?

  • Upvote 2
trindieprod.png?dl=0spacer.png?dl=0steam-icon.png?dl=0twitter-icon.png?dl=0spacer.png?dl=0
Link to comment
Share on other sites

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.

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

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.

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

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.

trindieprod.png?dl=0spacer.png?dl=0steam-icon.png?dl=0twitter-icon.png?dl=0spacer.png?dl=0
Link to comment
Share on other sites

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

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

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

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

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 :)

AV MX Linux

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...