views:

471

answers:

6

I don't see an answer to this question here on SO which makes me afraid that it's incredibly simple and I'm just missing something but here goes.

Background, feel free to skip: I need a single course for my bachelor's degree that I skipped out on years ago. Theoretically it's Computer Graphics, but since I left it has become more Game Development. And that's great because to me it's more interesting than the fill algorithms and translations and whatnot that it used to be. It's a 4th year course only offered every other year, but I've managed to talk the department into letting me take a 4th year independent study on the same topic and call that good enough.

The prof "running" the independent study doesn't teach the actual Computer Graphics course so while he's a smart guy this isn't really his field. So most of my questions are left to me, a text book and the internet. You know...like an independent study should be. :)

/Background

I've got a buddy that likes to develop game systems for fun. I plan to take one of his table top games and make it into a computer game using XNA.

I don't foresee any insurmountable challenges with the game mechanics but one thing I'm curious about is how do most games save their content? I mean that in a couple of ways and hopefully I can express them clearly.

Take the case of any RPG you've ever played. You can hit the "Save" button and save the world, your character's information and whatever other information is necessary. Then later on you can hit the "Load" button and bring it back.

Or the case of NPC dialogue. When I bump into Merchant #853 he randomly spits out one of 3 different greetings.

There are others that I can think of but they're really just variations on the same theme. Even with those two examples it seems to me the same mechanic could be used, but what is that mechanic?

I've been doing web development for years so my mind automatically jumps to "databases!". A database is the solution to any problem. And I can see how it could work here but the overhead seems pretty steep. "Here's my 6mb compiled game...oh and 68mb MySQL installation." Or even worse since I'm using XNA, maybe I'd need to find a way to bundle SQL Server. :)

I thought maybe XML but that doesn't feel right to me either. How would it work if I wanted to run on the XBox? Or Zune? (Those aren't necessary for what I'm doing, but there must be a solution somewhere that takes them into account.)

Anyone know the secret? Or have some ideas anyway?

Thanks Jeff

+5  A: 

One approach is to use .net serialization.

Make sure the state of you game is a fully connected graph and that each class in that graph is marked as Serializable (with the SerializableAttribute), the for saving (and loading) you can use normal .net serialization.

You can look at the codebase for Project Xenocide (open source XNA game) to see how it was done there.

Oded
Thanks Oded, I'll dig through that
JeffMc
I suggest you take a look at the save game screen and see what happens what saving as a starting point.
Oded
Serialization is a good starting point, but things get a litte messy because you don't want to serialize assets sush as textures, but which references must be saved and reloaded in a clever way.
Cecil Has a Name
A: 

While the game is running, I'd try to keep everything relating to the current context in memory. Your initialization can be kept in some suitable serialized format and read in on start up. XML would work, but it's somewhat verbose. A custom compact binary format is probably more appropriate. The same is true of the saved state. Whatever objects need to be reinitialized when the saved game is loaded should be serialized to a custom binary format and then reconstituted on load. If you run into memory problems, a small custom database optimized for speed would be another alternative. It could be pre-populated on installation.

tvanfosson
+3  A: 

You could use an SQLite database, with the SQLite.NET wrapper. I've used this, and found it quite simple. The whole DLL is only 850KB, and the database itself sits in a single file (with temp files created as needed). So your users shouldn't have an issue.

But you could also use a simple XML file, or a home-grown binary format. It all depends on how you're going to be querying the data, and how much data is involved. There is no one answer.

Matthew Flaschen
This won't work on the XBox or Zune
Joel Martinez
First, he said XBox and Zune isn't necessary. Second, SQLite (though maybe not SQLite.NET) can be used with XBox (see http://www.mail-archive.com/[email protected]/msg17898.html). I don't know for sure about Zune.
Matthew Flaschen
Many games use SQLite to save their state. It's also my preferred way.
gradbot
+1  A: 

From my limited experience developing games, save games really don't use much storage. As tvanfosson said, you normally store most things in memory while playing the game, so saving state to disk isn't a problem.

Here's a short example. Assuming a single person RPG, if you needed to save your character's location only, you'd have perhaps a level number, xyz coordinates and maybe the direction you're facing. That's just a few bytes.

Now assume you need to save the state/location of things like health packs, crates, enemies, character's health and picked up items, etc. You could have a few hundred of these at most which would easily be less than 10KB.

Obviously things can get very complicated with more complex games. The trick is to only store what is truly necessary to recreate the player's experience. A lot of games only let you save at certain places, like the end of a level. In this case you only need to store the new level number plus the outcome of previous levels (e.g. health remaining, picked up items).

Even if you allow arbitrary save points you can ignore the state of any places/levels that you cannot return to. And you probably wouldn't want the user to be able to save mid-jump.

EDIT: With regard to file format... use any way that's convenient for the data type! XML is quite a nice way of doing things. Not sure how effective a database would be since for an RPG each fragment of data can be very different; You might end up with a bunch of tables with one row each.

