GameMaker Saving a ds_grid in a ds_map

MeltingCat

Member
Hi, I'm having trouble saving my inventory system in a ds_map as part of a JSON.

I found this thread:
https://forum.yoyogames.com/index.php?threads/adding-a-ds-grid-to-a-ds_map.50573/
where the answer to my question seems to be written, but I can't make it work.
As of lack of experience I believe I might just not get the correct syntax for it.
I've been trying multiple ways to use ds_grid_read/write correctly.

saving:
Code:
ds_map_add(_Map, "InventoryBox", ds_grid_write(Box))
loading:

Code:
ds_grid_read(Box, _Map[? "InventoryBox"])
is there something else to it?
thanks in advance!
 
D

Danei

Guest
It might help if you post more of your saving and loading code, and the text of an error message if you're getting one. Based on what you posted so far, I can't tell whether you're creating the ds_map named _Map before adding to it, or creating the ds_grid named Box before reading into it, or how/if you are encoding and decoding the map, or what happens instead of proper saving and/or loading when you try it.
 
Last edited by a moderator:

MeltingCat

Member
in the create event of o_Inventory:
Code:
Box = ds_grid_create(Width, Height)

ds_grid_clear(Box, Item.None)
...then there are items added...

saving:
Code:
var _RootList = ds_list_create()
with o_SaveObject {
   
    var _Map = ds_map_create()
    ds_list_add(_RootList, _Map)
    ds_list_mark_as_map(_RootList, ds_list_size(_RootList)-1)
    if _Object == o_Inventory {
              ds_map_add(_Map, "InventoryBox", ds_grid_write(Box))
    }
}

//store the root list in a map
var _Wrapper = ds_map_create()
ds_map_add_list(_Wrapper, "Root", _RootList)

//wrap the root list in a string
var _String = json_encode(_Wrapper)
Save_String_To_File("SavedGame", _String)

//destroy the data
ds_map_destroy(_Wrapper)
loading:

Code:
if file_exists("SavedGame") {
   
    var _Wrapper = Load_JSON_From_File("SavedGame")
    var _RootList = _Wrapper[? "Root"]
   
    var _GameMap = _RootList[| 0]
   
    with o_SaveObject instance_destroy()

     for (var _i = 1; _i < ds_list_size(_RootList); _i++) {
       
        var _Map = _RootList[| _i]
       
        var _Object = _Map[? "Object"]
        with (instance_create_layer(0, 0, "Instances", asset_get_index(_Object))) {
           
            if _Object == o_Inventory {
               
                ds_grid_read(Box, _Map[? "InventoryBox"])
            }
        }
    }
   
    ds_map_destroy(_Wrapper)
   
}
 
D

Danei

Guest
Hmm, if Box is an instance variable inside o_Inventory, and saving takes place within o_SaveObject, you need to use dot notation to access that variable.

When you save, try

Code:
ds_map_add(_Map, "InventoryBox", ds_grid_write(o_Inventory.Box))
This assumes that there's only one instance of o_Inventory. If there's more than one you'll want to capture each one's instance ID instead of using the object index like I did just now.

It looks like your ds_grid_read is already taking place inside o_Inventory, so if this is the issue, probably that part doesn't need to change.
 

Ido-f

Member
In the saving part you're creating a map for each instance of o_SaveObject and its childs, but you're not adding anything to that map.
Except when _Object == o_Inventory: but where is that _Object variable being defined?
I'd guess you're defining it before entering the "with" loop, which means it keeps the same value for each running instance, and if that value isn't o_Inventory, the grid would never be saved to any map.

Also, when loading the data, you're trying to define a new _Object local variable using an "Object" key in the map, but you haven't set any keys to any maps before saving them, at least not in the code you posted here.

I'd work with the built in instance variable object_index instead of _Object in your saving code.
It's also needed to save the object_index as a string using object_get_name in order to work properly with asset_get_index, that expects a string.

Add this code in the saving "with" loop:
Code:
_Map[? "Object"] = object_get_name(object_index);
Also in the saving section, change "if _Object == o_Inventory" into "if object_index == o_Inventory" (no quotation marks because we're working with indexes)

And in the loading section, change "if _Object == o_Inventory" into "if _Object == "o_Inventory" " (quotation marks because we're working with strings)

If something's still not working after that, please explain where it fails and post any error messages.
 
Last edited:

MeltingCat

Member
I'm sorry I forgot a relevant line of code:
Code:
    var _Object = object_get_name(object_index)
    ds_map_add(_Map, "Object", _Object)
that was of course necessary. This is within the with loop after creating _Map for each o_SaveObject.

But you were right, here was my mistake:

Also in the saving section, change "if _Object == o_Inventory" into "if object_index == o_Inventory" (no quotation marks because we're working with indexes)

And in the loading section, change "if _Object == o_Inventory" into "if _Object == "o_Inventory" " (quotation marks because we're working with strings)
I missed that the function object_get_name returns a string and I didn't refer to it correctly, so adding the quotation marks worked great!
Thank you very much for your help, it's working awesome!
 
Top