• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Save/Load Code

Status
Not open for further replies.
H

Homunculus

Guest
The code looks ok at a first glance. That’s the output you’d expect in case there are no instances of obj_saveable in the room. You can verify if that’s the case by adding a show_debug_message inside the with statement (try just outputting something like “instance” + string(i) ). If you get no output message, it means the with content is never run.

Edit: i just saw your code for adding the instance map is inside the switch statement... you need to correct that, it makes no sense (does that even compile?). Also, as said before, you need to destroy the main map after this whole process, not the instance map.
 
Last edited by a moderator:
The code looks ok at a first glance. That’s the output you’d expect in case there are no instances of obj_saveable in the room. You can verify if that’s the case by adding a show_debug_message inside the with statement (try just outputting something like “instance” + string(i) ). If you get no output message, it means the with content is never run.

Edit: i just saw your code for adding the instance map is inside the switch statement... you need to correct that, it makes no sense (does that even compile?). Also, as said before, you need to destroy the main map after this whole process, not the instance map.

@Catan. Thanks for your help so far. I made the changes you suggested and now I"m getting JSON that looks like this:

Code:
{ "instance19": { "objIndex": 10.000000 }, "instance3": { "objIndex": 273.000000 }, "instance17": { "objIndex": 12.000000 }, "instance9": { "objIndex": 371.000000 }, "instance7": { "objIndex": 32.000000 }, "instance13": { "objIndex": 118.000000 }, "instance1": { "objIndex": 71.000000 }, "instance15": { "objIndex": 14.000000 }, "instance5": { "objIndex": 104.000000 }, "instance11": { "objIndex": 46.000000 }, "instance20": { "objIndex": 9.000000 }, "instance6": { "objIndex": 105.000000 }, "instance12": { "objIndex": 15.000000 }, "instance8": { "objIndex": 56.000000 }, "instance2": { "objIndex": 70.000000 }, "instance16": { "objIndex": 13.000000 }, "instance18": { "objIndex": 11.000000 }, "instance4": { "objIndex": 103.000000 }, "instance10": { "objIndex": 358.000000 }, "instance0": { "objIndex": 106.000000 }, "instance14": { "objIndex": 8.000000 }, "instance21": { "objIndex": 20.000000 } }
If you look at the code it is clearly not detecting the SentryBatObject object and the only thing being added to the map is the objIndex, that's outside the switch.

Code:
if (argument0 == 0)
{
    
    var saveFile = file_text_open_write(working_directory+"save_working1.sav");
    
    
    if (file_exists(working_directory+"save_working1.sav"))
    {
        file_delete(working_directory+"save_working1.sav");
        
    }
}

if argument0 == 1
{
    var saveFile = file_text_open_write(working_directory+"save_working2.sav");

    if (file_exists(working_directory+"save_working2.sav"))
    {
        file_delete(working_directory+"save_working2.sav");
    
    }
}

if argument0 == 2
{
    var saveFile = file_text_open_write(working_directory+"save_working3.sav");

    if (file_exists(working_directory+"save_working3.sav"))
    {
        file_delete(working_directory+"save_working3.sav");
    
    }
}

if argument0 == 3
{
    var saveFile = file_text_open_write(working_directory+"save_working4.sav");

    if (file_exists(working_directory+"save_working4.sav"))
    {
        file_delete(working_directory+working_directory+"save_working4.sav");
    }   
}

if argument0 == 4
{
    var saveFile = file_text_open_write(working_directory+"save_working5.sav");

    if (file_exists(working_directory+"save_working5.sav"))
    {
        file_delete(working_directory+"save_working5.sav");
    
    }
}
show_debug_message("SaveWorkingFile executing")



var overarchingSaveMap = ds_map_create();

var instanceSaveID = 0;

with (obj_saveable){    //sort of like a for loop iterating over the objects with this signature
  var instanceMap = ds_map_create(); //create a submap
  instanceMap[? "objIndex"] = object_index; //save the object index so we know what to create upon load.
    show_debug_message("With obj_saveable");


  switch (object_index) {
  case SentryBatObject:
            show_debug_message("case SentryBatObject");
 
            //ds_map_add(instanceMap, "global-wind_drop", global.wind_drop);
            //ds_map_add(instanceMap, "global-wind_drop_myTimer", global.wind_drop_myTimer);
            //ds_map_add(instanceMap, "sprite_index", sprite_index);
            //ds_map_add(instanceMap, "image_speed", image_speed);
            instanceMap[? "name"] = "test";
            instanceMap[? "x"] = x;
            instanceMap[? "y"] = y;
            instanceMap[? "hp"] = hp;
            instanceMap[? object_get_name(object_index)] = object_get_name(object_index)
            break;
 

        
  }
 
 
  ds_map_add_map(overarchingSaveMap, "instance"+string(instanceSaveID), instanceMap);//add this with instance to the overarchingSaveMap
  instanceSaveID ++; //put the instance map into the larger map ensuring each one will have a unique key
}

