SOLVED Player spawning to wrong x,y position upon loading

kbuell5

Member
This is my first forum post here, so if I neglect to put any important code please tell me and I'll try to include what's needed.
I'm working in GameMaker v1.4.1804. I've followed Shaun Spalding's JSON based save/load tutorials and I'm run into a problem. Whenever I load my game, when I go to the room that I last saved in, the player object spawns in a fixed location every time that is not the x,y values I stored when I saved. No matter what value I've actually saved to my JSON file, the player spawns in the same wrong place every time. I've used debug messages and made sure that the values I'm saving are saving properly. There just seems to be something wrong with the actual loading process, or possibly something happening when the room starts, although they don't have any creation code. I'm loading from a menu room that's separate from the room I've saved in.
Here is my code for my loading script (I've put it all because I don't know how much to include):
GML:
with (obj_player) instance_destroy();
var party_grid = global.ds_party;

if (file_exists("savedgame.sav"))
{
    var _wrapper = scr_loadJSONFromFile("savedgame.sav");
    var _list = _wrapper[? "ROOT"];
    
    for (var i = 0; i < ds_list_size(_list); i++)
    {
        var _map = _list[| i];
        
        var _obj = _map[? "obj"];
        
        with (instance_create(0,0,asset_get_index(_obj)))
        {
            room_goto(_map[? "room"]);
            x = _map[? "x"];
            y = _map[? "y"];
            show_debug_message("X,Y Coords LOADED as: " + string(_map[? "x"]) + ", " + string(_map[? "y"]));
            show_debug_message("Player X,Y: " + string(x) + ", " + string(y));
            party_grid[# 0,0] = _map[? "name"];
            party_grid[# 1,0] = _map[? "hp"];
            party_grid[# 2,0] = _map[? "hpMax"];
            party_grid[# 3,0] = _map[? "xp"];
            party_grid[# 4,0] = _map[? "xpMax"];
            party_grid[# 5,0] = _map[? "lvl"];
            party_grid[# 6,0] = _map[? "status"];
            party_grid[# 7,0] = _map[? "inParty"];
            global.money = _map[? "money"];
            global.playerDown = _map[? "downSprite"];
            global.playerLeft = _map[? "leftSprite"];
            global.playerRight = _map[? "rightSprite"];
            global.playerUp = _map[? "upSprite"];
            image_index = _map[? "image_index"];
        }
    }
    
    show_debug_message("Player x,y (2nd time): " + string(x) + ", " + string(y));
    ds_map_destroy(_wrapper);
    show_debug_message("Game Loaded");
    
}
I'm almost positive the bug doesn't have anything to do with my save script. Everything else saves and loads fine. My character object is persistent. I don't have an instance in it placed in the room creator menu thing, so it's not that that's overriding it. I've tried so many things and I'm at a loss. I have a feeling the solution is simple and I'm missing it.

Here's what it looks like when I load.
saved loaded positions.jpg
 

chamaeleon

Member
What relevance are the x and y coordinates of the instance that is executing this script? If it is the player object, what correlation this that preexisting instance have with the x and y coordinates being assigned for created instances in the for loop? In short, there's nothing that assigns x and y for the instance executing this code, so no change would be made to it. If it's not the player instance, why bother displaying its coordinates as it if is? I assume you understand the implication of using with() and how instance variables inside the code block for it refers to the instance variables of the argument to it, not the instance that calls with().
 

kbuell5

Member
What relevance are the x and y coordinates of the instance that is executing this script? If it is the player object, what correlation this that preexisting instance have with the x and y coordinates being assigned for created instances in the for loop? In short, there's nothing that assigns x and y for the instance executing this code, so no change would be made to it. If it's not the player instance, why bother displaying its coordinates as it if is? I assume you understand the implication of using with() and how instance variables inside the code block for it refers to the instance variables of the argument to it, not the instance that calls with().
I think I understand what you're saying. I do understand the with() stuff, I had just assumed that the argument was something else, it must have slipped my mind in the moment. I've changed the bits that just refer to x and y to refer to obj_player.x and obj_player.y, and that seems to have done something. In my debug, the 2nd time I print the player's coordinates, those are now correct, as they were printing incorrectly before. However, the player still spawns in at that wrong fixed position.
 

Nidoking

Member
Is the player instance persistent? Because you're setting the positions of all of the instances in the room where you're loading, then changing to the new room at the end of the step. All of the non-persistent instances you just loaded will be destroyed, and whatever is normally in the room you loaded will be there instead. You'd need to do the room transition first, then create instances in the next step.

Also, you're doing a room_goto for every instance you create. Instances don't move from room to room like that. Only the game does.
 

kbuell5

Member
You'd need to do the room transition first, then create instances in the next step.
Ok, that makes sense. I’ve put the room_goto line outside of the with() now, right below where I define var _obj, but that didn’t do anything to fix the problem, so I think I’m still putting it in the wrong place?
My player object is persistent, but I don’t really know where the fixed coordinates it’s being spawned in came from.
 

chamaeleon

Member
Ok, that makes sense. I’ve put the room_goto line outside of the with() now, right below where I define var _obj, but that didn’t do anything to fix the problem, so I think I’m still putting it in the wrong place?
My player object is persistent, but I don’t really know where the fixed coordinates it’s being spawned in came from.
Does it make sense for your game to create a bunch of instances using instance_create() before calling room_goto() later in the script? Are all the objects you iterate over as stored in [_map[? "obj"] persistent as well? If not, they'll get destroyed right away, as the current room where they are created goes away and the next room you go to is populated with instances as defined for it (in addition to persistent instances).
 

TheouAegis

Member
Create a normal variable to hold the file ID in your persistent control object, set it to -1 by default. Open the INI file and save its ID to a normal variable inside your persistent control object. If the room you need to go to is saved in the file, retrieve that first, then go to the room. In the Room Start event of your control object, check if the variable holding the file ID is >-1 and if it is, load the rest of the data, then close the file, then set the variable to -1.
 

kbuell5

Member
Create a normal variable to hold the file ID in your persistent control object, set it to -1 by default. Open the INI file and save its ID to a normal variable inside your persistent control object. If the room you need to go to is saved in the file, retrieve that first, then go to the room. In the Room Start event of your control object, check if the variable holding the file ID is >-1 and if it is, load the rest of the data, then close the file, then set the variable to -1.
I'm not using INI files, I'm using JSON. From what I've heard JSON is better to prevent tampering with data on the player end, so that's why I've chosen it. I'm not sure if that would work for what I'm trying to do. The room is loading properly, I'm just somehow spawning the player object in the wrong coordinates in the room.
 

kbuell5

Member
Does it make sense for your game to create a bunch of instances using instance_create() before calling room_goto() later in the script? Are all the objects you iterate over as stored in [_map[? "obj"] persistent as well? If not, they'll get destroyed right away, as the current room where they are created goes away and the next room you go to is populated with instances as defined for it (in addition to persistent instances).
All of the objects are persistent, it's actually just my player object. I followed Shaun's tutorial, and he had it written that way to incorporate the saving/loading of multiple objects, but I only have one at the moment. Is the problem I'm having related to where I put the room_goto() in the script? I've moved it around a whole bunch and I haven't fixed the issue. For some reason I can't find any tutorials online for loading a player to a specific location in a specific room.
I apologize if I seem stupid, I've been stuck for days and I'm afraid I'm looking over a basic concept accidentally. I'm new to saving and loading.
 

kbuell5

Member
Alright, I've fixed my problem! Turns out it had nothing to do with my saving and loading at all. I have an object for room transitions that put the player at the designated x and y coordinates every time a room started. This was for my door system. Only thing is, it ran whenever a room started at all, not just when the player came through a door. It was spawning the player at the last saved door's target x and y values every time I loaded.

Thanks so much for all your help!!
 
Top