GameMaker Ds_list displaying as -1 after doing a ds_map_destroy.

C

Chris Livermore

Guest
hi guys,

im getting a bit confused....

I am attempting to create a save file and Load the save file.

the only issue I am having is the below:

I am loading all my credit list from JSON file... it loads in perfectly.
_wrapper holds the whole JSON file information
ds_list_copy(planetCredits, _wrapper[? "PLANETCREDITS"]); // load planet Credits.
this loads it fine with no issues.

I then destroy my _wrapper.
ds_map_destroy(_wrapper);

and the planetCredits displays as (size: -1) <invalid data structure>.

I have tried the following trying to rectify this....

I have tried firstly saving _wrapper[? "PLANETCREDITS"]); into a different variable and then loading this into planetCredits as I thought it may be something to do with GMS just referencing the List. this had the same result.

I then tried running all the data through a for loop an then adding each value into the list... this also did not work.

has onyone any ieas as to why this may be happening?

thanks for your help in advance :)
 
Are you assigning a new ds_list to planetCredits before attempting the copy? i.e.

Code:
planetCredits = ds_list_create();
When you destroy a map that you have loaded via JSON, all the lists inside the map are also destroyed automatically.

This is only a guess without seeing the rest of your code, maybe the list inside the wrapper map has the same id as planetCredits (somehow - not sure how this would happen exactly, but it seems like thats whats happening).
 
C

Chris Livermore

Guest
ok, I had another look at it this morning with fresh eyes, It would seem that one of my variables in a nested for loop is being assigned the same ID s the global variable I am using to store the list and then when the script has finished executing it drops the "a" variable and and such wipes the list as well. the problem Is i can see why its keeping the a variable as it should drop it after the for loop surely?

here is my full script not sure why its doing what its doing though!

Im aware my code is messy, for that I can only appologise....

Code:
loading = true;
globalvar planetsLoaded, planetsInventorysLoaded_Amounts, planetsInventorysLoaded_Names;

if (file_exists("SaveGame.sav"))
{
    //TODO: goto room also need to save the current room on save.
    room_goto(Galaxy1);
    
    
    var _wrapper = LoadJSONFromFile("SaveGame.sav");
#region LOAD PLAYER
    var _list = _wrapper[? "PLAYER"];
    
    for (var i = 0; i < ds_list_size(_list); ++i)
    {
        var _map = _list[| i];

            var test = _map[? "x"]
            if test != undefined
            {
                //LOAD SHIP POSITION
                playerX = _map[? "x"];
                playerY = _map[? "y"];
                if player_craft != undefined
                {
                    player_craft.x = playerX;
                    player_craft.y = playerY;
                }
            }
            
            var test = _map[? "Credits"];
            if test != undefined
            {
                //LOAD ALL PLAYER DATA
                playerCredits = _map[? "Credits"];
                maxHP = _map[? "maxHP"];
                currentHP = _map[? "currentHP"];
                onFire = _map[? "onFire"];
                chanceOfFire = _map[? "chanceOfFire"];
                fireExtinguishers = _map[? "fireExtinguishers"];
                shield = _map[? "shield"];
                upgrade_Hull = _map[? "upgrade_Hull" ];
                upgrade_Booster = _map[? "upgrade_Booster"];
                upgrade_doubleGun = _map[? "upgrade_doubleGun"];
                upgrade_Laser = _map[? "upgrade_Laser"];
                maxShield = _map[? "maxShield"];
                shieldRegenTimer =  _map[? "shieldRegenTimer"];
                max_thrust = _map [? "max_thrust"];
                gun_maxCooldown = _map[? "gun_maxCooldown"];
                gun_cooldown = _map[? "gun_cooldown"];
                
            }
        test = undefined;
    }
    ds_list_destroy(_list);

#region LOAD PLAYER INVENTORY
    var _list = _wrapper[? "PLAYERINVENTORY"];
    for (var b = 0; b < ds_list_size(ds_list_find_value(_list,0)); ++b)
    {
        var _list1 = ds_list_find_value(ds_list_find_value(_list, 0),b);//first set of names
        var _list2 = ds_list_find_value(ds_list_find_value(_list, 1),b);//first set of amounts
    
        for (var a = 0; a< ds_list_size(_list1); ++a)
        {//iterate through each list in the list
            var details = ItemDetails(ds_list_find_value(_list1,a),0,0);
            scr_addItem(playerInventory, ds_list_find_value(_list1,a), ds_list_find_value(_list2,a), details[1], details[2], details[3], details[4], details[5])
        }

    }
    
#endregion
    
    
    
    
#endregion
#region LOAD PLANETS
    var _list = _wrapper[? "PLANETS"];
    planetsLoaded = ds_grid_create(6,0);
    for (var i = 0; i < ds_list_size(_list); ++i)
    {
        var _map = _list[| i];
        var test = _map[? "obj"];
        
        if test != undefined && test = "planet"
        {   
            ds_grid_resize(planetsLoaded,6,ds_grid_height(planetsLoaded)+1);
            ds_grid_add(planetsLoaded, 0, ds_grid_height(planetsLoaded)-1,_map[? "x"]);
            ds_grid_add(planetsLoaded, 1, ds_grid_height(planetsLoaded)-1,_map[? "y"]);
            ds_grid_add(planetsLoaded, 2, ds_grid_height(planetsLoaded)-1,_map[? "name"]);
            ds_grid_add(planetsLoaded, 3, ds_grid_height(planetsLoaded)-1,_map[? "inventoryLocation"]);
            ds_grid_add(planetsLoaded, 4, ds_grid_height(planetsLoaded)-1,_map[? "repairCost"]);
            ds_grid_add(planetsLoaded, 5, ds_grid_height(planetsLoaded)-1,_map[? "image_blend"]);
        }
        test = undefined;
    }
//BELOW NEEDS WORK LOADS LIST with 2 INTERNAL LISTS wich contain 6 internal Lists. FIX SAVING
//or LOADING so we pull indevidual lists out of each of the 6 lists.
#endregion
#region LOAD PLANET INVENTORYS/CREDITS
    
    var _list = _wrapper[? "PLANETINVENTORYS"];
    planetsInventorysLoaded_Names = ds_grid_create(ds_list_size(ds_list_find_value(_list,0))+1,10);
    planetsInventorysLoaded_Amounts = ds_grid_create(ds_list_size(ds_list_find_value(_list,0))+1,10);
    for (var b = 0; b < ds_list_size(ds_list_find_value(_list,0)); ++b)
    {
        var _list1 = ds_list_find_value(ds_list_find_value(_list, 0),b);//first set of names
        var _list2 = ds_list_find_value(ds_list_find_value(_list, 1),b);//first set of amounts
    
        for (var item = 0; item< ds_list_size(_list1); ++item)
        {//iterate through each list in the list
            var debugtest = ds_list_find_value(_list1,a);
            ds_grid_add(planetsInventorysLoaded_Names,b,item,ds_list_find_value(_list1,item));
            ds_grid_add(planetsInventorysLoaded_Amounts,b,item,ds_list_find_value(_list2,item));
        }

    }
    
    //planetCredits = ds_list_create();
    ds_list_copy(planetCredits, _wrapper[? "PLANETCREDITS"]); // save planet Credits.     
#endregion
#region LOAD CRITTERS
    var _list = _wrapper[? "CRITTERS"];
    for (var i = 0; i < ds_list_size(_list); ++i)
    {
        var _map = _list[| i];
        var Createdcritter = room_instance_add(Galaxy1,_map[? "x"], _map[? "y"],obj_enemy);
         ds_list_add(DS_critter, Createdcritter);
        with (Createdcritter)
        {
            movement_x = _map[? "movement_x"];
            movement_y = _map[? "movement_y"];
            hp = _map[? "hp"];
            direction = _map[? "direction"];
            speed = _map[? "speed"];
            view_range = _map[? "view_range"];
            state = _map[? "state"]
        }
    }
#endregion

    
}

ds_map_destroy(_wrapper);
show_debug_message("Game Loaded")
instance_activate_all();
initialise = 0;
Thanks again for taking the time to look at this!
 
and the planetCredits displays as (size: -1) <invalid data structure>.
<invalid data structure> would suggest the data structure hasn't been created, or it was destroyed prior to you accessing it.

Are you sure planetCredits is a valid data structure?

Is there a reason you have commented out the line:

Code:
//planetCredits = ds_list_create();
Is that something you added as per my suggestion, but it didn't work so you commented it out?

If this line is commented out, can you confirm that you still have this code existing somewhere else? Because ds_copy requires that the list you are copying data to has already been created.

I had a look through the code. I don't notice anything else immediately out of place.

So bear with me a second.

When you create a data structure by calling ds_list_create(), it returns an integer value which represents a reference/index to that list, and you save that number into a variable.

So the first ds_list that gets created has an index of 0, the second ds_list has an index of 1 etc...

When you do a LoadJSONFromFile, its loading a map that contains a bunch of lists as well. Those lists will have their own indexes, for example if there are 6 lists in the map, their indexes will be from [0..5].

