27
\$\begingroup\$

What is the procedure followed by game programmers for saving and resuming game state? like files/mappings. I want to save it for tower defense game and I am using unity3D game engine.

\$\endgroup\$

4 Answers 4

16
\$\begingroup\$

I generally don't think in terms of a memory snapshot, but rather I just make a list of which values need to be saved between sessions and save those values into an external file.

This depends of course on the needs of your specific game, but usually I simply save the state of the current level (ie. where all the enemies are, what their health is, etc.) and then higher level stuff like what levels the player has already completed.

\$\endgroup\$
3
  • 3
    \$\begingroup\$ +1 That's how I do it. I write what I need to a binary file. And, if I need to add something new, I add it to the end so I don't break old save files. \$\endgroup\$ Dec 26, 2011 at 18:00
  • \$\begingroup\$ That's a good tip about not breaking old save files, although adding data to the end is irrelevant to how I save data. I do it by serializing/deserializing a Dictionary, and order is irrelevant in that data structure. \$\endgroup\$
    – jhocking
    Dec 27, 2014 at 14:18
  • \$\begingroup\$ (basically, the code in jonas' answer, with my Object being a Dictionary) \$\endgroup\$
    – jhocking
    Dec 27, 2014 at 14:59
10
\$\begingroup\$

This answer is Unity3d specific.
In Unity, most classes are serializable, this means you are able to stream complete Unity objects to disk. The follwing C# code is a way to serialize an object, save it to disk an load it again (after loading you must cast the object):

import System;
import System.IO;
import System.IO.Stream;
import System.Runtime.Serialization;
import System.Runtime.Serialization.Formatters.Binary;

class SaveLoad {
        public static function SaveFile(filename:String, obj:Object):void {
                try {
                        Debug.Log("Writing Stream to Disk.", SaveLoad);
                        var fileStream:Stream = File.Open(filename, FileMode.Create);
                        var formatter:BinaryFormatter = new BinaryFormatter();
                        formatter.Serialize(fileStream, obj);
                        fileStream.Close();
                } catch(e:Exception) {
                        Debug.LogWarning("Save.SaveFile(): Failed to serialize object to a file " + filename + " (Reason: " + e.ToString() + ")");
                }
        }

        public static function LoadFile(filename:String):Object {
                try {
                        Debug.Log("Reading Stream from Disk.", SaveLoad);
                        var fileStream:Stream = File.Open(filename, FileMode.Open, FileAccess.Read);
                        var formatter:BinaryFormatter = new BinaryFormatter();
                        var obj:Object= formatter.Deserialize(fileStream);
                        fileStream.Close();
                        return obj;
                } catch(e:Exception) {
                        Debug.LogWarning("SaveLoad.LoadFile(): Failed to deserialize a file " + filename + " (Reason: " + e.ToString() + ")");
                        return null;
                }       
        }
}
\$\endgroup\$
8
  • 2
    \$\begingroup\$ Besides using C#, you'd also want to use PlayerPrefs. They are cross platform, you cant do IO on Web/iOS/Android. unity3d.com/support/documentation/ScriptReference/… (Nice sample though!) \$\endgroup\$
    – TJHeuvel
    Apr 17, 2012 at 8:45
  • \$\begingroup\$ PlayerPrefs are way less flexible, they are cross platform indeed and they are perfect to store single or unrelated values. But on Windows PlayerPrefs are stored in the registry, plaintext. \$\endgroup\$
    – jonas
    Apr 18, 2012 at 10:10
  • 7
    \$\begingroup\$ If you're already serializing, why not serialize it to a String and store it in PlayerPrefs. Sure it is less flexible, but its pretty much the only solution for a crossplatform game. \$\endgroup\$
    – TJHeuvel
    Apr 18, 2012 at 11:17
  • 2
    \$\begingroup\$ PlayerPrefs is great for storing small data like settings, but for entire savegames you should use Application.persistentDataPath docs.unity3d.com/ScriptReference/… \$\endgroup\$
    – jhocking
    Dec 27, 2014 at 14:20
  • 2
    \$\begingroup\$ @TJHeuvel : "you cant do IO on Web/iOS/Android" You most definitely can do IO on mobile \$\endgroup\$ Nov 10, 2015 at 16:13
2
\$\begingroup\$

For a TD I'd probably save exclusively between waves. That way all you have to think about is the towers. Put some automatic save points in the levels, no more than 10 minutes between, but less is probably preferable.

Of course if your levels are short enough you could simply save nothing but the campaign status.

\$\endgroup\$
1
\$\begingroup\$

When I refer to the current state of the game I am referring the memory snapshot at the moment of saving. You need to be able to recreate that from the data you are going to store on you HDD.

It is easiest just serialize all of you classes that have data that needs to be persistent and dump it to the HDD, essentially performing a memory dump. Problem with this is that altering you classes will change the number/types of serialized values and break old saves. Also because you are saving everything it increases loading times. Its more efficient to mark individual fields that are actually needed to rebuild the current "memory snapshot" with whatever attribute system your serializer/IDE uses. Then rebuild the "memory snapshot" from that saved data.

Also I have never used Unity before so it may have something built in. However, this is the typical approach.

\$\endgroup\$
2
  • \$\begingroup\$ u mean I have to store my states in a file ? \$\endgroup\$
    – Syed
    Dec 26, 2011 at 8:50
  • 1
    \$\begingroup\$ @Syed yes, at the end of the day it has to be written to a file of some kind since the app state isn't going to be saved in memory. With Unity specifically you can use the PlayerPrefs class (which I think actually stores things in the registry on Windows) if you want to avoid the whole file reading/writing stuff. \$\endgroup\$
    – Tetrad
    Dec 26, 2011 at 9:18

You must log in to answer this question.

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