• 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!

UWP [Resolved] Having trouble creating/initializing global variables

Nixxi

Member
Hello GameMaker Community.

I'm having an issue with creating global variables for sharing information between the players, game objects, and ini reading/writing. Part of the problem is that my game has a max of twenty (20) save slots, each slot has roughly 5,200 individual datapoints (for stats, records and progression, inventory, etc.), and if I can't get them created/initialized using 'for' loops and concatenated strings I'll need to refactor the whole game or be forced to write 103,360 individual variables - and who knows how many errors and carpal tunnel-related doctor visits that will result.

So what I'm hoping is that I can show you my little batch of code that should initialize all these variables and someone will recognize what I'm doing and show me the correct way to do it because it's currently just not doing anything. Any help would be very much appreciated.

Here's my code:
Code:
for (var d = 0; d < global.i_SaveSlots; d += 1) {
    variable_global_set("ss"+string(d)+"_ISLOCKED",0); // Save Slot is occupied
    variable_global_set("ss"+string(d)+"_ISLOADED",0); // Save Slot is currently loaded
    // Create Player Profile, Records, and Base Stats
    for (var i = 0; i < 16; i += 1) {
        if i <= 2 {
            variable_global_set("d"+string(d)+"_PlayerProfile"+string(i),noone);
        } else {
            variable_global_set("d"+string(d)+"_PlayerProfile"+string(i),-1);
        }
        variable_global_set("r"+string(d)+"_PlayerRecord"+string(i),-1);
        variable_global_set("s"+string(d)+"_PlayerBaseStats"+string(i),-1);
    }
    // Values for p_GearSlot0#[#,#] - 8 Slots, 16 Items per Slot, 40 stats per Item
    for (var g = 0; g < global.i_InventoryGroups; g += 1) { // Gear Group
        for (var n = 0; n < global.i_InventorySlots; n += 1) { // Gear Slot Number
            for (var v = 0; v < global.i_InventoryStats; v += 1) { // Gear Stat Value
                variable_global_set("i"+string(d)+"_Gear0"+string(g)+"_Slot"+string(n)+"_Stat"+string(v),-1);
            }
        }
    }
}
Quick breakdown:
d = Number of Saved Players
i = Number of data points for non-inventory related things (name, score, xp, currency, name, color, character customization, etc.)
g = Number of gear groups (helmet, chest, gloves, belt, etc)
n = Number of inventory slots in each gear group
v = Individual stat values for each gear item
ss##_ISLOCKED and ss##_ISLOADED are for ensuring data is being saved in the correct corresponding save location and can't be overwritten by anyone else once a player has loaded the save onto their character.

When I run this in the debugger, all of my individually initialized globals (like global.i_SaveSlots) are present, but none of these variable_global_set functions seem to work - I can't find or reference any of them and they're not presently listed in the global variables list. So, does anyone have a good alternative to this (preferably not using 'ds_list/maps/grids' because I can never get them to work right and they scare me) so I can salvage my project?
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Okay, it looks like this may be a debugger issue, as my tests indicate that the variables DO exist and are accessible to use. I simply copied a bit of your code like this:
Code:
for (var d = 0; d < 10; d += 1) {
    variable_global_set("ss"+string(d)+"_ISLOCKED", d * 10); // Save Slot is occupied
    show_debug_message(variable_global_get("ss"+string(d)+"_ISLOCKED"));
}

show_debug_message(global.ss5_ISLOCKED);
Now, the debug messages all showed the correct values and none of them gave an unknown variable error, so the global vars are there and can be accessed fine. In the debugger, however, I only see a single <unknown> global variable with a single value of 40. So, the debugger is not picking up these variables correctly I think.

I'll file a bug. ;)
 

Nixxi

Member
Okay, it looks like this may be a debugger issue, as my tests indicate that the variables DO exist and are accessible to use. I simply copied a bit of your code like this:
Code:
for (var d = 0; d < 10; d += 1) {
    variable_global_set("ss"+string(d)+"_ISLOCKED", d * 10); // Save Slot is occupied
    show_debug_message(variable_global_get("ss"+string(d)+"_ISLOCKED"));
}

show_debug_message(global.ss5_ISLOCKED);
Now, the debug messages all showed the correct values and none of them gave an unknown variable error, so the global vars are there and can be accessed fine. In the debugger, however, I only see a single <unknown> global variable with a single value of 40. So, the debugger is not picking up these variables correctly I think.

