Author Topic: Saving and loading new variables in GM:Studio  (Read 1890 times)

TheGamerGuy500

  • Cherry Eater
  • Posts: 62
  • I'm a gamer and a guy, video-game-music junkie...
  • OS:
  • Windows 7/Server 2008 R2 Windows 7/Server 2008 R2
  • Browser:
  • Chrome 44.0.2403.107 Chrome 44.0.2403.107
    • View Profile
    • TheGamerGuy500 HQ
  • Playstyle: Keyboard
Saving and loading new variables in GM:Studio
« on: July 27, 2015, 02:00:22 PM »
I know I'm giving up my novice GM-coding level by making this and going back to beginner, but...
Saving and loading variables (specifically arrays) seems to be harder than expected.
So I gotta know.
What in bloody blazes do I have to do to get a global.clear variable to work for my game?
With Klazen's Studio Engine...
The saving script:
Code: [Select]
var f,n;

dyingSave = argument0

n=EXECUTABLE_DIRECTORY + 'save' + string(global.savenum);

if (FS_file_exists(n)) {
    f=FS_file_bin_open(n,2);
} else {
    f=FS_file_bin_open(n,1);
}

FS_file_bin_write_dword(f,global.death);
FS_file_bin_write_dword(f,global.time);
if (!dyingSave) { //only save death,time for dying save
    FS_file_bin_write_byte(f,global.difficulty);
    FS_file_bin_write_dword(f,room);
    FS_file_bin_write_dword(f,round(x));
    FS_file_bin_write_dword(f,round(y));
    FS_file_bin_write_byte(f,player.image_xscale+1); //+1 so -1=0, 1=2; bytes have no sign
    //new values go under here
    FS_file_bin_write_byte(f,global.hasPartner); //just a thing for the game I'm making
    FS_file_bin_write_byte(f,global.clear[global.savenum]);   //if this isn't an array then it will crash the game at the file select
}

FS_file_bin_close(f);
Loading script:
Code: [Select]
var f,r,xx,yy,xs;

f = FS_file_bin_open(EXECUTABLE_DIRECTORY + 'save' + string(global.savenum),0);
global.death = FS_file_bin_read_dword(f);
global.time = FS_file_bin_read_dword(f);
global.difficulty = FS_file_bin_read_byte(f);
r = FS_file_bin_read_dword(f);
xx = FS_file_bin_read_dword(f);
yy = FS_file_bin_read_dword(f);
xs = FS_file_bin_read_byte(f)-1; //see saveGame to see why -1
//new values go under here
global.hasPartner = FS_file_bin_read_byte(f);
global.clear[global.savenum] = FS_file_bin_read_byte(f); //again, it will crash the game or just not save if it's not an array

FS_file_bin_close(f);

room_goto(r);

if (!instance_exists(player)) {
    instance_create(xx,yy,player);
} else {
    player.x=xx;
    player.y=yy;
}
player.image_xscale=xs;
For some freakin' reason, even though it's in the order that klazen specified, this variable wants to choose whichever room you save in last as the clear value.

world create event:
Code: [Select]
// Init Other
timeCounter = 0;

// Init Menu Globals
for (i=1;i<=3;i++) {
    global.menuDeath[i] = 0;
    global.menuTime[i] = 0;
    global.menuDiff[i] = 0;
    global.clear[i] = 0;
}

// Checks Save Files
for(i = 1; i <= 3; i += 1){
    if(FS_file_exists(EXECUTABLE_DIRECTORY + 'save' + string(i)) == true){
        f = FS_file_bin_open(EXECUTABLE_DIRECTORY + 'save' + string(i),0);
       
        // Load Data
        global.menuDeath[i] = FS_file_bin_read_dword(f);
        global.menuTime[i] = FS_file_bin_read_dword(f);
        global.menuDiff[i] = FS_file_bin_read_byte(f);
        global.clear[i] = FS_file_bin_read_byte(f);
       
        FS_file_bin_close(f);
    }
}

guiTimer=0; //time before GUI appears
guiOffset=0; //position of GUI

global.buildNumber = "Build 2";

