After many trails and tribulations Paul has finally gotten Save and Load working for his Windows Phone 7 Game - Alien Military Strike (AMS).  He has also been so kind as to write up some more great tips and tricks on how to get this working for your first Windows Phone 7 Game!

 

Save/Load on Windows Phone 7 Series – Tips and tricks used in writing Save/Load for AMS.

1.       Extend binary reader/write to include XNA constructs (Vector, Color, etc…)

   public static class BinaryWriterExtension

    {

        public static void Write(this BinaryWriter writer, Matrix value)

        {

            writer.Write(value.M11);

            writer.Write(value.M12);

            writer.Write(value.M13);

            writer.Write(value.M14);

            writer.Write(value.M21);

            writer.Write(value.M22);

            writer.Write(value.M23);

            writer.Write(value.M24);

            writer.Write(value.M31);

            writer.Write(value.M32);

            writer.Write(value.M33);

            writer.Write(value.M34);

            writer.Write(value.M41);

            writer.Write(value.M42);

            writer.Write(value.M43);

            writer.Write(value.M44);

        }

        public static void Write( this BinaryWriter writer, Quaternion value )

        {

            writer.Write(value.X);

            writer.Write(value.Y);

            writer.Write(value.Z);

            writer.Write(value.W);

        }

        public static void Write( this BinaryWriter writer, Vector2 value )

        {

            writer.Write(value.X);

            writer.Write(value.Y);

        }

        public static void Write( this BinaryWriter writer, Vector3 value )

        {

            writer.Write(value.X);

            writer.Write(value.Y);

            writer.Write(value.Z);

        }

        public static void Write( this BinaryWriter writer, Vector4 value )

        {

            writer.Write(value.X);

            writer.Write(value.Y);

            writer.Write(value.Z);

            writer.Write(value.W);

        }

 

        public static void Write( this BinaryWriter writer, Color value )

        {

            writer.Write( value.R );

            writer.Write( value.B );

            writer.Write( value.G );

            writer.Write( value.A );

        }

 

        public static void Write( this BinaryWriter writer, ref Rectangle value )

        {

            writer.Write( value.X );

            writer.Write( value.Y );

            writer.Write( value.Height );

            writer.Write( value.Width );

        }

 

        public static void Write( this BinaryWriter writer, ref Point value )

        {

            writer.Write( value.X );

            writer.Write( value.Y );

        }

    }

    public static class BinaryReaderExtension

    {

 

        public static Matrix ReadMatrix(this BinaryReader reader)

        {

            Matrix matrix = new Matrix();

            matrix.M11 = reader.ReadSingle();

            matrix.M12 = reader.ReadSingle();

            matrix.M13 = reader.ReadSingle();

            matrix.M14 = reader.ReadSingle();

            matrix.M21 = reader.ReadSingle();

            matrix.M22 = reader.ReadSingle();

            matrix.M23 = reader.ReadSingle();

            matrix.M24 = reader.ReadSingle();

            matrix.M31 = reader.ReadSingle();

            matrix.M32 = reader.ReadSingle();

            matrix.M33 = reader.ReadSingle();

            matrix.M34 = reader.ReadSingle();

            matrix.M41 = reader.ReadSingle();

            matrix.M42 = reader.ReadSingle();

            matrix.M43 = reader.ReadSingle();

            matrix.M44 = reader.ReadSingle();

            return matrix;

        }

        public static Quaternion ReadQuaternion( this BinaryReader reader )

        {

            Quaternion quaternion = new Quaternion();

            quaternion.X = reader.ReadSingle();

            quaternion.Y = reader.ReadSingle();

            quaternion.Z = reader.ReadSingle();

            quaternion.W = reader.ReadSingle();

            return quaternion;

        }

        public static Vector2 ReadVector2( this BinaryReader reader )

        {

            Vector2 vector = new Vector2();

            vector.X = reader.ReadSingle();

            vector.Y = reader.ReadSingle();

            return vector;

        }

        public static Vector3 ReadVector3( this BinaryReader reader )

        {

            Vector3 vector = new Vector3();

            vector.X = reader.ReadSingle();

            vector.Y = reader.ReadSingle();

            vector.Z = reader.ReadSingle();

            return vector;

        }

        public static Vector4 ReadVector4( this BinaryReader reader )

        {

            Vector4 vector = new Vector4();

            vector.X = reader.ReadSingle();

            vector.Y = reader.ReadSingle();

            vector.Z = reader.ReadSingle();

            vector.W = reader.ReadSingle();

            return vector;

        }

        public static Color ReadColor( this BinaryReader reader )

        {

            Color color = new Color();

            color.R = reader.ReadByte();

            color.B = reader.ReadByte();

            color.G = reader.ReadByte();

            color.A = reader.ReadByte();

            return color;

        }

        public static Rectangle ReadRectangle( this BinaryReader reader )

        {

            Rectangle rect = new Rectangle();

            rect.X = reader.ReadInt32();

            rect.Y = reader.ReadInt32();

            rect.Height = reader.ReadInt32();

            rect.Width = reader.ReadInt32();

            return rect;

        }

        public static Point ReadPoint( this BinaryReader reader )

        {

            Point point = new Point();

            point.X = reader.ReadInt32();

            point.Y = reader.ReadInt32();

            return point;

        }

    }

 

 

2.       Use an object system with retrieve by ID. Keep a list of all objects each having its own Unique ID. Rather than having a class reference to an object use a class like this FakePointer. It will allow you to save/load objects without dependencies on each other. It will decrease performance in accessing these objects

    public class FakePointer<T> where T : BaseObject

    {

        protected float ID;

 

        public FakePointer(T ob)

        {

            ID = ob.ID;

        }

 

        public FakePointer(float id)

        {

            ID = id;

        }

 

        public T Value

        {

            get

            {

                if (ID == -1)

                {

                    Engine.DebugHelper.Break(DebugHelper.DebugLevels.Curious);

                    return null;

                }

                return (T)Engine.GameState.GameStateSystem.Instance.GetCurrentState[ID];

            }

        }

 

        public void Clear()

        {

            ID = -1;

        }

    }

3.       Be careful with your delegates. Delegates do not save/load cleanly and will all need to be setup again when you restore your game.