JSONInstance = json_encode(overarchingSaveMap);
show_debug_message("WINDJSON" + JSONInstance);
//JSONInstance2 = json_encode(list1);
file_text_write_string(saveFile, JSONInstance);
        
ds_map_destroy(overarchingSaveMap);   
// completed processsing of with statement


///close the file
file_text_close(saveFile);
I'm not entirely sure (and I read the switch section of the manual) how GML handles GM handles objects/instances and switcfhes.
 
H

Homunculus

Guest
Nothing special about objects inside switches. If your json does not contain any SentryBatObject, and your output does not show “case SenteyBatObject”, it means that there are no instances of that object.

It may be more clear if you use the object name instead of the object_index in the map for the key “objIndex”. You are doing that also in the instanceMap in a weird way, not so sure why...
 
Last edited by a moderator:
How does the switch (object_index) work? What exactly am I testing against? I had someone help me with that part of the code and I don't know 100% how it works. I know how switch works
in Java and C but not GML so much.
 

chamaeleon

Member
How does the switch (object_index) work? What exactly am I testing against? I had someone help me with that part of the code and I don't know 100% how it works. I know how switch works
in Java and C but not GML so much.
switch(x) will take the value of x and compare it, one by one, against your case statements until one succeeds, at which point it will execute the statements until a break or the end of the switch code block, whichever comes first. So you could in theory, say, use show_debug_message("Trying to save a " + object_get_name(object_index)), just before your switch statement, and see if it displays "Trying to save a SentryBatObject", or if it will say something else, in which case you will know why the case is not matched.
 
Ok. So I did like you suggested @chamaeleon and this was the result:

Code:
SaveWorkingFile executing
With obj_saveable
Trying to save a SkyLandGrass
With obj_saveable
Trying to save a GrassLandsTerrain
With obj_saveable
Trying to save a EightStarObject
With obj_saveable
Trying to save a WallObject
With obj_saveable
Trying to save a FrankenSteinsCastleObject
With obj_saveable
Trying to save a DraculasCastleObject
With obj_saveable
Trying to save a DraculaObject
With obj_saveable
Trying to save a FrankensteinIdleObject
With obj_saveable
Trying to save a MiniSentry
With obj_saveable
Trying to save a MasterController
With obj_saveable
Trying to save a BrainMaster
With obj_saveable
Trying to save a Bats8
With obj_saveable
Trying to save a GemObject
With obj_saveable
Trying to save a Bats1
With obj_saveable
Trying to save a Bats7
With obj_saveable
Trying to save a Bats6
With obj_saveable
Trying to save a Bats5
With obj_saveable
Trying to save a Bats4
With obj_saveable
Trying to save a Bats3
With obj_saveable
Trying to save a Bats2
With obj_saveable
Trying to save a Player
It seems to have picked up on just about everything but the SentryBatObject.
 

TsukaYuriko

☄️
Forum Staff
Moderator
Does SentryBatObject have a parent, and is that parent obj_saveable, or another object that has it as its parent further up the chain? If yes, confirm that there is an instance of it in the room at the time this code runs.
 
Hi Tsuka!!!

Actually I got it to output to the JSON string but I really can't make heads or tails of it. Also, it is only supposed to output the one case statement and it did a lot more. Are you any good at JSON?

This is the JSON file:

Code:
{ "instance19": { "Bats3": "Bats3" }, "instance3": { "WallObject": "WallObject" }, "instance17": { "Bats5": "Bats5" }, "instance9": { "MiniSentry": "MiniSentry" }, "instance7": { "x": 340.000000, "hp": 9000.000000, "y": 950.000000, "SentryBatObject": "SentryBatObject", "name": "test" }, "instance13": { "GemObject": "GemObject" }, "instance1": { "GrassLandsTerrain": "GrassLandsTerrain" }, "instance15": { "Bats7": "Bats7" }, "instance5": { "DraculasCastleObject": "DraculasCastleObject" }, "instance11": { "BrainMaster": "BrainMaster" }, "instance20": { "Bats2": "Bats2" }, "instance6": { "DraculaObject": "DraculaObject" }, "instance12": { "Bats8": "Bats8" }, "instance8": { "FrankensteinIdleObject": "FrankensteinIdleObject" }, "instance2": { "EightStarObject": "EightStarObject" }, "instance16": { "Bats6": "Bats6" }, "instance18": { "Bats4": "Bats4" }, "instance4": { "FrankenSteinsCastleObject": "FrankenSteinsCastleObject" }, "instance10": { "MasterController": "MasterController" }, "instance0": { "SkyLandGrass": "SkyLandGrass" }, "instance14": { "Bats1": "Bats1" }, "instance21": { "Player": "Player" } }
 
H

Homunculus

Guest
So the problem was that you didn’t have obj_saveable as parent lf sentrybat? I see it in the json so i suppose this is solved.

About the JSON: it’s outputting exactly what you told it to: an entry with the object name for every child of obj_saveable, and if it’s a sentrybatobject some extra.

The code for adding the instance name and creating the instanceMap is not in a condition or switch statement that prevents it from executing unless it’s sentrybatobject, so why do you expect not to see the other objects as well?

If you only want to output the data of sentrybatobject, don’t have the other object as children of obj_saveable... or just create the instanceMap inside the switch case instead of every obj_saveable, but then what’s the point of having obj_saveable at all?

You need to really understand your code, you can’t just make changes randomly based on our suggestions and hope it works.
 
Last edited by a moderator:
Ok. Here is something I need to understand. I need to separate objects ink the JSON. Right now the JSON is pretty random. But since it is a map it is not ordered, correct? So how do I separate the data from say, SentryBatObject and LightningBatObject. ?
 
H

Homunculus

Guest
Good question. Right now you have a (main) ds_map holding other ds_maps of instances, but as you correctly noted, it’s not an ideal structure to iterate over the instances.

Instead of adding the instances to the ds_map directly, add them to a ds_list and mark them using ds_list_mark_as_map.
Afterwards add the ds_list to the main map using ds_map_add_list. This should return a better formatted json that should be easier to process on load.
 
Ok @Catan. Before I waste my time coding something that's wrong is this the right procedure you are talking about?

I create a ds_list for each object , marking the individual addition to the ds_list, When the ds_list object is complete, I add it to the
"main" map. That way each list object can be retrieved by key, and then I can iterate over that list (since they are marked) and I can
get individual data members. Is that correct?
 
H

Homunculus

Guest
To be clear, please note that adding them to a single list does not allow you to get a specific set of instances out of the map (as in "get all saved SentryBatObjects"), but just makes it more efficient to iterate over every instance.

If for some reason you need to get all saved instances of a specific object, you need to split the list into multiple lists, one for every type object you are saving. The code for this can be tricky, if you need an example let me know.
 
If for some reason you need to get all saved instances of a specific object, you need to split the list into multiple lists, one for every type object you are saving. The code for this can be tricky, if you need an example let me know.
Ok/. I think we are on the same page. Say, I have a SentryBatObject and a LightningBatObject. I create a generic ds_list. I come across the case for SentryBatObject..I add each entry into the list, one by one, marking each member at a time. I don't use one gigantic list but
a ds list for eaech object. When the ds_list is done being populated, I add the ds_list to the main map. Then I move on to the next object., adding members to a ds list etc... When it adds the ds_list to the main map, it does so with key. For example, the key SentryBatObject and the ds_list SentryBatObject_list.
 
H

Homunculus

Guest
Yeah that sounds about right @Ted Gress .

Here's how the code could look like (at least the part in the with block). Not tested, but should at the very least give you an idea:

Code:
//iterate over every saveable object
with (obj_saveable){

  //create the ds_map for the instance
  var instanceMap = ds_map_create();

  //get the name of the object we are trying to save
  var objName = object_get_name(object_index);

  //get the ds_list of instances for the specific object instance we are trying to save
  var objList = overarchingSaveMap[? objName];

  //if the list does not exist yet (undefined), create a new one and add it to the overarching map (using the object name as key)
  if(is_undefined(objList)) {
    objList = ds_list_create();
    ds_map_add_list(overarchingSaveMap, objName, objList);
  }

  //add the instance map to its ds_list, and mark it as such
  ds_list_add(objList, instanceMap);
  ds_list_mark_as_map(objList, ds_list_size(objList)-1);

  //start adding the instance attributes to the instance ds_map
  instanceMap[? "objName"] = objName; //add the name to the ds_map
 
  /* if there are any other attributes you need to save for EVERY object, regardless of which object it is, add them here */

  //add attributes for specific objects
  switch (object_index) {
    case SentryBatObject:
      instanceMap[? "x"] = x;
      instanceMap[? "y"] = y;
    break;
  }

}
Note that you can add the lists to the main map before actually inserting the instance map and attributes, it doesn't really matter as long as you generate the JSON after this block.
 
Last edited by a moderator:
What does this mean?

Data structure with index does not exist.
at gml_Script_scr_save_total (line 70) - var objList = overarchingSaveMap[? objName];
 
H

Homunculus

Guest
That overarchingSaveMap does not exist or does not contain a ds_map. As in your previous code, you create it before the with block, maybe you inadvertently removed it?
 
H

Homunculus

Guest
Give it a try on your own first. Remember that you don't really need to think about the json since the structure you get back from json_decode is exactly the one you created while saving, that is a main map holding several ds_list of instance attributes (as ds_maps)
 
Ok. How am I doing so far?

Code:
var overarchingSaveMap = ds_map_create();

var instanceSaveID = 0;

