Like any programming language GML uses variables as the basic unit for most programming operations. Variables are used to store information in the devices memory for later (or instant) use, and they are given a name so that you can refer to them in functions and scripts. A variable in GML can store many different data types, like a real number (like 100, 2.456575, -56 etc...), a string (like "Hello world!"), an integer (like 1, 556, -7), or a boolean (true or false).
A variable is something that we use to store a value for use in one or more operations or functions. Think of "pi", for example... it is a real world variable that holds the value 3.14159265(etc...). Why? Well, it's much easier to say to someone "pi" than "three point one four one five nine two six five"! So, naming things makes life a lot simpler and it also means that should the value of that variable ever change, we don't have to change the number everywhere as the variable name is still the same. In GML a variable has a name that must start with a letter and can contain only letters, numbers, and the underscore symbol '_' with a maximum length of 64 symbols. So, valid variables are things like fish, foo_bar, num1, and invalid variables would be 6fish, foo bar, or *num.
Now, In many programming languages you need to "declare" a variable before you can use it. This basically means that you tell the computer the name you wish to use so that it can assign a place in memory to store whatever value you decide to hold in that variable. With GML, that is not always necessary as it depends on the scope of the variable. There are four main variable categories when you program with GameMaker Studio 2 and each has its own scope (which is can be considered as its area of operation, or reach). These variables and their scope are outlined below:
An instance variable is created within an instance of an object and is considered unique to that instance - ie: many instances of the same object can have the same variable, but each variable can hold a different value as they are unique to each instance. But how is an instance variable created? Well, you create new variables simply by assigning a value to them as shown in this small example:
potions = 12;
life = 100;
name = "Jock MacSweeney";
strength = 5.5;
armour = -2;
As you can see you just have to give the name and then a value (either numeric or a string) to set that variable and have it ready for use within an instance of the object you are coding for. These variables can then be used and modified in a number of ways from within the instance, for example this code could be in a collision event and used to take an amount off of the variable "life":
life -= 5 + armour;
If "life" is at 100 it will now have a value of 97 (100 - (5 + -2) = 97). Now, that's a simple example, and you could replace "armour" for the actual value of -2, but what happens if you use that value in multiple places and then decide to change it? You would have to go through ALL your code and change every -2 to whatever the new value is, which is time consuming and very error prone! But if you use a variable, all you have to do is reassign it a new value and the code will automatically use that new value from then onwards, making things far more flexible and far easier to fix should there be a problem. It should also be noted that even if a value is not going to change it is far easier to remember what a variable called "life" means rather than just looking at a number.
GameMaker Studio 2 has a collection of "built in" instance variables too, so you should be aware of them as you may name one of your own instance variables the same or wish to have your own global variable with the same name and wonder why you are getting errors. They are easy to spot, however, as they are shown in a different colour in the code editor and also come up in the auto-complete bar at the bottom.
There are a couple of functions designed to help you when dealing with instance variables (primarily for use with Compatibility Scrpts for imported projects and the code for Drag and Drop actions, but they can be used elsewhere too):
A local variable is one that we create for a specific event only and then discard when the event has finished (the only exception to this is in the script resources, where a var declared variable is local to the script and then discarded). Why would we need them? Well, variables take up space in memory and it may be that we are only going to use them for one operation or function in which case we only need to have it in memory for that short time that it's used. This keeps your code base clean and tidy as well as keeping memory space optimised for the things that really need it. To declare a local variable we use the function var like this:
var i, num, str;
i = 0;
num = 24.5;
str = "Hi there!";
All of the variables created above will be "forgotten" (ie: removed from memory) at the end of the event (or script) in which they were created. You must be careful that the name you give var declared variables does not coincide with another instance variable within the object running the code, and also make sure that you have no intention of using the value stored in that variable outside of the event declare it in. These variables are used a lot in programs, especially in loops for counting iterations, or when using a value several times in one operation that is not going to be repeated again. Here are another couple of examples:
var i = 0;
inventory[i] = 0;
The above code creates a local variable called "i" and sets it to 0, all in the same line. Note that in previous versions of GameMaker you had to declare your local variables first and then assign them values, but in this version you can declare and assign them a value at the same time. The above code then uses this variable to initialize an array. As the variable "i" is not going to be used for any further functions in the instance other than this, it can be local in scope. Here is one more example:
xx = x - 32 +irandom(64);
yy = y - 32 +irandom(64);
instance_create_layer(xx, yy, "Effects", obj_blood);
Here we have used the local variables to store some random coordinates that we then use to create an instance. In this example you can see that it is not strictly necessary that we use these variables but for the sake of readability and ease of use, we do. It is MUCH clearer and obvious what we are doing there than if we used this code:
instance_create_layer(x - 32 + irandom(64), y - 32 + irandom(64), "Effects", obj_guts);
One other thing about var declared variables should be noted... As they are unique to the event that runs them, they can be used in any other instances through code too! This means that we can use these variables to set and change things in other instances using the "with()" construct (there is a section on this in the GML Overview section of the manual). The actual code itself would look something like this:
var num = instance_number(obj_Enemy);
if num>10 instance_destroy();
The above code works because the var declared variable is local to the event (or script) it is contained in, not the instance, nor the game world, and so can be used in any function in any object as long as it is in the same code block.
A basic description of a global variable is one that, once declared, belongs to no instance in particular and yet can be accessed by all. Just like local variables, global variables must be declared, but unlike a local variable, a global variable remains in memory until the end of the game. So, you can create a global variable to keep track of (for example) the number of bullets that the player has and then just update this variable at different points in the game. A global variable does not belong to any specific instance and can be accessed, changed and used by all instances at any time, but any change made to the variable are "global", in that all instances using the variable will be affected by the change. Let's have a look at an example:
global.food = 5;
We declare the "food" variable by first writing "global" and then a "." to tell GameMaker Studio 2 that this variable is now global scope. We will need to use this method from now on any time we are required to access or to change this variable in any way. So, we have created a new variable called "food" and we have declared it as global. Now, any instance can use and change this variable in any way and all other instances will "see" this. For example we could have a different food object that the player collides with and in the collision event we have:
We also have another object that draws this value like this:
draw_text(32, 32, "food = " + string(global.food));
With global variables we can change values and see those changes reflected in all instances of the objects that reference this variable. As with local variables you have to take care not to name your global variables the same as any instance variables as that will cause you problems and make bugs creep into your games due to variable overlap, which can be a difficult issue to debug sometimes. In general you should have a single script or object that declares all your global variables at the very start of the game (for example, in the Room Start Event), so that they are initialised and ready for any instance to use, and this also gives you a handy place to go back and reference should you need to check a variable name.
GameMaker Studio 2 has a collection of "built in" global variables too, so you should be aware of them as you may name one of your instance variables the same or wish to have your own global variable with the same name and wonder why you are getting errors! They are easy to spot, however, as they are shown in a different colour in the code editor and also come up in the auto-complete bar at the bottom. The majority of built in global variables are very specific and will only be used on rare occasions - and are listed in the appropriate sections of the manual - but there is one important one that is used frequently and isn't listed elsewhere:
There are also three deprecated built in global variables which you should be aware of (these variables are only designed to support legacy projects from previous versions of GameMaker and should not be used in new projects):
The following method can also be used to declare global variables, but it is only included for backwards compatibility, and it is not recommended that you use this method for new projects as future versions of GameMaker Studio 2 may not support it.
The second method for creating global variables is to declare them as such using the globalvar declaration, much as you would a local variable using the var declaration.IMPORTANT! The globalvar declaration is deprecated and only supported for legacy purposes. You should always use the global. identifier to mark global variables.
This (deprecated) declaration would be used as follows:
food = 5;
Once declared in this way that variable "food" is now considered global and requires no global. prefix - which also means that it's a lot harder to identify global variables in your code and it's also much easier to get variable overlap as you use the same variable name in different objects or from extensions that you've installed. Once declared in this way the global variable is accessed as follows:
food += 2;
draw_text(32, 32, "food = " + string(food));
As you can see, with nothing to show that the variable is global in scope you are potentially setting yourself up for many subtle problems to arise in your game, which is why this declaration should be avoided.
There are a couple of functions designed to help you when dealing with global variables (primarily for use with Compatibility Scripts for imported projects and the code for Drag and Drop actions, but they can be used elsewhere too):
Built in variables are special variables that are "built into" the objects and the rooms in the game world and they can be either instance or global in scope (but never local). Some global variables are listed in the section above, and the different sections of the manual for sprites, rooms, objects etc... also outline the built-in variables available. Examples of such built-in instance variables would be:
And examples of built-in global variables would be:
Built-in variables can be changed and set like most other variables, and some can even be arrays, only you don't have to set them to create them like you would a regular variable as they will already be initialised to a default value.
While not exactly variables, macros are similar to them in how they are used, ie: they are named values that you can use throughout your code to replace hard values. Basically, a macro (also called a constant when used like this) is a named variable that holds a constant single value (or string). You can define your own constants using the Script Editor and then use them in your code and DnD as if they were regular variables, with the one difference being that they can't be changed in the game. For example say you define the following macro as a constant (note the preceding "#" and the lack of a colon ";" at the end):
#macro total_weapons 10
You would then call this in your code like this:
if ++pos == total_weapons
pos = 0;
Note that you would not be able to change the constant value, so code like this will cause the game to crash:
total_weapons = 11;
You can define a macro anywhere in your code or scripts and it will be pre-compiled and included in your game as if it was there from the start, but we recommend that you create a dedicated script resource and define all your macros in there. It will be easier to organise and debug later!
If you need the value of a macro to change at run-time then you should probably make it a global variable, since these can be changed from code during a game, unless you set the macro to be a function. By setting the macro to a function it means that this function will be called every time you use the macro. For example:
#macro col make_colour_hsv(irandom(255), 255, 255)
You would then call this macro something like this:
image_blend = col;
Using this code will make the image blend a different colour every time the macro is used. It is worth noting that you can also split macros over multiple lines using the \ character to show where the line breaks. An example would be something like:
#macro hello show_debug_message("Hello" + \
string(player_name) + \
", how are you today?");
This is purely cosmetic, in that splitting a macro like this will have no effect over the result of the final macro, and is simply to provide support for multiline text on macros that have longer lines of code.
One very important feature of macros is that they can be defined for use with specific Configurations (configs), meaning you can have the same macro name but give it different values based on the currently selected config. For example, say you have a configuration for Android Ads and another for iOS Ads, then you could define a single macro to hold the required app ID value:
#macro ad_id "";
#macro Android:ad_id "com.yoyogames.googlegame"
#macro iOS:ad_id "com.yoyogames.appstoregame"
As you can see, you give the config name first then a colon : and then the macro name and value. Note that you cannot have any whitespace between the colon : and either the config name nor the macro name otherwise you will get an error.