Savegames and saving files.

Post your questions, suggestions and experiences regarding game design, integration of external libraries here. For irrEdit, irrXML and irrKlang, see the
ambiera forums
Post Reply
Morgawr
Posts: 95
Joined: Wed Sep 26, 2007 7:04 pm

Savegames and saving files.

Post by Morgawr »

Hello everyone, my questions would be two today, they are both about saving/loading files but with different purposes:

First question:

What's the concept behind a savegame? I mean, how does saving games work? Do I save into a file all the variables of the application and then when loading it I put them "back" in their place? I'm really confused about this so if someone could explain/link me to a tutorial, I'd be really grateful.


Second question:

I'm developing an application that allows me to draw 2D maps (like RPGMaker) for my future RPG 2D game, the map is just a simple 16x16 matrix of int with every int referring an ID of a texture.. My problem is saving that map, what filetype should I use? Can someone explain me or link me to a tutorial for saving/loading files with IReadFile and IWriteFile? I'm a bit confused about that part, thanks :roll:
bull
Posts: 36
Joined: Wed Sep 12, 2007 8:49 am
Location: s1Ng4p0R3

Post by bull »

What's the concept behind a savegame? I mean, how does saving games work? Do I save into a file all the variables of the application and then when loading it I put them "back" in their place? I'm really confused about this so if someone could explain/link me to a tutorial, I'd be really grateful.
It depends on the game itself. For a chess game, just saving pieces' positions or moves is enough. For a rpg, you need to save items, levels ,skills ... For FPS: weapons, character position, level, trigger states... it's a very general topic.
I'm developing an application that allows me to draw 2D maps (like RPGMaker) for my future RPG 2D game, the map is just a simple 16x16 matrix of int with every int referring an ID of a texture.. My problem is saving that map, what filetype should I use? Can someone explain me or link me to a tutorial for saving/loading files with IReadFile and IWriteFile? I'm a bit confused about that part, thanks
A binary file with 16x16 ints should be enough.
My name is bull, for we are many ...
Morgawr
Posts: 95
Joined: Wed Sep 26, 2007 7:04 pm

Post by Morgawr »

bull wrote:
What's the concept behind a savegame? I mean, how does saving games work? Do I save into a file all the variables of the application and then when loading it I put them "back" in their place? I'm really confused about this so if someone could explain/link me to a tutorial, I'd be really grateful.
It depends on the game itself. For a chess game, just saving pieces' positions or moves is enough. For a rpg, you need to save items, levels ,skills ... For FPS: weapons, character position, level, trigger states... it's a very general topic.
I'm developing an application that allows me to draw 2D maps (like RPGMaker) for my future RPG 2D game, the map is just a simple 16x16 matrix of int with every int referring an ID of a texture.. My problem is saving that map, what filetype should I use? Can someone explain me or link me to a tutorial for saving/loading files with IReadFile and IWriteFile? I'm a bit confused about that part, thanks
A binary file with 16x16 ints should be enough.
mm since I'm thinking about making an RPG, I guess it'll be kinda complex... I will have to put a variable for each event in the game and set it to true when it's been triggered already or not... then save all those variables + items + character position + levels + everything else in a file.. right? Hope it works, it looks complex..

and regarding the other question, I'm a newbie with the saving/loading files subject, how can I make a binary file with 16x16 ints using IReadFile and IWriteFile? Is there a tutorial about it or a chapter explaining? I don't like looking like a newbie but I'm really having a hard time understanding this since there is no guide around (at least I haven't found any) :wink:

by the way, thanks :P
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Morgawr wrote:mm since I'm thinking about making an RPG, I guess it'll be kinda complex...
Yes. Yes it will.
Morgawr wrote:I will have to put a variable for each event in the game and set it to true when it's been triggered already or not... then save all those variables + items + character position + levels + everything else in a file.. right? Hope it works, it looks complex..
Yes. Yes it is.

First off, your serialisation scheme will change a lot during development. I'd strongly recommend that you start your serialisation (of the whole file, and of each significant object in it) with a version number. That will give you the opportunity of loading older save files, if they contain a subset of your current data and if you can fill in the blanks with defaults; at a minimum, you should fail gracefully with a descriptive error. Remember to take into account older software being given a newer save file. It's better to do it and then never need it than to try to kludge it in later once you've released versions of both software and save files into the wild.

I'd recommend making objects responsible for serialising themselves. This breaks the task up into more manageable subtasks, and keeps the responsibility for each part of it better compartmentalised. Note that when you do the load, that each object will be responsible for creating new instances of its children, and then telling them to set themselves up (passing them whatever stream/file you're using).

Notionally, each object should do this during saving:
  • Its own data (e.g. global data for the world, starting with a version number)
    The number of children of each type (e.g. 3 dungeons)
    Telling each of its children (e.g. each of 3 dungeons) to serialise itself out.
