22
\$\begingroup\$

My question is whether or not I should use text files to save my game data. I have some basic concerns over doing this:

  1. There's really no way to protect the data, and thus, the user could screw up everything if they touched it and I don't want that to happen.

  2. It's probably not the most efficient way to store my data (There will be a lot of it)

I know how to parse/write to text files effectively, though, so for prototyping they have been fantastic. I just want to look to the future for what I should be thinking about switching to so it doesn't punch me in the face near the end of development.

If I shouldn't use text files, what should I use? I need something C++ compatible.

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Zip files (with password) - there are many libraries available that will allow you to do this, and it should save on disk space \$\endgroup\$
    – SeanC
    Commented Jul 22, 2013 at 16:17
  • 2
    \$\begingroup\$ Applying a simple cipher like en.wikipedia.org/wiki/ROT13 should be enough to keep the average user from editing the files. Everyone else probably knows what they're doing anyway. \$\endgroup\$
    – Exilyth
    Commented Jul 22, 2013 at 18:36
  • 1
    \$\begingroup\$ Have it your own way, but I like my games to be easily modifiable. \$\endgroup\$
    – mmyers
    Commented Jul 24, 2013 at 4:36

3 Answers 3

28
\$\begingroup\$

For now, since you're just beginning, text files are probably OK. There's a couple of concerns in your question that I'll address.

  1. Protecting the data isn't as crucial as you probably think. If your game is multiplayer, you'll have the data saved server-side anyways. If your game is single player, so what if players modify the data? If they break something it's really their fault and they can re-install.

  2. Performance is also something else that we often fail to plan properly. You shouldn't really optimize until you actually measure a performance issue. My guess is that you'll probably have an amount of data that isn't that big and that text files are going to be just fine.

That being said, your best bet is to abstract your data saving and loading routines as best you can. For example, you can have a base class, say DataWriter, and then provide different implementations of its different methods. A very basic example would look like:

class DataWriter {
  virtual void save(GameState state) = 0;

  virtual ~DataWriter() { }
};

class TextFileDataWriter : public DataWriter {
  virtual void save(GameState state) {
    //write to text file
  }
};

class DatabaseDataWriter : public DataWriter {
  virtual void save(GameState state) {
    //write to database
  }
};

When you eventually profile your game and realize the performance bottleneck is in the file writing routine, you can provide another implementation of that class (for example to write to a database instead) with minimal changes to calling code.

\$\endgroup\$
8
  • \$\begingroup\$ It's a single player game, and those were my thoughts exactly if they wanted to mess with the data. I don't know, something about text files just seemed unprofessional, and I figured if I could keep the user from screwing up, I probably should. Also, What do you mean when you say "Database"? I hear that thrown around a lot but I have no idea as to the exact definition or what kind of file that entails. \$\endgroup\$
    – Althezel
    Commented Jul 22, 2013 at 13:18
  • 6
    \$\begingroup\$ @Althezel The thing is, regardless of how you save your data, someone determined enough to modify it will be able to. In that sense, it's usually a waste of your precious development time to try and put protections in place :) \$\endgroup\$
    – anthonyvd
    Commented Jul 22, 2013 at 13:19
  • \$\begingroup\$ @Althezel As for the databases, think of it as a sort of engine to which you pass requests to read or write data. That engine is responsible for saving/reading it in an efficient manner, usually in relational form in tables. In your use case, I'd take a look at SQLite (sqlite.org). Basically you'd use a C++ library to connect to a local SQLite database (SQLite uses local files) and pass that library calls in SQL syntax to access your data. \$\endgroup\$
    – anthonyvd
    Commented Jul 22, 2013 at 13:21
  • 2
    \$\begingroup\$ It is a sad world when developers want to be able to lock users out of information they store on thier computers. \$\endgroup\$ Commented Jul 22, 2013 at 19:54
  • 2
    \$\begingroup\$ It really only feels unprofessional to use text files because very few games store things as "save-data.txt" - but if you've ever spent time looking into most saved game files you'll find they are often nothing more than text files that sometimes have binary data added to them. Every Civilization and Total War series game, for instance, uses actual .txt files for a wide variety of game data. The most common 'upgrade' for this is a database system that ends up storing the data as a flat-file that - except for some binary blobs - is just a text file. \$\endgroup\$
    – BrianH
    Commented Jul 23, 2013 at 1:30
3
\$\begingroup\$

The word Game Data can mean many things, for example

  • Gamestate
  • Configuration files
  • Maps, textures, sounds, scripts, animation data, ...
  • Localisation
  • GUI layout data
  • more i didn't think of

For each category you can take another approach.

For example you could use SQLite for Localisation stuff, binary for Maps, textures, sounds and so on.

For configuration stuff you should use easy to change xml files.

As always, the correct answer is "it depends".

There exists many xml parsers with a c++ binding and a c++ binding for SQLite exists too.

\$\endgroup\$
1
  • \$\begingroup\$ It might be a religious thing but I would rather use INI file format for configs instead of XML. The latter feels like an overkill for this scenario. And there is an INI reader in boost libraries. \$\endgroup\$ Commented Aug 24, 2013 at 18:54
0
\$\begingroup\$

You could save out your data as a binary blob and stream the data back in when you come to accessing that file. This would solve both your issues. Just make sure that the serialisation code is exactly the same as the de-serialisation.

Streaming in the binary blob is relatively fast and also prevents the user from seeing the data and changing it.

You can achieve all this by using the standard library streams.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ While binary blob is fast and easy (both to dev and to load/run) the biggest problem I've had with binary blob is as soon as you change anything about the data structure organization (so much as add a single float member to a single object), the old savegames become completely invalid. This is difficult to deal with during development, but if you're up to it, then by all means. \$\endgroup\$
    – bobobobo
    Commented Jul 26, 2013 at 16:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .