Save / Load system

S

sean o reilly

Guest
I have a game built that uses physicsw and im trying to add a save/load system to it. I've looked at some tutoials and ive tried the in-game save / load and none of it works. The in-game save / load systems won't work while i'm using physics. Just wondering if anyone can point me in the right direction to set this up. I'm very new to programming and not sure how to resolve this. GMC has helped me out before and I'm hoping they can again.

Thanks in advance.
 
A

Acr515

Guest
The easiest way to create a saving loading system is to use an INI file. These are simply text files that contain the variables you've saved.

When you want to save your game, you'll have something like this:

Code:
ini_open("saveData.ini");
ini_write_real("Variables", "score", score); //The first value is a header for that section, the second value is the label for your variable in the INI file, and the third value is the actual variable
ini_write_string("Variables","string",string); //This is how you save strings
ini_close(); //Remember to close the INI or you'll have a memory leak
Then, once you want to load your save game, you would have something like this:

Code:
ini_open("saveData.ini");
score = ini_read_real("Variables","score",0); //The third value here will set the score variable if there is no save file
string = ini_read_string("Variables","string","Hello world"); //This is a string instead of a number
ini_close();
Hope this helps!
 

Yal

🐧 *penguin noises*
GMC Elder
The first thing you should consider when making a save system is to decide WHAT to save. Do you NEED to save the position of every physics object so you can recreate the scene, or is it enough to save what the last level the player got to and then restart that when they load? Trying to minimize the granularity of the data you save makes the system a lot easier to manage - that's one of the reasons a lot of games use special 'save points' in separate rooms and have all enemies respawn when you load the game.
 
S

sean o reilly

Guest
Thanks for the quick responce guys. So heres what i was hoping i could do, put a continue on the start screen thats only visable when a saved game is available. Now from here I would like to save the game when you enter a room so that each to you load it starts that room from the beginning but the main character would have keys in her inventory or may have damage to her health and these things i'd like to have saved as well just not sure how to do that lol. So the question is do i do a physical object save that the player has to select to save the game or everytime you enter a room it autosaves either way the room should restart when you load a room but either way is fine.
 
S

sean o reilly

Guest
I've tried to use the save/load example that comes with gamemaker. It saves the character but not the room, the health or the keys and I dont know where to go from here the tutorial uses a .ini and a .txt but to be honest from what i can see the .ini is for saving global variables and the .txt is for saving and loading game objects. The character loads correctly but the keys collected keep resetting, the health returns to full and the room stays on the start screen could anyone advise what im doing wrong ? I can't seem to get passed this road block.

The code im using is:

//Initialise all the global variables
//Open the ini file for reading
ini_open("Save.ini");

//General Vars
global.hp = ini_read_real("Health", "hp", 100);
global.dest_room = ini_read_real("dest_room", "room", dest_room);

//Saving Keys
global.keyUp[0] = ini_read_real("keyUp", "0", keyUp);
global.keyLeft[1] = ini_read_real("keyLeft", "1", keyLeft);
global.keyDown[2] = ini_read_real("keyDown", "2", keyDown);
global.keyRight[3] = ini_read_real("keyRight", "3", keyRight);
global.keyBoss[4] = ini_read_real("keyBoss", "4", keyBoss);

//Close the ini file
ini_close();

The save code i use:

L-key press:


if !instance_exists(obj_Hero_Walk)
{
var file, str, str_pos, str_temp, val, num;
file = file_text_open_read("level.txt");
if file != -1
{
str = file_text_read_string(file);
file_text_readln(file);
str_pos = 1;
num = 0;
str_temp = "";

while(str_pos < string_length(str))
{
while (string_char_at(str, str_pos) != "|")
{
str_temp += string_char_at(str, str_pos);
str_pos += 1;
}
val[num] = real(str_temp);
str_pos += 1;
num += 1;
str_temp = "";
}
instance_create(val[0], val[1], obj_Hero_Walk);

str = file_text_read_string(file);
file_text_readln(file);
str_temp = "";
num = 0;
str_pos = 1;

while(str_pos < string_length(str))
{
while (string_char_at(str, str_pos) != "|")
{
str_temp += string_char_at(str, str_pos);
str_pos += 1;
}
val[num] = real(str_temp);
str_temp = "";
str_pos += 1;
num += 1;
if num = 2
{
num = 0;
instance_create(val[0], val[1], obj_Inventory);
}
}
file_text_close(file);
}
}


S-key press:

var file, str;
//Open file for writing
file = file_text_open_write("Level.txt");

//Create player string
str = string(obj_Hero_Walk.x) + "|" + string(obj_Hero_Walk.y) + "|";

//Write player string and go to a new line
file_text_write_string(file, str);
file_text_writeln(file);

//Reset string var
str = "";

//Write wall objects to file
with (obj_Inventory)
{
str += string(x) + "|" + string(y) + "|";
}

//Write string with wall information to file and start a new line
file_text_write_string(file, str);
file_text_writeln(file);

//Reset string var
str = "";

file_text_close(file);

not sure if this helps anyone see what I'm doing wrong.

Thanks in advance
 

RangerX

Member
Well, you see how you save those global variables and keys variables?
You have to save each objects' position and other important variables in them so the game comeback exactly as the way it was when saving.
Its a good amount of work and organisation. You can prepare arrays and have the objects save their important variables in them and then when you load you have them read them again, etc.
 
S

sean o reilly

Guest
I can save the objects but when i collect a key and its stored in my inventory (ds_list) and i save the game it doesnt save the key I've already collected plus if the character is hurt it resets her health after a save and i need it to save any damage she recieved. plus I've no idea how to save the room im in too and it loads everything to the start screen instead of bringing me to whatever room I've saved the game in. Would arrays work for this and could you point me in the direction of some examples, I've never used arrays before and would'nt even know where to start.

Thanks in advance.
 

slayer 64

Member
The built in game_save("filename") and game_load("filename") functions will save a snapshot of the entire gamestate and write it to a file. This worked great for me back in the day and it's suppose to still. The only drawback is that is saves everything, so you have to make sure your player is in a really good spot before saving.
 

NazGhuL

NazTaiL
The built in game_save("filename") and game_load("filename") functions will save a snapshot of the entire gamestate and write it to a file. This worked great for me back in the day and it's suppose to still. The only drawback is that is saves everything, so you have to make sure your player is in a really good spot before saving.
What if you patch the game? I think the savegame can't be use in that case no?
I believe custom save using ds_map_secure_save is a better option than ini.
 

RangerX

Member
About the game_save function...

It can be a powerful allie but you have to be careful of its limitations:

- Save files aren't compatible from one compile to another (though wouldn't crash for some minor changes)
- Does not work if physics are enable
- Doesn't save any data structures or surfaces (everything that is volatile anyways)
 
S

sean o reilly

Guest
Thanks again for the quick response. I would be saving when the player collides with the goto_room trigger that way each time the player sellects load game the room should restart without me having to save every item inside the room. but my issue is saving the inventory, health and the room change. i already have a code in the creation code of each room that wont let a key spawn if its already been collected. its the health, inventory and room that im having trouble saving or loading I'm not even see which area I'm making the mistake.

thanks in advance.
 
D

Danny Taylor

Guest
Try using a custom variable for health, and using global variables for the items the player collected, as you said, the system seems to save global variables correctly. Also, saving at certain trigger points is a good idea. :)
 
N

Noprops

Guest
Would something like this work by chance?

ini_open("aooni.ini");
ini_write_real("Variables", "score", score); //The first value is a header for that section, the second value is the label for your variable in the INI file, and the third value is the actual variable
ini_write_string("Variables","string",string); //This is how you save strings
ini_close(); //Remember to close the INI or you'll have a memory leak

//Here is the ini, i am trying to figure out how to get it to work in here
//[settings]
//ambient =
//sfx =
//brightness =
//resolution =
//
//[player]
//name =
//room =

//[achievments]
//You are cool by default //You stuck with the name you were given. =
//Travelling Through Time //It's utter madness, isn't it? =
//You bastard! //Play through South Park mode. =
//Temporary Existance //Yeah, we all knew this would happen someday. =
//Mika =
//Takuro =
//Takeshi =
//The Mysterious Unknown //Attempt to play as the Mysterious Man =
//Failed Entry //Be prevented from playing as the oni. =
//Teachers Pet //Save your teacher, Be the teachers pet you have always wanted to be. =
//First Blood //Let your teacher die, be that child that the other kids in school have been tempting you to be. =
//Every Prologue Has An Ending //Beat the prologue. =
//Dawn of a New Start //Begin Chapter One. =
//Do you fancy this? (I) //Unlock the first set of custom skins for the menus. =
 
