Windows Game freezes while loading

Genetix

Member
I have a procedurally generated world in which I save all objects that have the parent object "default_save" - I save each of these objects to an .ini file. The saved .ini file can easily climb over 40,000 lines - but my problem can occur when it is large or small, I haven't been able to find a correlation to the issue when the file is to big.

Sometimes when running my loading script the game will just freeze up entirely - and will not resume, even if left for hours.

Here is the Saving script:


num = instance_number(default_save); //Getting the number of building objects
name = ""
instanceArray[num] = 0; //Defining the instance array
save_system()

ini_open("savedata.ini")
ini_section_delete( 'Save' );

for ( i = 0; i < num; i += 1)
{
instanceArray = instance_find(default_save, i);
name = object_get_name(instanceArray.object_index)
ini_write_string("Save", "object" + string(i), name); //saves id to file so you know what object to create when loading
ini_write_real( "Save", "object" + string(i) + "x", instanceArray.x); //saves x to file
ini_write_real( "Save", "object" + string(i) + "y", instanceArray.y); //saves y to file
ini_write_real( "Save", "count", num); //saves the total number of instances to the file for loading later
}


It will save each objects name,x value, y value, and also saves a variable 'count' which tells the load script how many items to load. This works fine, i've never had an issue with it.

Here is the Loading Script:


ini_open("savedata.ini")
num = ini_read_real("Save", "count", 0); //get the number of instances
name = ""
ini_close();

show_debug_message("Start For Loop for default_save");
ini_open("savedata.ini")
for ( i = 0; i < num; i += 1)
{
myID = ini_read_string( "Save", "object" + string(i) , ""); //loads id from file
myX = ini_read_real( "Save", "object" + string(i) + "x", 0); //loads x from file
myY = ini_read_real( "Save", "object" + string(i) + "y", 0); //loads y from file
name = asset_get_index(myID)
instance_create( myX, myY, name);
show_debug_message("Item Loaded" + string(name))
}

ini_close();


The load script first grabs the 'count' to tell how many objects to load. Then we go to a for loop, set to run 'count' times.
The for loop cycle through each line of the saved .ini file. For each line it sets a var for x value, y value, and object name. It then creates an instance of that object at the corresponding x and y location in the game map. This process repeats thousands of times until the for loop ends. At this point a previously saved world has been restored.

This saving and loading system works really great 99% of the time, but occasionlly seems to freeze up entirely somewhere in that loading scripts for loop. I have tried many things to troubleshoot the root cause of the problem - I made a huge world that had over 100,000 objects to save/load - and it still worked fine. I output to the debug window each items name, trying to find out if a specific item was causing the issue, which doesn't seem to be the case.

Any ideas?
 

jo-thijs

Member
Your code looks correct, though it is structured a little odd.
I have too little information to say what might be going wrong.

Is there some save file that always consistently freezes everything up?
In that case, could you send your game (or project) with that savefile to someone to test if it is device dependent?

If you could send me the gmz file of the project, I could try to analyse what exactly goes wrong.
 

johnwo

Member
Here's some minor changes to you code:

Save script:
Code:
var num = instance_number(default_save); //Getting the number of building objects
var name = "";
instanceArray[num] = 0; //Defining the instance array
save_system();

ini_open("savedata.ini")
ini_section_delete("Save");

for ( i = 0; i < num; i++)
{
    instanceArray = instance_find(default_save, i);
    name = object_get_name(instanceArray[i].object_index);
    ini_write_string("Save", "object" + string(i), name); //saves id to file so you know what object to create when loading
    ini_write_real( "Save", "object" + string(i) + "x", instanceArray.x); //saves x to file
    ini_write_real( "Save", "object" + string(i) + "y", instanceArray.y); //saves y to file
}

ini_write_real( "Save", "count", num);
ini_close(); // Added ini_close()
Changes/questions:
save_system(), I assume this is where the instance array is populated.
In the line name = object_get_name(instanceArray.object_index); Indexing wasn't present, just instanceArray.object_index
Moved ini_write_real( "Save", "count", num); outside the loop, as it is only necessary to write it once.
Added var to some variables as they aren't likely to be used outside of this script.


Load script:

Code:
ini_open("savedata.ini")
var num = ini_read_real("Save", "count", 0); //get the number of instances
var name = "";

show_debug_message("Start For Loop for default_save");

for ( i = 0; i < num; i += 1)
{
     myID = ini_read_string( "Save", "object" + string(i) , ""); //loads id from file
     myX = ini_read_real( "Save", "object" + string(i) + "x", 0); //loads x from file
     myY = ini_read_real( "Save", "object" + string(i) + "y", 0); //loads y from file
     name = asset_get_index(myID)
     instance_create( myX, myY, name);
     show_debug_message("Item Loaded" + string(name));
}

ini_close();

Questions/changes:
ini_open("savedata.ini");
and ini_close(); was removed. You don't have to open, close, open, close, when you can open then close...
Added var to some variables as they aren't likely to be used outside of this script.
You may want to remove show_debug_message("Item Loaded" + string(name)); as lots of debugger output may freeze GM:S (speaking from experience).

If this doesn't help, then please provide the save_system-script.

Cheers!
 

jo-thijs

Member
You made an error in your code, instanceArray is not an array anymore when you reference it as an error, which will result in an error.
Besides that, it's indeed a lot better, but it can still be improved.

For example, why is instanceArray initialized as a huge empty array, only to be used as a single number afterwards?

Why is the variable name used in the save script?
It is referenced only once, directly after calculation, so it is quite unnecessary.

Why is name initialized as an empty string in both scripts?
It doesn't need initialization.

Why is the name of an object stored in "myID" and the id of an object stored in "name" in the load script?

Why are i, myID, myX and myY not temporary variables?

And finally, why not use i++ in the for loop of the load script.
 
Top