When loading, each object:
  • Loads its own data (e.g. global data for the world, starting with a version number and either handing older versions gracefully or raising an error if it can't handle them or if a newer or unknown version number is encountered)
    The number of children of each type (e.g. 3 dungeons)
    Create that number of instances of the appropriate object type.
    Tells each of these new instances (e.g. each of 3 dungeons) to serialise itself in.

Also, I'd recommend put in error checking and descriptive logging right from the start. If you produce a human readable log of everything that's being saved and loaded then it'll save you time in the long run when you introduce a subtle discrepancy between what you're saving and what you're loading.

Morgawr wrote:and regarding the other question, I'm a newbie with the saving/loading files subject, how can I make a binary file with 16x16 ints using IReadFile and IWriteFile?
God knows. I'd urge you not to become reliant on Irrlicht for anything other than rendering. Just use C++ streams or (heresy!) stdio. That way you'll learn skills that are applicable outside of Irrlicht.

Code: Select all

#include <stdio.h>

int matrix[16][16];

FILE * file = fopen("save.bin", "wb"); // "wb" is "write" + "binary"

if(file)
{
    // Even for a simple case that you think will never change,
    // write out a version in case you do change your mind later 
    // and need to identify older versions.  It's also a good idea to start
    // with a magic string to identify the file type.  Here, we'll use 
    // one string for both
    const char magicString[] = { 'M', 'A', 'T', '1', '6', 'x', '1', '6' };
    if(1 != fwrite(magicString, sizeof(magicString), 1, file) ||
       1 != fwrite(matrix, sizeof(matrix), 1, file))
    {
        // handle error
    }
    (void)fclose(file);
}
else
{
    // handle error
}
Last edited by rogerborg on Sun Dec 02, 2007 10:11 am, edited 1 time in total.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Morgawr
Posts: 95
Joined: Wed Sep 26, 2007 7:04 pm

Post by Morgawr »

rogerborg wrote:
Morgawr wrote:mm since I'm thinking about making an RPG, I guess it'll be kinda complex...
Yes. Yes it will.
Morgawr wrote:I will have to put a variable for each event in the game and set it to true when it's been triggered already or not... then save all those variables + items + character position + levels + everything else in a file.. right? Hope it works, it looks complex..
Yes. Yes it is.

First off, your serialisation scheme will change a lot during development. I'd strongly recommend that you start your serialisation (of the whole file, and of each significant object in it) with a version number. That will give you the opportunity of loading older save files, if they contain a subset of your current data and if you can fill in the blanks with defaults; at a minimum, you should fail gracefully with a descriptive error. Remember to take into account older software being given a newer save file. It's better to do it and then never need it than to try to kludge it in later once you've released versions of both software and save files into the wild.

I'd recommend making objects responsible for serialising themselves. This breaks the task up into more manageable subtasks, and keeps the responsibility for each part of it better compartmentalised. Note that when you do the load, that each object will be responsible for creating new instances of its children, and then telling them to set themselves up (passing them whatever stream/file you're using).

Notionally, each object should do this during saving:
  • Its own data (e.g. global data for the world, starting with a version number)
    The number of children of each type (e.g. 3 dungeons)
    Telling each of its children (e.g. each of 3 dungeons) to serialise itself out.
When loading, each object:
  • Loads its own data (e.g. global data for the world, starting with a version number and either handing older versions gracefully or raising an error if it can't handle them or if a newer or unknown version number is encountered)
    The number of children of each type (e.g. 3 dungeons)
    Create that number of instances of the appropriate object type.
    Tells each of these new instances (e.g. each of 3 dungeons) to serialise itself in.

Also, I'd recommend put in error checking and descriptive logging right from the start. If you produce a human readable log of everything that's being saved and loaded then it'll save you time in the long run when you introduce a subtle discrepancy between what you're saving and what you're loading.

Morgawr wrote:and regarding the other question, I'm a newbie with the saving/loading files subject, how can I make a binary file with 16x16 ints using IReadFile and IWriteFile?
God knows. I'd urge you not to become reliant on Irrlicht for anything other than rendering. Just use C++ streams or (heresy!) stdio. That way you'll learn skills that are applicable outside of Irrlicht.

Code: Select all

#include <stdio.h>

int matrix[16][16];

FILE * file = fopen("save.bin", "wb"); // "wb" is "write" + "binary"

if(file)
{
    // Even for a simple case that you think will never change,
    // write out a version in case you do change your mind later 
    // and need to identify older versions.  It's also a good idea to start
    // with a magic string to identify the file type.  Here, we'll use 
    // one string for both
    const char magicString[] = { 'M', 'A', 'T', '1', '6', 'x', '1', '6' };
    if(1 != fwrite(magicString, sizeof(magicString), 1, file) ||
       1 != fwrite(matrix, matrixSize, 1, file))
    {
        // handle error
    }
    (void)fclose(file);
}
else
{
    // handle error
}
WOW thanks a lot man, that is EXTREMELY useful.. and yeah I guess I'll just use normal C/C++ I/O operations, without relying on Irrlicht...
Time to look into my C++ manual once again, haven't opened it for months now... :roll:
Post Reply