Last edited by a moderator:

Yal

🐧 *penguin noises*
GMC Elder
//Here is the ini, i am trying to figure out how to get it to work in here
Two ideas:
  • Try saving some dummy stuff in an INI file to see how the format looks like, then you can make your file using that as a guide.
  • INI read functions will use a default value if it can't find the sought-for value in the file, so you could use that for the defaults and then write them to the file once they're different (e.g. when the player changes settings and clicks "apply").
 
D

derp556

Guest
Hi! I am just wondering, how would i go about using this to save global variables (I.E. global.minigameunlocked = insertnumber)
 

PlayerOne

Member
Hi! I am just wondering, how would i go about using this to save global variables (I.E. global.minigameunlocked = insertnumber)

If you write false or true in the global use this:
Code:
ini_write_string("Save", "Unlocks", global.minigameunlocked);
However, if you use 1,2,3, etc to determine what has been unlocked in your game use this:
Code:
ini_write_real("Save", "Unlocks", global.minigameunlocked);
Example:
Code:
ini_open(save.ini) //If save doesnt exist an .ini file will be created, otherwise it will open save.ini.
ini_write_string("Save", "Unlocks", global.minigameunlocked); // Saves the global as a string
ini_close() //Prevents memory leaks.
For more information: https://docs.yoyogames.com/source/dadiospice/002_reference/file handling/ini files/index.html
 

Yal

🐧 *penguin noises*
GMC Elder
how would i go about using this to save global variables (I.E. global.minigameunlocked = insertnumber)
To save them, write their current value to a file.
To load them later, at boot you'd read the file, find the value, and put it in the variable.

The hard part is knowing which value originally belonged to each variable. INI files tags each value with a name, so it's pretty simple to read (with the drawback that HUMANS can read it too, so it's super easy for a player to hack their savefile and unlock everything). For binary and text files, you could save everything in a certain order and then read it back in the same order (which is what I generally do).
 
Does GM:Studio v1.something support json?
No, but JSON is fairly easy to re-create.
example (without using computer programs, just my brain)
Code:
{
    "TestValue":"This is a test"
    "width":419
    "height":68
    "whatRickAstleyIsNeverGonnaGive":"You up"
    "willRickAstleyLetYouDown":false
}
if you want to create nested structures, it will be more difficult for a human, at which point you may as well look for a gms2 plugin that will do it better

[EDIT] I actually don't know whether v1 does, but I don't think v2 does.
 

FrostyCat

Redemption Seeker
[EDIT] I actually don't know whether v1 does, but I don't think v2 does.
That is absolutely false and unresearched.

GMS 2.3 supports JSON, and in fact it does it better than any other previous version.
Even GMS 1 supports JSON, albeit a little less convenient because it doesn't yet have structs or accessor chaining:
Please DO NOT sign up for new accounts on the GMC just to spew fake news and talk to ghosts on it. If you aren't educated on the subject of a thread, don't respond. If a post dates back more than a year ago from someone who has been deactivated for inactivity, don't respond.
 
That is absolutely false and unresearched.

GMS 2.3 supports JSON, and in fact, it does it better than any other previous version.
Even GMS 1 supports JSON, albeit a little less convenient because it doesn't yet have structs or accessor chaining:
Please DO NOT sign up for new accounts on the GMC just to spew fake news and talk to ghosts on it. If you aren't educated on the subject of a thread, don't respond. If a post dates back more than a year ago from someone who has been deactivated for inactivity, don't respond.
I stand corrected. At least it encouraged someone to add something useful to the conversation, although the paragraph at the end is kinda toxic.
 
I stand corrected. At least it encouraged someone to add something useful to the conversation, although the paragraph at the end is kinda toxic.
That last paragraph is the best forum etiquette advice you're ever going to get. Trust me, FrostyCat put it nicer than most would and offered you resources to boot.
 
Top