Please tell me what I did wrong, as it's delaying the release of the game to some friends that want it (although I don't expect you to care).

The problem: the clear variable never saves correctly. if I take out the square brackets, the clear variable will save as a variable instead of an array, even if it's for one save file. Then, at the file select, it will try to index a variable that isn't an array, resulting in an immediate crash. But even when this is an array it saves just the room number of where you last saved. Everything else saves correctly. It crashes at the file select without the square brackets because I have if global.clear[number_of_file] = 1 then display "complete" under the file and removing the square brackets makes that just a variable and not an array. What do?
Also to set the clear to 1:
« Last Edit: July 27, 2015, 03:07:16 PM by TheGamerGuy500 »
Pro tip: you gotta run and jump at the same time!
Notice: She doesn't stop spinning.

:KappaHD:

klazen108

  • Administrator
  • The Kid
  • Posts: 286
  • your a kid now your a squid now
  • OS:
  • Windows 8.1/Server 2013 Windows 8.1/Server 2013
  • Browser:
  • Chrome 44.0.2403.89 Chrome 44.0.2403.89
    • View Profile
    • Delicious-Fruit
  • Playstyle: Keyboard
Re: Saving and loading new variables in GM:Studio
« Reply #1 on: July 28, 2015, 12:04:05 AM »
For the save/load scripts, just save global.clear (no array) - you just want to put that one value in the file.

For the world create event, use global.menuClear[] instead of global.clear - the game is crashing because you were defining it as an array in the world create, but using it as a single variable in the save/load files. Using a different name here will fix that. The menu values are for display only, they're not used beyond the main menu.

As for why it's getting the room number - this is because of the order you're loading it in. in the world create, it opens the save file, then does this:
Code: [Select]
global.menuDeath[i] = first value in file
global.menuTime[i] = second value in file
global.menuDiff[i] = third value in file
global.menuClear[i] = fourth value in file

And if you look in the save/load scripts, you'll see that it saves the room value fourth, so when you read it in the menu, it's getting that room value. Again, using a menuClear array in the world create will solve this.

Now, to make sure that the menu can read it, you should move the clear value save/load to the fourth position in the file:
Code: [Select]
//...snip...
FS_file_bin_write_dword(f,global.death);
FS_file_bin_write_dword(f,global.time);
if (!dyingSave) { //only save death,time for dying save
    FS_file_bin_write_byte(f,global.difficulty);
    FS_file_bin_write_byte(f,global.clear); //////put clear here so it's the fourth value in the file
    FS_file_bin_write_dword(f,room);
    FS_file_bin_write_dword(f,round(x));
    FS_file_bin_write_dword(f,round(y));
    FS_file_bin_write_byte(f,player.image_xscale+1); //+1 so -1=0, 1=2; bytes have no sign
    //new values go under here
    FS_file_bin_write_byte(f,global.hasPartner); //just a thing for the game I'm making
}

FS_file_bin_close(f);
Do the same for the load script, and do the same for anything you want to appear in the menu screen.

So, here's the todo list:
  • For the world create event, use global.menuClear[] instead of global.clear
  • Use global.clear (not array) in save/load scripts
  • Move global.clear to fourth position in save/load scripts

Try that out and let me know if it solves your issue!

TheGamerGuy500

  • Cherry Eater
  • Posts: 62
  • I'm a gamer and a guy, video-game-music junkie...
  • OS:
  • Windows 7/Server 2008 R2 Windows 7/Server 2008 R2
  • Browser:
  • Chrome 44.0.2403.107 Chrome 44.0.2403.107
    • View Profile
    • TheGamerGuy500 HQ
  • Playstyle: Keyboard
Re: Saving and loading new variables in GM:Studio
« Reply #2 on: July 28, 2015, 11:03:59 AM »
That actually worked. Thanks a bundle, mate :atkHappy: !
I think I see how the menu(variable) things work, but I was skeptical why menuClear could just, work automatically without some translation from variable clear to menuClear. The translation is in the order that it reads things.
Pro tip: you gotta run and jump at the same time!
Notice: She doesn't stop spinning.

:KappaHD: