• Hey! Guest! The 40th (!!!) GMC Jam will take place between February 25th, 12:00 UTC to March 1st 12:00 UTC. Why not join in this very special anniversary jam! Click here to find out more!

Windows Loading In-Game Save Error After Update(non-STEAM)

jwyouth

Member
Everything was working fine until update. Now I get this Error when I try to load save game from in-game menu:

############################################################################################
ERROR in
action number 1
of Step Event1
for object obj_soldiergunidle:

Variable obj_soldiergunidle.freeze(100435, -2147483648) not set before reading it.
at gml_Object_obj_soldiergunidle_Step_1 (line 8) - if (freeze = true)
############################################################################################
gml_Object_obj_soldiergunidle_Step_1 (line 8)

"freeze = false" in the Create Event of the instance, and in the Begin Step Event I have "if (freeze = true)". This also happens with another line of code, "hp = 10" in the Create Event of the instance, and in the Begin Step Event I have "if (hp <= 0)". I have this for every enemy instance and the error will pop up for any of them in any room I have saved in. Other than not loading the save file, the game runs fine. I created a new save file but same result.
 
Last edited:

FoxyOfJungle

Kazan Games
Please show your code, how are you loading and saving the game? are you using that save method using game_save_buffer() or are you using a custom system?
 

jwyouth

Member
Create Event
-------------------------------------------------------------------------------
smoke = false;
freeze = false;
vsp = 0;
grv = 0.3;
walksp = 1;
hsp = walksp;
attacking = false;

hp = 6;
flash = 0;
-----------------------------------------------------------------------------------

Begin Step Event
----------------------------------------------------------------------------------

if (place_meeting(x,y,obj_puddlesmoke))
{
smoke = true;
instance_change(obj_soldiergunsmoke,true);

}
if (freeze = true)
{
image_index = 0;
instance_change(obj_soldiergunfreeze,true);
}
if (hp <= 0)
{
image_index = 0;
instance_change(obj_soldierexplode,true);
}
---------------------------------------------------------------------------------------

Save game code
-----------------------------------------------------------------------------------------
if image_index = 2
{

game_save("save.dat");
with(obj_player)
{
image_index = 0;
sprite_index = Hero_save;
state = states.save
}
}
-------------------------------------------------------------------------------------------

Load game code
--------------------------------------------------------------------------------------------
key_down = keyboard_check_pressed(ord("S")) or (gamepad_button_check_pressed(0,gp_padd));
key_up = keyboard_check_pressed(ord("W")) or (gamepad_button_check_pressed(0,gp_padu));
menu_x += (menu_x_target -menu_x) / menu_speed;

if (menu_control)
{
if (key_up)
{
menu_cursor ++;
if (menu_cursor >= menu_items) menu_cursor =0;
}
if (key_down)
{
menu_cursor--;
if (menu_cursor < 0) menu_cursor = menu_items-1;
}
if (gamepad_button_check_pressed(0,gp_start)) or (keyboard_check(vk_enter))
{
menu_x_target = gui_width+200;
menu_committed = menu_cursor;
menu_control = false;
}
}

if (menu_x > gui_width+150) && (menu_committed != -1)
{
switch (menu_committed)
{
case 2:
{
audio_stop_sound(sndIntro);
if (!file_exists("save.dat"))
{
scr_slidetransition(TRANS_MODE.NEXT);
}
if (file_exists("save.dat"))
{
instance_create_layer(x+315, y+25, "Text", obj_newgame);
}
}
break;
case 1:
{
if (!file_exists("save.dat"))
{
audio_stop_sound(sndIntro);
scr_slidetransition(TRANS_MODE.NEXT);
}
else
{
audio_stop_sound(sndIntro);
game_load("save.dat")
}
}
break;
case 0: game_end(); break;
}
}
----------------------------------------------------------------------------------------------------------------------
 

jwyouth

Member
everything works like it used to except when this happens: game_load("save.dat"). The game crashes because the instances begin step events can't read the create event values even though they are there.
 

FrostyCat

Member
everything works like it used to except when this happens: game_load("save.dat"). The game crashes because the instances begin step events can't read the create event values even though they are there.
You screwed yourself over the instant you chose this "easy" way out.

This function will not revive data structures, buffers, surfaces, or any other ID-numbered dynamic resource from when the save file was generated.

This function will break when you change even the slightest detail of your project, invalidating any and all save files generated by builds prior to the change.

This function's output is not documented, so there's no known way of patching the save file manually either.

This function's reputation among seasoned GML programmers is beyond salvation, for the reasons described above.

There is no easy way out of this mess. Learn how to load and save manually through other formats (e.g. JSON, buffers, text files, INI files, etc.) and redo your entire saving/loading code using what you learned, maybe then there's hope.
 

jwyouth

Member
You screwed yourself over the instant you chose this "easy" way out.

This function will not revive data structures, buffers, surfaces, or any other ID-numbered dynamic resource from when the save file was generated.

This function will break when you change even the slightest detail of your project, invalidating any and all save files generated by builds prior to the change.

This function's output is not documented, so there's no known way of patching the save file manually either.

This function's reputation among seasoned GML programmers is beyond salvation, for the reasons described above.

There is no easy way out of this mess. Learn how to load and save manually through other formats (e.g. JSON, buffers, text files, INI files, etc.) and redo your entire saving/loading code using what you learned, maybe then there's hope.
I am definitely not a seasoned programmer by any means, but fortunately almost everything I have done is artwork, animation, and coding for the main character, enemies, and some environmental stuff. My game is not dependent on this save feature, so I don't think its all that dire of a mistake. I used it because it worked until this last update. So, would having a better save system resolve my problem or would I still have the same issue but with a better save system?
 

FrostyCat

Member
If you redo your save system manually using other formats (e.g. JSON, buffers, text files, INI files, etc.), not only will you solve the problem this time, it will also prevent version upgrades and minor changes from completely invalidating your system in the future. It's worth taking time off to learn.
 
I am definitely not a seasoned programmer by any means, but fortunately almost everything I have done is artwork, animation, and coding for the main character, enemies, and some environmental stuff. My game is not dependent on this save feature, so I don't think its all that dire of a mistake. I used it because it worked until this last update. So, would having a better save system resolve my problem or would I still have the same issue but with a better save system?
Save systems are usually pretty easy to make. It gets complicated the more you want to save, but most games don't actually need to save that much.

Most games normally have to save this kind of info:
-What level the player is on.
-Maybe score
-Maybe some details on the player (how many lives left, what weapon they have, etc).

Make a saveGame function, and a loadGame function. All the saveGame function will do is

write to a file (savegame1.sav) and just write your details:
[savegame1.sav]
level=5
score=120
lives=5

And then your load function has to:
1: Read this file
2: Setup the score/lives
3: Goto the level that was saved.

There should be plenty of examples in the tutorial section to give this a go.

Also, a note on the default GM save function: It's fine to use for simple/small projects. It's super convenient and works well at what it does. Just be aware of some of the issues with it (Frosty listed it above). For bigger projects you'll want to write your own one, so you have proper control on what's going on.
 

jwyouth

Member
Thanks everybody!

I will research different types of save systems and see which one works best for what I'm doing.

Save systems are usually pretty easy to make. It gets complicated the more you want to save, but most games don't actually need to save that much.

Most games normally have to save this kind of info:
-What level the player is on.
-Maybe score
-Maybe some details on the player (how many lives left, what weapon they have, etc).

Make a saveGame function, and a loadGame function. All the saveGame function will do is

write to a file (savegame1.sav) and just write your details:
[savegame1.sav]
level=5
score=120
lives=5

And then your load function has to:
1: Read this file
2: Setup the score/lives
3: Goto the level that was saved.

There should be plenty of examples in the tutorial section to give this a go.

