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

GML changing global variables in scripts?

Non.A

Member
hello :)

I'm having a hard time trying to increment a global variable inside a script. I thought global variables could be changed anywhere, so this is pretty confusing.

example: global.heartcount++
I have a draw event in the room to represent the global.heartcount number so that I can see whether or not it's working.
the code works fine when it's directly inside an object, but doesn't seem to register when it's used in a script. here are screenshots of an example of the issue:
screenshots:
1.) script 2.) script inside object 3.) result of script inside object 4.) code directly in object 5.) result of code directly in object
script.pngobject with script.pngwith script result.pngobject without script.pngobject without script result.png
 

FoxyOfJungle

Kazan Games
The way you did it will never work. In the first screenshot you are saying that a = argument0; You are setting the variable "a" to the argument0, and incrementing the copy "a" of the value returned by argument0, not the original variable returned by argument0.

Instead, just put this inside the function:
GML:
function scr_globaltest() {
    global.heartcount += 1;
}
And call this in the Create Event:
GML:
scr_globaltest()


If your goal is to call a function to increment a global variable, this is not necessary, instead, just do this:
GML:
function scr_globaltest(value) {
    /// @func scr_globaltest(value)
    /// @arg value
    global.heartcount += value;
}
And call this in the Create Event:
GML:
scr_globaltest(10)
 

Non.A

Member
thank you both for responding so quickly. I've been at this all day.

I'm trying to avoid using the actual words 'global.heartcount' in the script, because I'm using the same script for different objects.

example: scr_globaltest(variable_to_increment)

in one object, I'll use scr_globaltest(global.heartcount)
in another I'll use scr_globaltest(global.flowercount)

I'm sure there are lots of ways to do this, but a script is most convenient for what I'm doing.
 

Nidoking

Member
a script is most convenient for what I'm doing.
This is almost certainly not true, if each object has its own variable that it would need to increment. A better approach might be to define the function in the object's Create event and then call it from there. There are ways to do what you're trying to do, but I think they're poor programming practice and I will not advocate for them. Someone else will almost certainly chip in to tell you how it's done, and it's up to you whether you want to do it their way or a good way.
 
Not specifically talking about GML, but general programming here: the best functions are functions you can reuse. That's 100% correct.
On a slightly more advanced level, not all your functions need to be global in scope (just like variables). There are also METHODS, which are basically functions that are NOT global in scope.
But in this case, I would just go with what reads and feels best to you. You can always make backups and refactor your code later on.
 

Non.A

Member
This is almost certainly not true, if each object has its own variable that it would need to increment. A better approach might be to define the function in the object's Create event and then call it from there. There are ways to do what you're trying to do, but I think they're poor programming practice and I will not advocate for them. Someone else will almost certainly chip in to tell you how it's done, and it's up to you whether you want to do it their way or a good way.
I will accept yours and anyone else's suggestions. I'm glad to hear any and all possible solutions.
 

Non.A

Member
Not specifically talking about GML, but general programming here: the best functions are functions you can reuse. That's 100% correct.
On a slightly more advanced level, not all your functions need to be global in scope (just like variables). There are also METHODS, which are basically functions that are NOT global in scope.
But in this case, I would just go with what reads and feels best to you. You can always make backups and refactor your code later on.
I'm pretty new to programming. I know once I figure this out it's going to be so simple. it's just the hours and hours of dead ends to get to that point. I'll keep at it. thank you.
 
I'm pretty new to programming. I know once I figure this out it's going to be so simple. it's just the hours and hours of dead ends to get to that point. I'll keep at it. thank you.
It's said approx. 3 millions people can code basic Python, you can definitely learn GML. It's also a good template to other languages, as, as you'll learn, once you know how to program (data types, loops, conditions, all the basics, really), the language itself becomes secondary. It's *almost* just a matter of syntax, by that point. GML provides mostly everything you need to learn as far as those basics goes
 

chamaeleon

Member
Unless I missed it, no one has explicitly said that gml uses call by value for the function call arguments, which means the functions does not have any knowledge of the variables passed. The functions only have the value. Changing a value won't affect the variable used in the function call.

At its core, what OP want to do is not really possible and I don't consider the get and set functions for variables to be a counter argument to the pass by value statement, despite being a way of somewhat being around the issue. On a syntactic and semantic level, inside the function nothing done to the value will change what value the variable has after the function call.

With arrays being reference counted, the value/reference stored isn't what changes when using @, it is the array content itself. Just like you can't make a variable holding a DS data structure number hold a different number (another DS number or anything else), but nothing stops you from changing the data in the DS structure by using the appropriate functions for the purpose.
 
At its core, what OP want to do is not really possible and I don't consider the get and set functions for variables to be a counter argument to the pass by value statement, despite being a way of somewhat being around the issue. On a syntactic and semantic level, inside the function nothing done to the value will change what value the variable has after the function call.
Yeah, the only way I see it possible is using structs, the $ accessor, and passing the struct variable as a string and going other.struct[$_variable_string] += 1, but this is overly complicated for this use case.
 

Non.A

Member
just for clarity, scripts are just copy+paste chunks of code. variables can be used but values inside scripts can't dynamically change?
 

Rob

Member
If you want a script that will increase/decrease the value of any variable you want to use it with, you can just make a function like this:

GML:
//Function
function change_val(variable, value){
   variable += value;
   return variable;
}


//To use
something = change_val(something, value);

//Eg
something = 10;
value = 5;
something = change_val(something, value); //something now equals 15
 
Last edited:

Nidoking

Member
increase/decrease the value of a variable
For clarity, this is not changing the value of a variable. This is returning a value that can be stored in the variable, or in a different variable, or thrown away. The variable passed in is not changed unless you store the return value of the function in it. That will always be the case for non-data structure variables.
 

Non.A

Member
If you want a script that will increase/decrease the value of any variable you want to use it with, you can just make a function like this:

GML:
//Function
function change_val(variable, value){
   variable += value;
   return variable;
}


//To use
something = change_val(something, value);

//Eg
something = 10;
value = 5;
something = change_val(something, value); //something now equals 15
thanks I was sure this was going to work but it didn't. I think I just misunderstood what scripts were capable of.
 
Last edited:
  • Like
Reactions: Rob

Nidoking

Member
If argument0 is a numeric type, then calling the function will result in Game Maker determining what one more than the argument is and not telling you about it. Effectively, if you think about variables as whiteboards that hold values, the answer will be written on the back of the whiteboard and you can't see it. From the perspective of every part of the game that matters, that function does absolutely nothing.

If argument0 is a non-numeric type, then I would expect the game to throw a math exception and crash or engage your exception handler.
 

Non.A

Member
What happens if you do this?...
Code:
function scr_globaltest(argument0) {
    argument0++;
}
good vibes to you.
good vibes your ancestors.
good vibes to your descendants.
a week of dead-ends is resolved by "put two plus signs after the word argument".
I will thank you in the credits.
 
Top