//iterate over every saveable object
with (obj_saveable){

  //create the ds_map for the instance
  var instanceMap = ds_map_create();

  //get the name of the object we are trying to save
  var objName = object_get_name(object_index);

 
  //get the ds_list of instances for the specific object instance we are trying to save
  var objList = overarchingSaveMap[? objName];

  //if the list does not exist yet (undefined), create a new one and add it to the overarching map
  if(is_undefined(objList)) {
    objList = ds_list_create();
    ds_map_add_list(overarchingSaveMap, objName, objList);
  }

  //add the instance map to its ds_list, and mark it as such
  ds_list_add(objList, instanceMap);
  ds_list_mark_as_map(objList, ds_list_size(objList)-1);

  //start adding the instance attributes to the instance ds_map
  //instanceMap[? "objName"] = objName; //add the name to the ds_map
 
 
  objName = instanceMap[? "objName"];
 
 
 
  /* if the are any other attributes you need to save for EVERY object, regardless of which object it is, add them here */

  //add attributes for specific objects
  switch (object_index) {
    case SentryBatObject:
      x = instanceMap[? "x"];
      y = instanceMap[? "y"];
    break;
  }

}

  ds_map_add_map(overarchingSaveMap, "instance"+string(instanceSaveID), instanceMap);//add this with instance to the overarchingSaveMap
  instanceSaveID ++; //put the instance map into the larger map ensuring each one will have a unique key


    JSONInstance = json_encode(overarchingSaveMap);
    show_debug_message("WINDJSON" + JSONInstance);
    //JSONInstance2 = json_encode(list1);

      
    ds_map_destroy(overarchingSaveMap); 


    ///close the file
    file_text_close(saveFile);

Edit:


More changes. I'm not sure where to get the object_index from.

Code:
readString = file_text_read_string(loadFile);
var overarchingSaveMap = json_decode(readString);

//iterate over every saveable object
with (obj_saveable){
  //create the ds_map for the instance
  var instanceMap = ds_map_create();
  //get the name of the object we are trying to save
  var objName = object_get_name(object_index);
 
  //get the ds_list of instances for the specific object instance we are trying to save
  var objList = overarchingSaveMap[? objName];
  //if the list does not exist yet (undefined), create a new one and add it to the overarching map
  if(is_undefined(objList)) {
    objList = ds_list_create();
    ds_map_add_list(overarchingSaveMap, objName, objList);
  }
  //add the instance map to its ds_list, and mark it as such
  //ds_list_add(objList, instanceMap);
  //ds_list_mark_as_map(objList, ds_list_size(objList)-1);
  //start adding the instance attributes to the instance ds_map
  //instanceMap[? "objName"] = objName; //add the name to the ds_map
 
  
  objName = instanceMap[? "objName"];
 
 
 
  /* if the are any other attributes you need to save for EVERY object, regardless of which object it is, add them here */
  //add attributes for specific objects
  switch (object_index) {
    case SentryBatObject:
      x = instanceMap[? "x"];
      y = instanceMap[? "y"];
    break;
  }
}
  //ds_map_add_map(overarchingSaveMap, "instance"+string(instanceSaveID), instanceMap);//add this with instance to the overarchingSaveMap
  //instanceSaveID ++; //put the instance map into the larger map ensuring each one will have a unique key

 
 show_debug_message("WINDJSON" + JSONInstance);
 //JSONInstance2 = json_encode(list1);
 
 ds_map_destroy(overarchingSaveMap);

 ///close the file
 file_text_close(saveFile);
 
Last edited by a moderator:
H

Homunculus

Guest
Making a copy of the save code, blindly inverting the assignment of the instance variables and posting the resulting code after 15 minutes of work does not even count as trying.

I’m sorry but after all the time invested by me and others explaining how to structure and fix your save file, and finally being given the actual code, you simply can’t post something like this. It shows you either don’t understand a thing of what you are doing in the save script, or are too lazy to figure it out yourself and expect us to give you the code to copypaste.

I don’t want to sound rude, but you need to do better than this and put more effort into it.
 
Last edited by a moderator:
I apologize. I admit I was rushing. I didn't mean to come off as lazy, I just have been working on this save code for so long now that I thought you could give me some hints while I worked out the details. To put things in frame, I'm the only programmer working on this game,
and this has been over a year I'm working on it. I just want you to see it from my perspective. I wasn't asking for a copy/paste, just correction so I understood the code better. I'lll keep working on it and I'll put more effort into it.
 
If you'd be so kind, could you tell me one thing and I'll let this rest. In my code below I need ma key for overarching map so I can retrieve the ds_list. If you can tell me where
it is I'll leave it rest.