Also, a note on the default GM save function: It's fine to use for simple/small projects. It's super convenient and works well at what it does. Just be aware of some of the issues with it (Frosty listed it above). For bigger projects you'll want to write your own one, so you have proper control on what's going on.
So I tried using an ini save system and it saves correctly but when I load it will send me to the default room not the saved room. Here is the code:


Save Code
--------------------------------------------------------------------------------------------------
if (file_exists("Save.sav")) file_delete("Save.sav");
ini_open("Save.sav");
var SavedRoom = room;
ini_write_real("Save1","room",SavedRoom);
ini_close();
----------------------------------------------------------------------------------------------------

Load Code
-----------------------------------------------------------------------------------------------------
if (file_exists("Save.sav"))
{
audio_stop_sound(sndIntro);
ini_open("Sav.sav");
var LoadedRoom = ini_read_real("Save1","room",Tutorial);
ini_close();
room_goto(LoadedRoom)
}
else
{

}
}
 

FrostyCat

Member
Rule #1 for save file safety: Save resource names, not resource IDs.
GML:
var SavedRoom = room_get_name(room);
ini_write_string("Save1", "room", SavedRoom);
GML:
var LoadedRoom = asset_get_index(ini_read_string("Save1", "room", "Tutorial"));
 

jwyouth

Member
I've read the manual and watched like 20 tutorials about json, ini, and ds maps, and for the life of me I'm not getting it. I just need to save and load the info of one persistent object that keeps track of your progress. So far I can get the room to save and load but I cannot grasp anything beyond that. I'm about to lose my mind. I don't know where to start. How do you save and load the persistent object in the current room if it didn't originally start there? I don't know what format is best, it is a linear game(no repeat rooms) and I have 10 things that go from false to true when you get them, i.e. sword=false but when you pick it up sword=true.
 

FrostyCat

Member
If you don't know where to start, start by saving and loading a single value. Then saving and loading your persistent object is the same procedure, done once per variable in it.

Saving your sword variable:
GML:
ini_write_real("PersistentObject", "sword", objPersistentObject.sword);
Loading your sword variable:
GML:
objPersistentObject.sword = ini_read_real("PersistentObject", "sword", false);
The example above is for INIs, but the same general idea applies for any other save format. The saving code writes the information to some position in a file. The loading code reads the information from some position in the file and places it back where the saving code got it from.
 

jwyouth

Member
If you don't know where to start, start by saving and loading a single value. Then saving and loading your persistent object is the same procedure, done once per variable in it.

Saving your sword variable:
GML:
ini_write_real("PersistentObject", "sword", objPersistentObject.sword);
Loading your sword variable:
GML:
objPersistentObject.sword = ini_read_real("PersistentObject", "sword", false);
The example above is for INIs, but the same general idea applies for any other save format. The saving code writes the information to some position in a file. The loading code reads the information from some position in the file and places it back where the saving code got it from.
so will this save and load the persistent object with default values but the value of sword will be pulled from the ini file?
 

FrostyCat

Member
You save extracted individual values into the file, not live objects. Then when you load, you recreate that object based on individual values saved into the file. The example code I provided saved one piece of information to the INI file, under the section PersistentObject and key sword. A correlated collection of these makes a save file.

When you were a kid, did bedtime ever get in the way of a physical game of Monopoly, and you have to save the board to a sheet of paper? If you have, think back. If you have not, think about the 1990's kid who did not have the luxury of a "Save Game" button.

If you have a hotel on Oriental Avenue, what would you do to remind yourself of that for the next playdate? Does the hotel token belong on the sheet? No, the hotel token goes back into the pit where the dice and tokens live. Instead you would draw a picture of a hotel on Oriental avenue, or write down "Hotel: Oriental Avenue", or something of the sort. Then when you play again, you see that drawing or text description of a hotel on Oriental Avenue, and take a hotel token from the pit and put it on the board.
 

jwyouth

Member
I'm an 80's kid, but I think I got a handle on it. I just didn't understand fully how the persistent object was being recalled back into the game and what all I needed to actually save and I need to rethink what needs to be a persistent object and what doesn't.
 
Top