When you destroy the map, those lists in the map with indexes from [0..5] are destroyed.

Now, what I think might be happening is that you have declared the variable planetCredits = 0 maybe in your Create Event.

So when you call ds_copy(planetCredits, ... ), GMS tries to copy the data from the map to the list that has an index of 0. HOWEVER, as I mentioned above, the list that has an index of 0 actually exists already within the map! So then, the data is copied from the map list back into a list in the map (if that makes sense).

So finally, when you destroy the map, the list with the index of 0 ( which is in the map ) gets destroyed. And then it appears as if the planetCredits list has also been destroyed, because it had a value of 0 assigned to it as well.

You *must* assign a unique, new, fresh list to planetCredits via the ds_list_create() command before using the ds_copy() function.

This *may* be whats happening based on your above code. Let me know if I'm on the right track or you have already tried this.

I have spoken. (Mandalorian reference in case anyone hasn't watched the show yet)
 
C

Chris Livermore

Guest
Yes I have commented as I realised the reason I was not declaring it withing this script is because it was already being declared outside of the script.

I will have a run through all my code when I get home and make sure that I am not decalring a integar to it.

However Im pretty sure this is NOT the case as the load Script is called from a button within the game AFTER is has initialised the planetCredits list and actually filled it with Data.

it is worth noting however that when said button is clicked the Dslist is created again. maybe this is the problem. ill try just clearing all the data from it and report back .
 
C

Chris Livermore

Guest
OK im not sure after looking through all references of planetCredits on a search why its doing what its doing.

I have overcome the side effects by doing the following.

when my game is started it creates a Globalvar NewGameStarted.
this is then set to true.

I then do this on Load.

Code:
if NewGameStarted
{
    ds_list_destroy(planetCredits);
    planetCredits = ds_list_create();
    ds_list_destroy(DS_critter);
    DS_critter = ds_list_create();
    ds_grid_destroy(global.DroneSquadDetailsGrid);
    global.DroneSquadDetailsGrid = ds_grid_create(droneSquadGridWidth, 0);
    
}
I will fully get down to the bottom of the side effects as I prefer to understand why thing are not working a desired so next time I come accross the issue I can quickly (hopefully) resolve it.

thanks for your help IndianaBones and for explaining in detail the working.
 
C

Chris Livermore

Guest
OK this issue is still causing me a real issue.....

I am now trying to Load another load of Data insto a list.

Code:
var _list = _wrapper[? "CRITTERS"];
    CrittersLoaded = ds_list_create();
    ds_list_copy(CrittersLoaded, _list);
(I have had to do it this was having issues when Creating an object outside of a room and accessing its variables with a with statement).

so this then copys _list (which contains bout 30 Maps) into CrittersLoaded.

that all works Fine everything is loaded and works fine.
my issue is at the end of my Loading Script I am using :
Code:
ds_map_destroy(_wrapper);
to clean the main map away....

the SECOND it hits this line CrittersLoaded gets destroyed also.... But why dies it do this? I have bot reference the list at all have I!?

full Script code below (but I cant see anything else that would be effecting it in the code:

Code:
//objButtonCreation.Menu = true;

if GameStarted
{ // for each Critter, drone, planet that exists cycle through and kill them.
    instance_activate_all();
    //blank all Ds lists that we will be working into.
    ds_list_destroy(planetCredits);
    planetCredits = ds_list_create();
    
    instance_destroy(obj_enemy);//Destroy all Critters

    ds_list_destroy(DS_critter);
    DS_critter = ds_list_create();
    
    instance_destroy(objEnemyDrone);//Destroy all Drones
    ds_list_destroy(DS_drones); // NEW CODE WE NOW USE DS_DRONES
    DS_drones = ds_list_create();
    
    //ds_grid_destroy(global.DroneSquadDetailsGrid);  ###OLD CODE WE USED TO LOAD INTO DRONE DETAILS
    //global.DroneSquadDetailsGrid = ds_grid_create(droneSquadGridWidth, 0);
    
    ds_grid_destroy(playerInventory);
    playerInventory = ds_grid_create(playerInventoryWidth, 0);

}
var roomname = room_get_name(room) ;
    if room_get_name(room) != "Galaxy1"
    {
        room_goto(Galaxy1);
    }
loading = true;
globalvar planetsLoaded, planetsInventorysLoaded_Amounts, planetsInventorysLoaded_Names;
globalvar CrittersLoaded;
if (file_exists("SaveGame.sav"))
{
    show_debug_message("Loading Game");
    //TODO: goto room also need to save the current room on save.
    room_goto(Galaxy1);
    
    
    var _wrapper = LoadJSONFromFile("SaveGame.sav");
#region LOAD PLAYER
    var _list = _wrapper[? "PLAYER"];
    
    for (var i = 0; i < ds_list_size(_list); ++i)
    {
        var _map = _list[| i];

            var test = _map[? "x"]
            if test != undefined
            {
                //LOAD SHIP POSITION
                playerX = _map[? "x"];
                playerY = _map[? "y"];
                if player_craft != undefined
                {
                    player_craft.x = playerX;
                    player_craft.y = playerY;
                }
            }
            
            var test = _map[? "Credits"];
            if test != undefined
            {
                //LOAD ALL PLAYER DATA
                playerCredits = _map[? "Credits"];
                maxHP = _map[? "maxHP"];
                currentHP = _map[? "currentHP"];
                onFire = _map[? "onFire"];
                chanceOfFire = _map[? "chanceOfFire"];
                fireExtinguishers = _map[? "fireExtinguishers"];
                shield = _map[? "shield"];
                upgrade_Hull = _map[? "upgrade_Hull" ];
                upgrade_Booster = _map[? "upgrade_Booster"];
                upgrade_doubleGun = _map[? "upgrade_doubleGun"];
                upgrade_Laser = _map[? "upgrade_Laser"];
                maxShield = _map[? "maxShield"];
                shieldRegenTimer =  _map[? "shieldRegenTimer"];
                max_thrust = _map [? "max_thrust"];
                gun_maxCooldown = _map[? "gun_maxCooldown"];
                gun_cooldown = _map[? "gun_cooldown"];
                
            }
        test = undefined;
    }
    ds_list_destroy(_list);

#region LOAD PLAYER INVENTORY
    var _list = _wrapper[? "PLAYERINVENTORY"];
    for (var b = 0; b < ds_list_size(ds_list_find_value(_list,0)); ++b)
    {
        var _list1 = ds_list_find_value( ds_list_find_value(_list, 0),0);//Load List of names
        var _list2 = ds_list_find_value( ds_list_find_value(_list, 1),0);//Load list of amounts
        
        if ds_list_find_value(_list1, 0)!= undefined && is_string(ds_list_find_value(_list1, 0))
        {
        
            for (var a = 0; a< ds_list_size(_list1); ++a)
            {//iterate through each list in the list
                var details = ItemDetails(ds_list_find_value(_list1,a),0,0);
                scr_addItem(playerInventory, ds_list_find_value(_list1,a), ds_list_find_value(_list2,a), details[1], details[2], details[3], details[4], details[5])
            }
        }
    }
    
#endregion
    
    
    
    
#endregion
#region LOAD PLANETS
    var _list = _wrapper[? "PLANETS"];
    planetsLoaded = ds_grid_create(6,0);
    for (var i = 0; i < ds_list_size(_list); ++i)
    {
        var _map = _list[| i];
        var test = _map[? "obj"];
        
        if test != undefined && test = "planet"
        {   
            ds_grid_resize(planetsLoaded,6,ds_grid_height(planetsLoaded)+1);
            ds_grid_add(planetsLoaded, 0, ds_grid_height(planetsLoaded)-1,_map[? "x"]);
            ds_grid_add(planetsLoaded, 1, ds_grid_height(planetsLoaded)-1,_map[? "y"]);
            ds_grid_add(planetsLoaded, 2, ds_grid_height(planetsLoaded)-1,_map[? "name"]);
            ds_grid_add(planetsLoaded, 3, ds_grid_height(planetsLoaded)-1,_map[? "inventoryLocation"]);
            ds_grid_add(planetsLoaded, 4, ds_grid_height(planetsLoaded)-1,_map[? "repairCost"]);
            ds_grid_add(planetsLoaded, 5, ds_grid_height(planetsLoaded)-1,_map[? "image_blend"]);
        }
        test = undefined;
    }
//BELOW NEEDS WORK LOADS LIST with 2 INTERNAL LISTS wich contain 6 internal Lists. FIX SAVING
//or LOADING so we pull indevidual lists out of each of the 6 lists.
#endregion
#region LOAD PLANET INVENTORYS/CREDITS
    
    var _list = _wrapper[? "PLANETINVENTORYS"];
    planetsInventorysLoaded_Names = ds_grid_create(ds_list_size(ds_list_find_value(_list,0))+1,10);
    planetsInventorysLoaded_Amounts = ds_grid_create(ds_list_size(ds_list_find_value(_list,0))+1,10);
    for (var b = 0; b < ds_list_size(ds_list_find_value(_list,0)); ++b)
    {
        var _list1 = ds_list_find_value(ds_list_find_value(_list, 0),b);//first set of names
        var _list2 = ds_list_find_value(ds_list_find_value(_list, 1),b);//first set of amounts
    
        for (var item = 0; item< ds_list_size(_list1); ++item)
        {//iterate through each list in the list
            var debugtest = ds_list_find_value(_list1,item);
            ds_grid_add(planetsInventorysLoaded_Names,b,item,ds_list_find_value(_list1,item));
            ds_grid_add(planetsInventorysLoaded_Amounts,b,item,ds_list_find_value(_list2,item));
        }

    }
    
    //planetCredits = ds_list_create();
    ds_list_copy(planetCredits, _wrapper[? "PLANETCREDITS"]); // save planet Credits.     
#endregion
#region LOAD CRITTERS
    var _list = _wrapper[? "CRITTERS"];
    CrittersLoaded = ds_list_create();
    ds_list_copy(CrittersLoaded, _list);
    //for (var i = 0; i < ds_list_size(_list); ++i)
    //{
    //    var _map = _list[| i];
    //    //var Createdcritter = room_instance_add(Galaxy1,_map[? "x"], _map[? "y"],obj_enemy);
    //    //var Createdcritter = instance_create_layer(_map[? "x"], _map[? "y"],"Enemy", obj_enemy);
    //    ds_list_add(CrittersLoaded, ds_map_create());
    //    ds_map_copy(ds_list_find_value(CrittersLoaded,i), _map);
    //}
#endregion

#region LOAD DRONES (MY HOPE IS THE DRONE SCRIPT WILL HANDLE ALL THE SQUAD WORK)
    var _list = _wrapper[? "DRONES"];
    for (var i = 0; i < ds_list_size(_list); ++i)
    {
        var _map = _list[| i];
        var CreatedDrone = room_instance_add(Galaxy1,_map[? "x"], _map[? "y"],objEnemyDrone);
         ds_list_add(DS_drones, CreatedDrone);
        with (CreatedDrone)
        {
            movement_x = _map[? "movement_x"];
            movement_y = _map[? "movement_y"];
            hp = _map[? "hp"];
            direction = _map[? "direction"];
            speed = _map[? "speed"];
            view_range = _map[? "view_range"];
            state = _map[? "state"]
            squad = _map[? "squad"];
        }
        
    }
    
    
    
    
#endregion

    
}

ds_map_destroy(_wrapper);
show_debug_message("Game Loaded")
instance_activate_all();
initialise = 0;
GameStarted = true;
Im completely at a loss with this now... it seems every time I try to copy over the data (even if I iterate through the Data with a for loop) the second it hits that Ds_map_Destroy at the end of the code the whole thing just unloads....


thanks for takign the time to look at this and if you help solve it ill hunt you down and kiss you (as iv spent all day trying to get this sorted...)
 
C

Chris Livermore

Guest
just for reference this is what I have also tried:

Code:
var _list = _wrapper[? "CRITTERS"];

for(var i = 0; i < ds_list_size(_list); ++i)
{
var _map = _list[| i];
ds_list_add(CrittersLoaded, ds_map_create());    ds_map_copy(ds_list_find_value(CrittersLoaded,i), _map);

}
 
C

Chris Livermore

Guest
OK SOLVED it!

Im still not sure why it was happening.

but sor some reason having theScript Declare
Code:
globalvar CrittersLoaded
made it get destroyed.

I instead Declared the global var in my initialisation code and it seems to now be stable.

If anyone can explain the Logic behind that?
 
Glad to hear it seems to be working for you now.

I honestly have no idea what *exactly* is causing that. Still just the general suggestion the ds_list indexes were overlapping somehow.

At this point, if I still wanted to figure out what was going on, I would be using the debugger to step through the code and checking the values of all my ds_list indexes.

I would also be sprinkling liberal amounts of show_debug_messages() printing out the states of the lists, and perhaps drawing their values on screen so i could see what was happening in real time.
 
C

Chris Livermore

Guest
Glad to hear it seems to be working for you now.

I honestly have no idea what *exactly* is causing that. Still just the general suggestion the ds_list indexes were overlapping somehow.

At this point, if I still wanted to figure out what was going on, I would be using the debugger to step through the code and checking the values of all my ds_list indexes.

I would also be sprinkling liberal amounts of show_debug_messages() printing out the states of the lists, and perhaps drawing their values on screen so i could see what was happening in real time.

lets just say my F11 button is very warn out... stil I cant figure it out. the second that it kills the DS map it had issues. I just declared all my Lists and DS grids that are global in my initialisation script and that seems to have fixed the issue.
 
Top