Code:
readString = file_text_read_string(loadFile);
var overarchingSaveMap = json_decode(readString);


 
  var objList = overarchingSaveMap[? "objName" ];   //get the big ds list from the overarchingsavemap
  var lsize = ds_list_size(objList);
  var i;
  var in_map;
  for (i=0; i < lsize; i++)
  {
    
    in_map = ds_list_find_index(objList, i);
    
    var objName = in_map[? "objName"]; //retrieve the object name from the map
    var objindex = asset_get_index(objName); //get the object index for this name
    
    
  switch (objindex) {
    case SentryBatObject:
      x = in_map[? "x"];
      y = in_map[? "y"];
      show_debug_message("in_map is x: " + string(x) + " y:" + string(y));
    break;
  }
 
H

Homunculus

Guest
There are two things that need to be clarified before anything else.

1. In general, when you save instances to file, you want to recreate them on load. I don’t know the specifics of your saving system, but if you already have some instances of those objects in your room, you may want to destroy those and create new ones by reading the save file. If that’s the case, the most important part of the code is missing: the creation of the instances. Don’t just take what I’m saying for granted, think about what you really need to happen (in words, not code) and post it here for reference.

2. If all you need to do is restore all the instances from the savefile, there’s no need to “group” them into one ds_list per object like we did. In fact, if that’s all you are trying to do, having them grouped makes no sense and is going to make it harder for you. Why do you need them grouped by object to begin with?
 
1. In general, when you save instances to file, you want to recreate them on load. I don’t know the specifics of your saving system, but if you already have some instances of those objects in your room, you may want to destroy those and create new ones by reading the save file. If that’s the case, the most important part of the code is missing: the creation of the instances. Don’t just take what I’m saying for granted, think about what you really need to happen (in words, not code) and post it here for reference.
Well, that's should've been obvious to me. I am retrieving values for a object, getting the object's name and member variables, but *not* creating an instance to populate. Correct?

. If all you need to do is restore all the instances from the savefile, there’s no need to “group” them into one ds_list per object like we did. In fact, if that’s all you are trying to do, having them grouped makes no sense and is going to make it harder for you. Why do you need them grouped by object to begin with?
This is a case of somebody suggesting something to me and me going along with it. The idea is, from what i understend when I return to the main room from the save screen to save the game, to only have to use the with(obj_saveable) to "iterate" through the objects that need to be saved such as the SentryBatObject and the LightningBatObject and the state of Dracula's castle, etc. I'm doing the obj_saveable to group the objects instead of checking all the objects individually? Does that sound right? That's thebest explanation I can gave.
 
H

Homunculus

Guest
When saving you are reading the data of your instances and storing it in json format. If at load time you need to restore the room as it was, you need to create those instances to begin with, and then assign the values you saved back to their original state. What are you setting those to if there are no instances? I really don’t know what you expected to happen just by saving the values to some variables.

With obj_saveable you are in fact “grouping” your instances that need to be saved so that it’s easier to loop through them and save everything that needs to be saved in a single script, without having to loop through every single object explicitly. It’s a “quality of life” solution that avoids writing tons of redundant code.
This has absolutely nothing to do with how you want your save file (the json) to be structured, it’s just how you process your instances. How you want them saved comes after inside the actual with block code. Makes sense?

Edit: by the way, i was asking for a description of what you expect to happen when loading the save file. The saving part is quite clear at this point
 
Last edited by a moderator:
Code:
Edit: by the way, i was asking for a description of what you expect to happen when loading the save file. The saving part is quite clear at this poin
I expected it to load an object name, create an instancfe based off that object name, and populate the member variables of that instance. It was just a really really stupid of me to forget to create
the instance as part of the load script. I honestly did know that was part of the problem.

SO this:


with the object name you can get the object index
Create an instance of the object index
Take the member variables values from the instance map
Assign the instance member variables to the ones taken from the instance map

let me clarify once you have the object index

Code:
 switch (objindex) {
    case SentryBatObject:
      x = in_map[? "x"];
      y = in_map[? "y"];
      show_debug_message("in_map is x: " + string(x) + " y:" + string(y));
    break;
I should have a case statement for every objindex. So since I have a case of SentryBatObjecvft,
Code:
case SentryBatObject:
   x = in_map[? "x"];
      y = in_map[? "y"];
   instance_create_depth(x, y, SentryBatObject)
break
I feel like I"m missing something though. Like how do I access the new instances when they are created like I did above. Suggestions?
 
Some may argue using the return value of instance create function. Just a thought.
Yeah I thought that. but I'm trying to figure out where to store it. Like I get the return value of the instance create function returns that instance, but where in my code should I put it?? hmmm Oh hey while we are at it, @chamaeleon , my game is loading too many copies of the savefile. I checked to see if I was claling th e load function more times than I close it and that didn't pan out. is there anything else I could be doing that it might cause to have multiple copies?
 
Last edited by a moderator:

chamaeleon

Member
Yeah I thought that. but I'm trying to figure out where to store it. Like I get the return value of the instance create function returns that instance, but where in my code should I put it?? hmmm
Maybe start with asking yourself whether you need to store it or not.. After all, it will be an instance with instance variables after it's created, and events will run for it according to the object it was created from, and it will participate in collision events or be returned or not in collision/point/instance functions, and with() statements using its object or a parent object will find it, etc., etc. If you still feel like you need to store it for some purpose, use whatever means you wish. Maybe a global variable holding map or list, or in the case of a singleton, a global variable for the purpose of holding this one instance, or put it in some variable holding data in a state management instance. The sky is the limit.

Edit: Needless to say, there should be fidelity between what you save and what you load, and how it's represented. If you rely on a data structure to save, you'll want to recreate it, if you rely on the implicitness of using with(), you don't necessarily need to store it in a data structure, but could just create the instance and forget about its exact id, and so on.
 
Maybe start with asking yourself whether you need to store it or not.. After all, it will be an instance with instance variables after it's created, and events will run for it according to the object it was created from, and it will participate in collision events or be returned or not in collision/point/instance functions, and with() statements using its object or a parent object will find it, etc., etc. If you still feel like you need to store it for some purpose, use whatever means you wish. Maybe a global variable holding map or list, or in the case of a singleton, a global variable for the purpose of holding this one instance, or put it in some variable holding data in a state management instance. The sky is the limit.

Edit: Needless to say, there should be fidelity between what you save and what you load, and how it's represented. If you rely on a data structure to save, you'll want to recreate it, if you rely on the implicitness of using with(), you don't necessarily need to store it in a data structure, but could just create the instance and forget about its exact id, and so on.
Good point. :)

So, any idea why this IDE keeps telling me I have too many copies of a file open? I call the read function once and at the end of the script I close it. SImple right?
 
Last edited by a moderator:

TsukaYuriko

☄️
Forum Staff
Moderator
When posting error messages, please always cite the full error message. Paraphrasing them runs the risk of om̶i̵t̨t͡͝i̷͘͡ǹ̸̵ǵ́͞ ̵̡̧͝͠͡͝͠͠v̨̢́͟͜i͡t̴̷̡͡͞a̵̧̧͘͟l͘ ̴͘͝ ͟͡ ̷͜҉̧ ̵͘ ̵͘͟͢ ͘͠ ̷͡ ͏̀͟ ̨́ ̷̨͟͠ ̶͏̧̕n̸ę͝e̶̡̧d̴ to be able to help you.

At least in this post, I see an _open, but no _close. It looks like it could just be a fragment of a bigger script, as it seems similar to more "complete" versions you've posted so far, but just to make sure...

In the worst case, prepend every line where you open a file with incrementing a (global) variable by 1, and every closing line with decrementing the same variable. If this ever exceeds 1, you have a problem that you can probably track down with strategic breakpoint placement.
 
@Tsuka Hi :) I usually don't post the whole script because they tend to be legthy. Here is the full script that is having the loading issues:

