GameMaker Save & Load Arrays Problem

I'm having issues with the save & load system in Shaun Spalding's RPG series...

Shauns video.

Code:
Save Script:
GML:
function save_game()
{
    var _map  = ds_map_create();

    //Inventory
    _map[? "Inventory"] = global.Inventory;
    _map[? "bombs"]   = global.bombs;
    _map[? "arrows"]  = global.arrows;

    //Save All Intfo in a string
    var _string = json_encode(_map);
    save_string_to_file("save" + ".sav",_string);
    show_debug_message(_string);

    //Nuke the data
    ds_map_destroy(_map);
    show_debug_message("Game saved!");
}

function save_string_to_file(_filename,_string)
{
    var _buffer = buffer_create( string_byte_length(_string)+1,buffer_fixed,1);
    buffer_write(_buffer,buffer_string,_string);
    buffer_save(_buffer,_filename);
    buffer_delete(_buffer);
}
Load Script:
GML:
function load_game()
{
    var _file = "save" + ".sav";
    if (file_exists(_file))
    {
    //Load game data
    var _json = load_json_from_file(_file);

    //Inventory
    global.Inventory = _json[? "Inventory"];
    global.arrows = _json[? "arrows"];
    global.bombs = _json[? "bombs"];

    return true;
    }
    else
    {
    return false;
    }
}

function load_json_from_file(_filename)
{
    var _buffer = buffer_load(_filename);
    var _string = buffer_read(_buffer, buffer_string);
    buffer_delete(_buffer);
    var _json = json_decode(_string);
    return _json;
}
Problem: I have an inventory, which uses arrays. global.Inventory = [ obj_apple, -1, -1], something like that. But when the inventory value is saved, then loaded, Inventory = 0, it's not an array anymore, just a singel number.

Any help would be appreciated.
With love, Philip.
 

chamaeleon

Member
Dont mix and match the use of ds_map/ds_list with struct/array for the purposes of json encoding and decoding, it will not end well, they are not compatible in this regard. I suggest you pick struct and arrays and stop using ds_map and ds_list unless absolutely necessary.
 
Ok, I see. Maybe I should convert the inventory array to a ds_map before saving, then make it back into an array in the load script. Would that perhaps be a solution?
 
Dont mix and match the use of ds_map/ds_list with struct/array for the purposes of json encoding and decoding, it will not end well, they are not compatible in this regard. I suggest you pick struct and arrays and stop using ds_map and ds_list unless absolutely necessary.
Ok, I see. Maybe I should convert the inventory array to a ds_map before saving, then make it back into an array in the load script. Would that perhaps be a solution?
 

chamaeleon

Member
Or you could write
GML:
function save_game()
{
    var _map  = { };

    //Inventory
    _map[$ "Inventory"] = global.Inventory;
    _map[$ "bombs"]   = global.bombs;
    _map[$ "arrows"]  = global.arrows;

    //Save All Intfo in a string
    var _string = json_stringify(_map);
    save_string_to_file("save" + ".sav",_string);
    show_debug_message(_string);

    //Nuke the data
    show_debug_message("Game saved!");
}

function save_string_to_file(_filename,_string)
{
    var _buffer = buffer_create( string_byte_length(_string)+1,buffer_fixed,1);
    buffer_write(_buffer,buffer_string,_string);
    buffer_save(_buffer,_filename);
    buffer_delete(_buffer);
}
GML:
function load_game()
{
    var _file = "save" + ".sav";
    if (file_exists(_file))
    {
    //Load game data
    var _json = load_json_from_file(_file);

    //Inventory
    global.Inventory = _json[$ "Inventory"];
    global.arrows = _json[$ "arrows"];
    global.bombs = _json[$ "bombs"];

    return true;
    }
    else
    {
    return false;
    }
}

function load_json_from_file(_filename)
{
    var _buffer = buffer_load(_filename);
    var _string = buffer_read(_buffer, buffer_string);
    buffer_delete(_buffer);
    var _json = json_parse(_string);
    return _json;
}
 

FrostyCat

Redemption Seeker
Ok, I see. Maybe I should convert the inventory array to a ds_map before saving, then make it back into an array in the load script. Would that perhaps be a solution?
That is completely unnecessary. Just forget about DS maps and DS lists already, and use structs and arrays.
GML:
function save_game()
{
    //Inventory
    var _strc = {
        Inventory: global.Inventory,
        bombs: global.bombs,
        arrows: global.arrows,
    };

    //Save all info in a string
    var _string = json_stringify(_strc);
    save_string_to_file("save.sav",_string);
    show_debug_message(_string);

    show_debug_message("Game saved!");
}

function save_string_to_file(_filename,_string)
{
    var _buffer = buffer_create( string_byte_length(_string)+1,buffer_fixed,1);
    buffer_write(_buffer,buffer_string,_string);
    buffer_save(_buffer,_filename);
    buffer_delete(_buffer);
}
GML:
function load_game()
{
    var _file = "save.sav";
    if (file_exists(_file))
    {
        //Load game data
        var _json = load_json_from_file(_file);

        //Inventory
        global.Inventory = _json.Inventory;
        global.arrows = _json.arrows;
        global.bombs = _json.bombs;

        return true;
    }
    else
    {
        return false;
    }
}

function load_json_from_file(_filename)
{
    var _buffer = buffer_load(_filename);
    var _string = buffer_read(_buffer, buffer_string);
    buffer_delete(_buffer);
    var _json = json_parse(_string);
    return _json;
}
For the information, Shawn Spalding's tutorial used DS maps and DS lists not because they are good, but because it is a tutorial predating GMS 2.3.0. You have been following an obsolete tutorial to begin with, and I am sick of him herding rookies into muddling modern structs+arrays with legacy maps+lists over the past 2 years.
 
That is completely unnecessary. Just forget about DS maps and DS lists already, and use structs and arrays.
GML:
function save_game()
{
    //Inventory
    var _strc = {
        Inventory: global.Inventory,
        bombs: global.bombs,
        arrows: global.arrows,
    };

    //Save all info in a string
    var _string = json_stringify(_strc);
    save_string_to_file("save.sav",_string);
    show_debug_message(_string);

    show_debug_message("Game saved!");
}

function save_string_to_file(_filename,_string)
{
    var _buffer = buffer_create( string_byte_length(_string)+1,buffer_fixed,1);
    buffer_write(_buffer,buffer_string,_string);
    buffer_save(_buffer,_filename);
    buffer_delete(_buffer);
}
GML:
function load_game()
{
    var _file = "save.sav";
    if (file_exists(_file))
    {
        //Load game data
        var _json = load_json_from_file(_file);

        //Inventory
        global.Inventory = _json.Inventory;
        global.arrows = _json.arrows;
        global.bombs = _json.bombs;

        return true;
    }
    else
    {
        return false;
    }
}

function load_json_from_file(_filename)
{
    var _buffer = buffer_load(_filename);
    var _string = buffer_read(_buffer, buffer_string);
    buffer_delete(_buffer);
    var _json = json_parse(_string);
    return _json;
}
For the information, Shawn Spalding's tutorial used DS maps and DS lists not because they are good, but because it is a tutorial predating GMS 2.3.0. You have been following an obsolete tutorial to begin with, and I am sick of him herding rookies into muddling modern structs+arrays with legacy maps+lists over the past 2 years.
Thanks for the advice, as I said it's appreciated. But there is no need to be rude, I simply didn't find someone with a similar problem. But as I said, thanks!
 
Top