• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker Saving global variable

B

batmanai15

Guest
hey all

Just had a quick question on saving global variables to an ini file.

I have some global variables that every play session they will be a different value. So during a session if there is a save I need to capture the value of those variables for the load game to work properly.

Let say the global variables is called:

Global.from_room

When saving that to an ini file would I write that as:

ini_write_real("savegame", "variable”, from_room);
Or
ini_write_real("savegame", "variable", global.from_room);

Thanks
 

Ralucipe

Member
If you ever define a variable as global, by using the "global." prefix, then you'll always need to reference the variable with that same prefix, no matter what you're referencing it for. So yes, use "global.from_room", as using just "from_room" would throw a runtime error (because the instance variable from_room is not defined, but the global variable from_room is defined.)
 
B

batmanai15

Guest
Awesome thanks much. Also when I load that would it be:

Global.from_room = ini_read_real(“savegame”, “variable”, “”);
 
B

batmanai15

Guest
This is not working. When I look at the ini file the global variables are numbers when they should be a room name
 
This is not working. When I look at the ini file the global variables are numbers when they should be a room name
You appear to be writing and reading them into and out of your file as reals, so therefore they are numbers. Which to me makes sense if you are trying to save and load what room was last in (as this would be the index of the room, not the name). You're going to have to show us how you allocate something to global.from_room when you are wanting to save. It is probable that you are saving the room index. If you are wanting to save the room name, then you need to translate the index into the room name and then use ini_write_string and ini_read_string instead.
And after loading you would then have to translate the room name back into the index again to do any sort of goto operation on it (if that is what you are doing).
 
B

batmanai15

Guest
Ok what I am doing is I have a collision set up with a non visible object. The collision code picks a random room (out of a list) and assigns the room name to a global variable. Then it moves the player to that room at set x and y coordinates. The reason why I save the room to a global variable is so if the player back tracks I know what room they were picked so I can send them back to the same room.

So because of this that variable can change values every game session.

The save file is a checkpoint and is deleted on player death.

What I need though is to save that global variable so the script knows what room they have visited.

I tried saving the global variable as a string and that still produces a number and not what the variable is which is a room name.
 
I tried saving the global variable as a string and that still produces a number and not what the variable is which is a room name.
Show us how you are assigning to that variable. So far you have said that you are assigning the room name to the variable, but have not shown that to us yet. If the variable had a string/name in it and you used write_string/read_string then it would save and load the string - but if it is still a number, then it looks like you are storing a number into the variable.

Show us the code for how you assign the room name into the global variable, and then we can take things from there.
 
B

batmanai15

Guest
Ok here is the code for the room transition which takes place in a collide event of the player with non visible object in the doorway
Code:
if global.VisitedA = W1_R1_TA_GA { //if variables are not yet assigned you go to the random_room part of the code
    room_goto(global.VisitedA);   
    x=68;
    y=126;
    } else if room=global.VisitedA and x<200 {
    room_goto(W1_Starting_Room) //code to go back to the previous room 
    
    }

    if global.VisitedA = W1_R2_TA_GA {
    room_goto(global.VisitedA);   
    x=68;
    y=126;
    } else if room=global.VisitedA and x<200 {
    room_goto(W1_Starting_Room) //back to the previous room if you collide again
    
    }
    
    //if first time entering room, the room is randomly chosen and assigned to the Group A variables for above code
    if global.VisitedA = noone {
    var random_room = choose (W1_R1_TA_GA, W1_R2_TA_GA) //all of the possible rooms in Group A
    global.VisitedA = random_room;
   
    
    room_goto(random_room);
    x=68;
    y=126;
    invincible_ = true;
    alarm[3] = global.one_second *0.75;
    } else if room=global.VisitedA and x<200 { //if not in the starting room execute this part of the code
    room_goto(W1_Starting_Room)
    //do not need x and y values for starting room as there's a global start in the code for this room
}
Now the code to save the global.VisitedA variable is:
Code:
ini_open("variable_save.ini");
ini_write_string("Level", "VisitedA", global.VisitedA);
ini_close();
and to open the save file

Code:
ini_open("variable_save.ini")
global.VisitedA = ini_read_string("Level", "VisitedA", "");
ini_close();
i have other code in the ini save file like the player position and object of the player and the room.
 
You are not storing the name of the room into global.VisitedA. You are storing the index to the room - exactly as you are seeing. You have nothing in that code which translates the room index to be the room name.

Whenever you reference a room using the resource name from the project, eg: global.VisitedA=choose(W1_R1_TA_GA, W1_R2_TA_GA), you are not storing the string "W1_R1_TA_GA" or "W1_R2_TA_GA". You are storing the index (which is an internal number) that references that resource in the project.

So the fact you are seeing a number in your global.VisitedA is perfectly correct, and is probably exactly how you should be using it. Otherwise you would need to take that value, use one of the *_name functions to get the actual name of the room, then save that, and when loading it back you would then need to translate that name back into the index once again. For what you are trying to do, you shouldn't have to do all of that. Just allow it to store the index, and not the name - because you don't need the name.
 
B

batmanai15

Guest
So now i'm confused, sorry. How do i store the index of the room? What would be the easiest way to assign that global variable so it knows what room its pointing too? For some reason this is one area i'm struggling with so i appreciate the help.

So as I understand. Even though my code is referencing the resource name of the room behind the scene it's actually using and storing the index.....If that's the case then why is the INI not saving it as index and even assigning it the index on load.....
 
So now i'm confused, sorry. How do i store the index of the room?
You already are. When you look at the resource tree and you see the names there, if you reference those in any code you are not actually referencing the name. Everything you reference in code: spr_player, obj_plater, room_room1, etc. is making actually using the index of the item.
An index is just a number, it is behind-the-scenes of how resources are handled.
What would be the easiest way to assign that global variable so it knows what room its pointing too?
You are already doing it. By doing:
Code:
global.VisitedA = choose(W1_R1_TA_GA, W1_R2_TA_GA);
You are choosing a room from one of those two resources and storing the index of that chosen room into global.VisitedA. This is why you were seeing a number in your variable and INI file.
So as I understand. Even though my code is referencing the resource name of the room behind the scene it's actually using and storing the index.....
That is correct.
.If that's the case then why is the INI not saving it as index and even assigning it the index on load
I'm sure you said earlier on that it was saving a number, so that would have been the index:
When I look at the ini file the global variables are numbers when they should be a room name
 
B

batmanai15

Guest
Then why doesn’t the code work when I load the save. The collision does not make me change rooms. I can go back and forth to rooms when I play the game but once I load the game nothing happens when I get to the door. It’s like the variable is not assigned. That’s why I’m confused.
 
Are you able to confirm that the loading does set global.VisitedA? I would normally start with some show_debug_message calls to confirm what bit of your code is being run, and to confirm the values that are in specific variables. Alternatively you can use the debugger (although I still just use the messages to find what is going on).

Perhaps global.VisitedA is being reset somewhere, even if it has been loaded.
 
B

batmanai15

Guest
I only confirmed what was being saved by looking at the ini file itself. I will do a search to make sure the variable is not being reset somewhere else.

It sounds like my code is correct and I’m saving the variable. It’s just the loading in question. Is there anything else I need to save as well? I made the non visible object that has the actual code in it for the collision to a visible object and can confirm that is there. So it’s the variable not getting re assigned.
 

Tony Brice

Member
Classic scenario would be that you're loading the file with the saved variable before you run the code that resets the variable in the first place.
 
B

batmanai15

Guest
The save is def being executed after the variable is assigned the room.
 
B

batmanai15

Guest
I GOT IT TO WORK!!!!!

Ok so I re wrote the entire room transition code. I had way to much going on and it was over complicated. So now the transition code is simply this:

Code:
if global.GroupA != noone {
    room_goto(global.GroupA)
    x=68;
    y=126;
}

if global.GroupA = noone {
global.GroupA = choose (W1_R1_TA_GA, W1_R2_TA_GA);
room_goto(global.GroupA);
x=68;
y=126;
}
This assigns the global.GroupA variable to a random room in the list. If the global variable equals noone then i tell the script to assign it (for the first time visiting the room). If it does not equal noone that means it has a value and i want to go to the value it has. I return to the same room.

In my save file i just save the global.GroupA variable like i was doing above.

Now when i load the game the variable is still assigned to the visited room and it's working GREAT!!!

Big thanks to you BaBia. I appreciate how you did not give me the answer but made me think and figure it out. I learned a great deal about INI files and saving. Also as a part of this exercise i completely optimized my random room transition code!!

Thanks.
 
Good to hear that you got it all sorted out.
If you wanted to optimise your code even more, you could reduce it a little bit more as you do still have some duplicate lines.
I think you could trim it down to this, and it should still do what you are wanting it to:
Code:
if (global.GroupA == noone) {
  global.GroupA = choose (W1_R1_TA_GA, W1_R2_TA_GA);
}

room_goto(global.GroupA);
x=68;
y=126;
It's a bit shorter as you are always going to the same x/y coordinates no matter which room you are going to, and you would only need to choose a room for global.GroupA if it doesn't already have one. The room_goto would happen regardless of whether there was already a room in global.GroupA, or if you had just assigned one through the choose() function.
 
Top