Code:
if (argument0 == 0)
{
    
    var loadFile = file_text_open_read(working_directory+"save_working1.sav");
    
    }

else if argument0 == 1
{
    var loadFile = file_text_open_read(working_directory+"save_working2.sav");

}

else if argument0 == 2
{
    var loadFile = file_text_open_read(working_directory+"save_working3.sav");;
}

else if argument0 == 3
{
    var loadFile = file_text_open_read(working_directory+"save_working4.sav");

}

else if argument0 == 4
{
    var loadFile = file_text_open_read(working_directory+"save_working5.sav");;

}



readString = file_text_read_string(loadFile);
var overarchingSaveMap = json_decode(readString);

with (obj_saveable){


//get the name of the object we are trying to save
  var objName = object_get_name(object_index);

 
  //get the ds_list of instances for the specific object instance we are trying to save
  var objList = overarchingSaveMap[? objName];

 //var obj_saveable_name = asset_get_index(obj_saveable);
  //var objList = overarchingSaveMap[? obj_saveable_name ];   //get the big ds list from the overarchingsavemap
  var lsize = ds_list_size(objList);
  var i;
  var in_map;
  for (i=0; i < lsize; i++)
  {
    
    in_map = ds_list_find_index(objList, i);
    
    var objName = in_map[? "objName"]; //retrieve the object name from the map
    var objindex = asset_get_index(objName); //get the object index for this name
    
    
  switch (objindex) {
    case SentryBatObject:
      x = in_map[? "x"];
      y = in_map[? "y"];
      show_debug_message("in_map is x: " + string(x) + " y:" + string(y));
    break;
  }


}

  //ds_map_add_map(overarchingSaveMap, "instance"+string(instanceSaveID), instanceMap);//add this with instance to the overarchingSaveMap
  //instanceSaveID ++; //put the instance map into the larger map ensuring each one will have a unique key


    
    show_debug_message("WINDJSON" + JSONInstance);
    //JSONInstance2 = json_encode(list1);

        
    ds_map_destroy(overarchingSaveMap);   


    ///close the file
    file_text_close(loadFile);


}
 

chamaeleon

Member
Looks like that will try to close the same file as many times as with() executes its code block. Move the close function outside it.
 
H

Homunculus

Guest
Can you explain what do you think "with" does? At this point I'm pretty sure you have no idea, but it may prove useful to direct you towards a working solution.
 
Can you explain what do you think "with" does? At this point I'm pretty sure you have no idea, but it may prove useful to direct you towards a working solution.
Really. Is this bash Ted week? Seriously some of this is uncalled for. Best explanation I have for a with statement is 1) changes the scope of the of the object being operated upon to the one in the with operator 2) say you have an object and the with is:

Code:
with (BrainObject)
{
    x + = 10
   y + = 10
}
The BrainObject is in scope and the two lines of code inside the curly braces are executed for all instances of BrainObject.
furthermnore

Code:
with (obj)
{
       other.x += 10
      other.y += 10
}
Will take x and y and add t hem to the x and y on the x and y that is on the outside scope.
 
Ok. This is the code but the only thing I don't understand is when loading how do you get t he key for the overarchingmap where the ds_list is stored??
Code:
if (argument0 == 0)
{
    
    var loadFile = file_text_open_read(working_directory+"save_working1.sav");
    
    }

else if argument0 == 1
{
    var loadFile = file_text_open_read(working_directory+"save_working2.sav");

}

else if argument0 == 2
{
    var loadFile = file_text_open_read(working_directory+"save_working3.sav");;
}

else if argument0 == 3
{
    var loadFile = file_text_open_read(working_directory+"save_working4.sav");

}

else if argument0 == 4
{
    var loadFile = file_text_open_read(working_directory+"save_working5.sav");;

}



readString = file_text_read_string(loadFile);
var overarchingSaveMap = json_decode(readString);

with (obj_saveable){


//get the name of the object we are trying to save
  var objName = object_get_name(object_index);

 
  //get the ds_list of instances for the specific object instance we are trying to save
  var objList = overarchingSaveMap[? objName];

 //var obj_saveable_name = asset_get_index(obj_saveable);
  //var objList = overarchingSaveMap[? obj_saveable_name ];   //get the big ds list from the overarchingsavemap
  var lsize = ds_list_size(objList);
  var i;
  var in_map;
  for (i=0; i < lsize; i++)
  {
    
    in_map = ds_list_find_index(objList, i);
    
    var objName = in_map[? "objName"]; //retrieve the object name from the map
    var objindex = asset_get_index(objName); //get the object index for this name
    
    
  switch (objindex) {
    case SentryBatObject:
      x = in_map[? "x"];
      y = in_map[? "y"];
      show_debug_message("in_map is x: " + string(x) + " y:" + string(y));
      instance_create_depth(x, y, -1100, SentryBatObject);
    break;
  }


}

  //ds_map_add_map(overarchingSaveMap, "instance"+string(instanceSaveID), instanceMap);//add this with instance to the overarchingSaveMap
  //instanceSaveID ++; //put the instance map into the larger map ensuring each one will have a unique key


    


}


    //show_debug_message("WINDJSON" + JSONInstance);
    //JSONInstance2 = json_encode(list1);

        
    ds_map_destroy(overarchingSaveMap);   


    ///close the file
    file_text_close(loadFile);
 
H

Homunculus

Guest
Great. Then back to your load code: you have a list of properties belonging to instances that existed at one point in time where the game got saved, and you need to restore them. Those instances don't exist yet, you just loaded a bunch of json data.
Why does having a "with" on the instances currently in the room seems like a good idea to you to achieve the above? I really don't get what's your reasoning behind this, you know how "with" works, why does this makes sense to you then?

Moreover, looking at this:

Code:
x = in_map[? "x"];
y = in_map[? "y"];
This code runs inside a "with", meaning that you are in the scope of a specific instance (that has nothing to do with your save data, by the way, other than being an instance of the same object), and you are in a loop as well, meaning that this code is executed multiple times for the same instance. If you understand how "with" and "for" loops work, how can this possibly look right to you?

I'm sorry, but I'm really lost. You get bashed because it doesn't matter how much we explain and what you claim to understand, this is not reflected in any sensible way in the code you produce. It looks like that, despite every possible effort on our part, you are producing code just by blindly combining pieces recycled from the save routine or whatever suggestion you get.

The only advice I can give you this: first, as discussed before, you probably don't need to group your save data into multiple lists anymore. Just use one with everything in there.
Then start coding the loading part from scratch. The save code is not going to help you if not as a reference on how the data was saved, open a blank script and lay out some comments on what it is supposed to happen before coding anything, something like this, maybe a bit more detailed:

Code:
//open the save file
//load the json
//go through the saved data
//restore the instances and their values
//etc...
 
Last edited by a moderator:
Code:
Great. Then back to your load code: you have a list of properties belonging to instances that existed at one point in time where the game got saved, and you need to restore them. Those instances don't exist yet, you just loaded a bunch of json data.
Why does having a "with" on the instances currently in the room seems like a good idea to you to achieve the above? I really don't get what's your reasoning behind this, you know how "with" works, why does this makes sense to you then?
1. The with statement is pointless for the functionality I'm trying to implement. It reallyl does nothing at all.
Code:
I'm sorry, but I'm really lost. You get bashed because it doesn't matter how much we explain and what you claim to understand, this is not reflected in any sensible way in the code you produce. It looks like that, despite every possible effort on our part, you are producing code just by blindly combining pieces recycled from the save routine or whatever suggestion you get.
No. My problem is blindly taking advice and suggestions without trusting my gut. With exception, if I would have taken the time I took to debug the "advice" that formed this monstrosity I called saved/load code and instead just referenced the manual and done the code before like I did for the *entire* remaning code in this project we wouldn't have to have this talk.