I'll file a bug. ;)
Thanks Nocturne, although I'm not sure if that's the end of it... I've been trying to reference these globals to write to an ini file for game saves, but nothing gets written. Not sure if it's connected to this issue or not (or if there is an issue with writing ini files while sandboxed that I'm not understanding correctly in GMS2). My script for writing to the ini file is roughly the same as when I initialize the globals: [ ini_write_string("SaveSlot_"+string(SS),"ItemNumber_"+string(SI),variable_global_get("StatValue"+string(SV))); ] - or I could have a misspelled variable somewhere that is throwing a wrench into everything that I haven't found yet. Either way, thank you for making sure I'm not crazy. :)

EDIT: I've included the save script just to eyeball in case I don't realize I'm doing something bad.
Code:
/// @func scr_SavePlayer(obj,int);
var pid = argument0;
var ssn = argument1;
if file_exists("SaveData.ini") {
    // Read/Set Default Data
    ini_open("SaveData.ini");
    // p_PlayerProfile[#] - Data to be shown on Profile Load screen
    if variable_global_get("ss"+string(ssn)+"_ISLOCKED") == 1 &&
    variable_global_get("ss"+string(ssn)+"_ISLOADED") == 1 &&
    ini_read_real("SaveSlotStatus","SS"+string(ssn)+"_ISLOCKED",0) == 1 &&
    ini_read_real("SaveSlotStatus","SS"+string(ssn)+"_ISLOADED",0) == 1 {
        // Initialize object-level variables
        for (var d = 0; d < 16; d += 1) {
            if d >= 2 {
                variable_global_set("p"+string(ssn)+"_PlayerProfile"+string(d),pid.p_PlayerProfile[d]);
                ini_write_string("SP"+string(ssn)+"_PlayerProfile"+string(d),variable_global_get("p"+string(ssn)+"_PlayerProfile"+string(d)),noone);
            } else {
                variable_global_set("p"+string(ssn)+"_PlayerProfile"+string(d),pid.p_PlayerProfile[d]);
                ini_write_real("SP"+string(ssn)+"_PlayerProfile"+string(d),variable_global_get("p"+string(ssn)+"_PlayerProfile"+string(d)),-1);
            }
            variable_global_set("r"+string(ssn)+"_PlayerRecord"+string(d),pid.p_PlayerRecord[d]);
            ini_write_real("SR"+string(ssn)+"_PlayerRecord"+string(d),variable_global_get("r"+string(ssn)+"_PlayerRecord"+string(d)),-1);
        }  
        // p_GearSlot00[#,#]
        for (var g = 0; g < global.i_InventoryGroups; g += 1) {            // Gear Group
            for (var n = 0; n < global.i_InventorySlots; n += 1) {        // Gear Slot Number
                for (var v = 0; v < global.i_InventoryStats; v += 1) {    // Gear Stat Value
                    // variable_instance_set(pid,"p_GearSlot0"+string(g)[n,v],-1);
                    variable_global_set("i"+string(ssn)+"_Gear0"+string(g)+"_Slot"+string(n)+"_Stat"+string(v),
                    variable_instance_get(pid,"p_GearSlot0"+string(g)+"["+string(n)+","+string(v)+"]"));
                    ini_write_real("SI"+string(ssn)+"_Gear0"+string(g)+"_Slot"+string(n),"Stat"+string(v),
                    variable_global_get("i"+string(ssn)+"_Gear0"+string(g)+"_Slot"+string(n)+"_Stat"+string(v)));
                }
            }
        }
        // Set Save Slot Status
        variable_global_set("ss"+string(ssn)+"_ISLOCKED",1); // Save Slot is occupied
        variable_global_set("ss"+string(ssn)+"_ISLOADED",1); // Save Slot is currently loaded
        ini_write_real("SaveSlotStatus","SS"+string(ssn)+"_ISLOCKED",variable_global_get("ss"+string(ssn)+"_ISLOCKED"));
        ini_write_real("SaveSlotStatus","SS"+string(ssn)+"_ISLOADED",variable_global_get("ss"+string(ssn)+"_ISLOADED"));
    } else {
        // Error message? - OR - Blank Profile?
    }
    // Close the ini file session
    ini_close();
}
 
Last edited:

Nocturne

Friendly Tyrant
Forum Staff
Admin
I'll do a wee test in a bit (when I've finished work) and see how it goes then post back. If I find that it works, I'll add a link to the test project I've made so you can compare with what you're doing.
 

Nixxi

Member
I'll do a wee test in a bit (when I've finished work) and see how it goes then post back. If I find that it works, I'll add a link to the test project I've made so you can compare with what you're doing.
You're my hero. :D
 

Nixxi

Member
I was able to fix my save issues by changing something. I don't remember what I changed, I'm just going to try really hard to not change it again. Thanks for the bug report and help in identifying some of the issues I was having. :)
 
Top