Most games use their own, binary, file formats. Firstly this reduces the storage amount dramatically. Secondly, it helps prevent users cheating by editing the save game manually - if you have XML like <health value="10"/> it's very easy to edit the file to read <health value="100"/>. The downside of binary is that it's much more difficult for debugging.

DisgruntledGoat
I think Fallout 3 saves are like 3mb... which is the largest I've ever seen. But they store *everything*. Every person you ever kill, and every item you ever drop will sit there forever. In other games, bodies disappear within 10 seconds... craziness! But way off topic :D
Mark
You really cannot generalize save game size being small. As @Mark mentions, games like Fallout 3 (and Oblivion, running on the same engine) really saves a lot of stuff. It then becomes crucial that the engine uses an efficient storage mechanism.
Peter Lillevold
But if 3MB is "a lot" for a game, that's pretty good because 3MB isn't really much space at all, either in memory or on disk. Web browser caches are at least 10 times this size. Like I said, if you implement rules such as not being able to go back to previous levels, you cut down your storage to next-to-nothing.
DisgruntledGoat
Really depends on what those 3 megs are. Whether it is "a highres screenshot of your last position" or "a list of close to 200.000 objects with state", storage format matters a lot. With such amounts of things to handle a database engine starts to be pretty feasible. We're seeing a lot of content in RPGs these days, why not utilize proven database platforms that can handle large amounts of data blazingly fast? ...Oblivion could surely benefit from that :)
Peter Lillevold
Actually I just realised that a database is really not the way forward for a game. Sure, they can retrieve segments of data blazingly fast, but with games this is not what you want - you're loading the entire data set into memory. A database could work if you have tens of megabytes of data that is not required to be accessible 100% of the time, otherwise the cost of loading it will be too much.
DisgruntledGoat
Perhaps if you view the save data in isolation. But what of the rest of the games data? That data definitively matches "tens of megabytes of data that is not required to be accessible 100% of the time".If you view the game world data in combination with save data, which is the target view after loading a savegame, as a database...you could cut down those pesky loading times. The state is already in place.
Peter Lillevold
+1  A: 

As others have noted, serialization is the way to go. And Gamasutra just published an article on data baking.

Nikhil Chelliah
Thanks, I'll look through that article.
JeffMc
I definitely don't think automatic serialization is the only way to go. That constrains tightly into the .NET framework (what if you want to port it to something else later?), and gives you less control over your format. It also tends to include some redundant data.
Matthew Flaschen
@Matthew: If you're talking about a data format that's interchangeable between platforms, then that's more difficult. But if that's an issue, then using .NET itself might not be the best idea.
Nikhil Chelliah
@Matthew: The alternative (short of writing your own serialization algorithm) would be plaintext or a file-based database, as you suggested, which can become complicated since you need to convert to and from that format yourself – more control but more hassle. And serialized data doesn't need to waste as much space as you'd think – enums, etc. require fewer bits than, say, several ASCII characters.
Nikhil Chelliah
I am not saying, "Never use automatic serialization". In fact, I just used it on a project. I just want the OP to be aware of the pros and cons. Note that the redundancy of serialization is not related to binary/text (at least for binary serialization). Rather, I was mostly referring to accidentally serializing caches, temporary data and the like, which is common.
Matthew Flaschen
+5  A: 

There are two main ways how games are saved, a simple one and a complex one. The first way is to simply stores the current level, the current score and a handful of other stats. This is seen in games such as Super Mario Galaxy and most earlier console module based games. The save game doesn't restore your exact position, but just which levels you have completed. These save games are generally very simple and require very little memory.

The second way not only stores your overall progress, but stores each and every little detail, such as enemy positions, their current animation frame and so on, so that loading a save game will place you at the exact spot where you stopped, with all the enemies right in place, instead of back at the start of a level. These savegames tend to get much bigger then the other version and thus are mostly seen on PC games.

Databases are used in neither of these schemes, as the purpose of databases is to provide the ability to dynamically query data structures, what the game however needs isn't a way to query individual pieces, but just a way to statically store them. When a savegame is loaded, it is loaded completly into memory and from there on the game engine does its thing with the data. There are a handful of exceptions, such as MMORPGs which might work on a database, but single player games generally don't.

How the data is actually stored depends on the game. Most common seem to be simple binary data formats, as they are much better in terms of disk space then XML. In older games those binary formats where often raw dumps of a pieces of memory of the games process, so they didn't have any well thought out structure and often broke when a patch or a different version of a game got released, in some modern games that's still the case. XML can be used as too, as well as any other text based file format.

In large part this is more a game design issue then a programming one, as they way a game can be saved can drastically change how its played. The simple way, where you just save the level number and some stats, is however a lot easier to implement, as its just a few lines of of code. While the second one requires serialization of most of your classes, which for a complex game can be quite a tricky issue and lead to many subtle bugs.

Grumbel