GMS 2 [SOLVED] Problem using ds map to save game.

tibbycat

Member
Hi, I'm still a newbie with programming but I'm trying to understand how to use data structures (ds maps specifically) to save where my player is in the platform game I'm making.

I've been using @Pixelated_Pope's code from his DS Map Based Save System video which works perfectly for saving to remember when the player has picked up the money objects, but I can't work out how to modify it to remember where the x and y positions of where my player was when saving, or to remember other global variables such as the player's lives and money obtained so far.

For the money object, I have on the Create Event:

Code:
key=scr_save_data_get_key();

var _save_data = ds_map_find_value(obj_game_setup.save_data,key);
if(!is_undefined(_save_data) && _save_data==true)
{
    instance_destroy();
}
The script for the key is:

Code:
///scr_save_data_get_key
return room_get_name(room)+object_get_name(object_index)+string(x)+string(y);
and back on the money object, there's a Collision Event with the player that contains:

Code:
global.money += 50;
ds_map_replace(obj_game_setup.save_data,key,true);
instance_destroy();
That works perfectly for remembering which money objects have been taken (although not for remembering the value of global.money when loading the game).

The control object there is obj_game_setup which contains in its Create Event:

Code:
//Save data
save_data=ds_map_create();
ds_map_replace(save_data,"Current Room",room_get_name(room));
file_name="SaveData.sav";
and on its Room Start Event is:

Code:
//Update current room
ds_map_replace(save_data,"Current Room",room_get_name(room));
That works to remember which room the player saved from (but not the x and y coordinates).

The game is saved from the following script:

Code:
///Save game
with(obj_game_setup)
{
    ds_map_secure_save(save_data,file_name);
}
Which is called from Friendly Cosmonaut's dialogue system when the player speaks to the relevant NPC:



That works perfect in calling the relevant script.

The game is loaded from the menu object (obj)in the menu room (the second room in the game as the first room is an initialization room where the permanent control object obj_game_setup is placed) that contains the following switch statement to start a new game, load the game saved, or to quit the game:

Code:
switch (menu_committed)
    {
        case 2: default: room_goto_next(); break;
        case 1: scr_load(); break;
        case 0: game_end(); break;
    }
That load script it calls is this:

Code:
with (obj_game_setup)
{
    if(!file_exists(file_name))
        exit;
        
    ds_map_destroy(save_data);
    save_data=ds_map_secure_load(file_name);
    
    var _room=ds_map_find_value(obj_game_setup.save_data,"Current Room");
    if(!is_undefined(_room) && room_get_name(room) != _room)
    {
        if !instance_exists(obj_player)
        {
            instance_create_layer(x,y,"Player",obj_player);
        }
        room_goto(asset_get_index(_room));
    }
    else
        room_restart();
}
When loading the game, the player appears in the correct room, but not at the same x and y coordinates where the game was saved. I'm guessing this is because the player's x and y coordinates were never saved in the ds map (as well as other key variables such as global.money and global.lives)?

Is there any way I can modify this to save these values? I've been reading the manual and looking at tutorials but I can't get my head around the logic and syntax I need to modify this system to add the player's x and y coordinates or other important values to be saved. Do I need to add something to the player object (obj_player) to reference the ds map on the control object (obj_game_setup)?

Thanks for any help anyone can provide for me here. :) I hope this wasn't too much of a wall of text I've written here. :p

I'm using GameMaker Studio 2, IDE version 2.2.4.495.
 
  • Wow
Reactions: Mut

tibbycat

Member
I found the solution myself. After some experimentation it wasn't too difficult to modify @Pixelated_Pope's code to save other values.

It might be a bit clumsy with some redundant code, but it works.

On my control object I have in the Create Event:

Code:
//Save data
save_data=ds_map_create();
ds_map_replace(save_data,"Current Room",room_get_name(room));
ds_map_replace(save_data,"life",global.life);
ds_map_replace(save_data,"money",global.money);

file_name="SaveData.sav";
(as well as other variables to save the game progress after that)

And then in the Room Start Event on the same control object I have:

Code:
//Update current room
ds_map_replace(save_data,"Current Room",room_get_name(room));
ds_map_replace(save_data,"life",global.life);
ds_map_replace(save_data,"money",global.money);
as well as the other global variables to save flagged events in the game that have to be remembered.

Then when the save script is called from the conversation with the NPC character, the save script contains:

Code:
///Save game
with(obj_game_setup)
{
    ds_map_replace(save_data,"x",obj_player.x);
    ds_map_replace(save_data,"y",obj_player.y);
    ds_map_secure_save(save_data,file_name);
}
show_debug_message("Game saved!");
I was struggling to know where to save the player's x and y coordinates, but that worked putting that there.

And lastly the load script that's called from the game menu at the start of the game contains:

Code:
with (obj_game_setup)
{
    if(!file_exists(file_name))
        exit;
     
    ds_map_destroy(save_data);
    save_data=ds_map_secure_load(file_name);
    show_debug_message("Game loaded");
 
    var _room=ds_map_find_value(obj_game_setup.save_data,"Current Room");
    global.life = save_data[? "life"];
    global.money = save_data[? "money"];

    if(!is_undefined(_room) && room_get_name(room) != _room)
    {
        if !instance_exists(obj_player)
        {
            instance_create_layer(x,y,"Player",obj_player);
            obj_player.x = save_data[? "x"];
            obj_player.y = save_data[? "y"];
        }
        room_goto(asset_get_index(_room));
    }
    else
        room_restart();
}
as well as the other global variables in there to save flagged events in the game that have to be remembered (I've cut them out of this post here, but they work).

I guess my lesson is, when stuck, persevere, and you'll get it, eventually, probably.

However, I'm scratching the surface on my understanding of data structures. I feel like someone who knows how to drive a car being given the keys to a plane and hoping that I don't crash it.

Anyway, it works. :)
 
Top