Code:
The only advice I can give you this: first, as discussed before, you probably don't need to group your save data into multiple lists anymore. Just use one with everything in there.
Then start coding the loading part from scratch. The save code is not going to help you if not as a reference on how the data was saved, open a blank script and lay out some comments on what it is supposed to happen before coding anything, something like this, maybe a bit more detailed:
Right one list. We don't need to mark the lists either as far as I can see. And you mean like, pseudocode? What a novel idea. I'll figure out how to do the load code on my own.I've always done better by m yself anyway.
 
No. My problem is blindly taking advice and suggestions without trusting my gut. With exception, if I would have taken the time I took to debug the "advice" that formed this monstrosity I called saved/load code and instead just referenced the manual and done the code before like I did for the *entire* remaning code in this project we wouldn't have to have this talk.
And you mean like, pseudocode? What a novel idea. I'll figure out how to do the load code on my own.I've always done better by m yself anyway.
Eeek. Funny how many people have tried to help you but they're all in the wrong and if only we hadn't forced you to post the question in the first place you would have done it by now. Sounds kinda like you were just hoping by posting on the forum someone would just give you the exact code to slot into your project. I seem to remember giving you some advice previously: sometimes, when your project gets big enough and complex enough, there's no way that someone on the forum is going to be able to help. There's too much information to post for someone simply stopping by to be able to understand exactly what is going on. At that point, it becomes entirely up to you to solve your problems. This is where projects fail. You're either good enough at coding at the specific moment to do that, or you're not.

And Ted, there are many people in this and ALL your other threads that are MUCH better at coding than you are (I don't mean this in an offensive way, there are many people in this thread who are better at coding than me as well). The problem is not on other peoples end. When someone gives you code, you need the coding chops to be able to take that code as advice and convert it into a form that will work within your project...If you can't do that, there's nothing we can do on our end. I can tell you from reading this thread that I understand exactly what the other people are trying to tell you to do...They are not wrong. There's been a few different approaches, which if combined brainlessly might clash, but none of them are specifically wrong.
 
Eeek. Funny how many people have tried to help you but they're all in the wrong and if only we hadn't forced you to post the question in the first place you would have done it by now. Sounds kinda like you were just hoping by posting on the forum someone would just give you the exact code to slot into your project. I seem to remember giving you some advice previously: sometimes, when your project gets big enough and complex enough, there's no way that someone on the forum is going to be able to help. There's too much information to post for someone simply stopping by to be able to understand exactly what is going on. At that point, it becomes entirely up to you to solve your problems. This is where projects fail. You're either good enough at coding at the specific moment to do that, or you're not.

And Ted, there are many people in this and ALL your other threads that are MUCH better at coding than you are (I don't mean this in an offensive way, there are many people in this thread who are better at coding than me as well). The problem is not on other peoples end. When someone gives you code, you need the coding chops to be able to take that code as advice and convert it into a form that will work within your project...If you can't do that, there's nothing we can do on our end. I can tell you from reading this thread that I understand exactly what the other people are trying to tell you to do...They are not wrong. There's been a few different approaches, which if combined brainlessly might clash, but none of them are specifically wrong.
I'm done with this forum. Everything I say is wrong. I could say the earth is round and these people who are trying to help me would say its flat. Have you read these posts? My code is unsalvageable? Do you know what "with" is because I'm pretty sure you don't"? Or how about: " I really don’t know what you expected to happen just by saving the values to some variables." I could cite two paragraphs where people were rude, ignorant, or just plain cruel. I'm done. I'm finished. This is a place to come and discuss coding and helping each other out. It's not bash the one who has the least experience coding in GML. And yes there are people on here who know GML better than me. I'll admit that. But its a FRICKIN GAME PROGRAMMING LANGUAGE. I admit I'm not that experienced in it. If I wasn't, I wouldn't be on a forum asking questions. Next time you have problems with Computer Vision, Machine Learning, AI, Big Data or something that isn't a hobby and is used in the real world I'd be glad to help. I don't see any blockbuster games coming out of this forum. That's it. I've said my peace. Bye.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
This topic is now closed, as I can't really see it going anywhere constructive.

@Ted Gress : I'm sorry to see you getting frustrated by this situation, but have to say that in all your posts you seem to be the one with the issues. You seem to get angry very easily and don't seem to be able to take any form of advice and actually apply it. I don't think anyone here has attacked you, and most - if not all - of the posts have been from people trying their hardest to patiently help you. I would also point out that blockbuster games don't come from this forum because most beginners don't make blockbuster games - and this is foremost a forum for beginners. They start here, learn what they need to make their blockbuster games and then move on and actually make them, so please don't try and belittle the entire community due to your inability to comprehend or adapt. I suggest you take a deep breath, rethink what you're doing and want to achieve, and then come back with a perhaps less ambitious project and start again.
 
Status
Not open for further replies.
Top