When you start programming a game, almost everything eventually comes back to one simple idea: storing information.
Your player’s health needs to be remembered. The game needs to know how many coins have been collected. An enemy needs a movement speed, a character needs a name, and your menu needs to know whether the sound is turned on or off.
In GameMaker Language, or GML, that information is usually stored inside variables.
Learning Variables and Data Types in GML Explained may sound like one of those dry programming topics you have to survive before making an actual game. In reality, variables are involved in nearly every gameplay system you will ever create.
Once you understand how values are stored, what different data types represent, and how variable scope works, GML becomes much easier to read and write.
This beginner-friendly guide explains the essential concepts using simple examples you can actually imagine using inside a GameMaker project.
1. What Is a Variable in GML?
A variable is essentially a named place where your game stores a value.
Imagine creating a player with 100 health points. Instead of writing the number 100 everywhere in your game, you could store it inside a variable:
health = 100;
Now health represents that value.
If the player receives 20 damage, you can simply write:
health -= 20;
The variable now contains 80.
GameMaker’s documentation describes variables as named storage used to keep information in memory for immediate or later use. Variables can hold different kinds of values, including numbers, strings, booleans, arrays, structs, and other GML data types.
Variables make your code flexible because values can change while the game runs.
For example:
player_speed = 4;
score = 0;
player_name = "Alex";
game_over = false;
Each variable stores information with a different purpose—and, in several cases, a different data type.
2. Understanding Numbers in GML
Numbers are among the most common values you will use.
You might store health, speed, damage, coordinates, timers, scores, animation speeds, or probabilities as numerical values.
For example:
health = 100;
move_speed = 4.5;
damage = 25;
x_position = 320;
GameMaker supports numerical types such as real numbers and integer formats. Its documentation explains that real values are generally stored using double-precision floating-point values or integer representations, depending on the value and platform.
That means you can work with both whole numbers and decimals naturally.
coins = 10;
gravity_strength = 0.5;
One thing beginners should remember is that decimal calculations can sometimes produce tiny rounding differences because of floating-point mathematics.
For ordinary movement or gameplay calculations, this usually is not something you need to worry about. It becomes more relevent when comparing decimal values with extreme precision.
3. Strings Store Text
A string represents text.
Strings are surrounded by quotation marks:
player_name = "Lena";
weapon_name = "Iron Sword";
message = "Game Over";
Strings are useful anywhere your game needs words rather than numbers.
You might use them for dialogue, character names, item descriptions, menu labels, quest information, save data, or debugging messages.
You can also combine strings.
player_name = "Maya";
message = "Welcome, " + player_name;
The resulting value of message becomes:
Welcome, Maya
This process is commonly called string concatenation.
Be careful when combining different data types. If you need to place a numerical value inside text, converting or formatting that value correctly can help prevent type-related errors.
For example, displaying a score might involve:
show_debug_message("Score: " + string(score));
Understanding when a value is text and when it is numerical becomes increasingly important as your game’s interface grows.
4. Boolean Values Handle True-or-False Logic
Some game information does not need numbers or text.
Sometimes you only need to know whether something is true or false.
That is where Boolean values come in.
is_alive = true;
door_open = false;
can_jump = true;
Booleans are particularly useful with conditional statements.
For example:
if (can_jump)
{
vspeed = -8;
}
This code only performs the jump when can_jump evaluates as true.
GameMaker provides the true and false constants specifically for Boolean logic. The documentation also explains how numerical values can be evaluated as Boolean values, although using the actual true and false constants generally makes your intentions much clearer.
You will use Boolean variables constantly for systems such as doors, switches, abilities, game states, enemy behaviour, checkpoints, and menu settings.
5. Local, Instance, and Global Variable Scope
Knowing what value a variable contains is only half the story.
You also need to understand where that variable exists.
This concept is called variable scope.
Local Variables
A local variable exists only inside the event or function where it is created.
In GML, local variables are commonly declared using var:
var _damage = 20;
var _critical = false;
Once that event or function finishes, the local variable is discarded.
Local variables are useful for temporary calculations because they do not need to remain available forever.
Many developers use an underscore at the beginning of local variable names, such as _damage, to make their scope visually obvious. This is a naming convention rather than a requirement.
Instance Variables
An instance variable belongs to a specific object instance.
For example:
health = 100;
speed_bonus = 1.2;
If five enemy instances exist, they can each have their own health value. Damaging one enemy does not automatically reduce the health of every other enemy.
GameMaker documents instance variables as values unique to individual instances, even when those instances originate from the same object.
This makes instance variables perfect for player stats, enemy health, movement states, ammunition, cooldowns, and other object-specific information.
Global Variables
Global variables can be accessed from throughout your game.
They use the global. prefix:
global.score = 0;
global.coins = 25;
Unlike temporary local variables, global variables remain available throughout the game once created.
They can be useful for information shared by many systems, but using too many can make a project harder to maintain.
Keep global data for genuinely game-wide information rather than turning every variable into a global one.
6. Arrays Store Multiple Values Together
Creating a seperate variable for every related value quickly becomes messy.
Imagine storing ten inventory items like this:
item1 = "Sword";
item2 = "Potion";
item3 = "Key";
That approach becomes difficult to manage.
An array lets one variable hold multiple values:
inventory = ["Sword", "Potion", "Key"];
Each element has an index, starting at 0.
inventory[0]; // Sword
inventory[1]; // Potion
inventory[2]; // Key
GameMaker describes arrays as variables capable of holding multiple values and supports both one-dimensional and multidimensional arrangements.
Arrays are useful for inventories, enemy lists, level data, dialogue options, statistics, coordinates, card decks, and many other systems.
For example:
scores = [120, 250, 180, 400];
Instead of managing four individual score variables, you can loop through the array and process every value automatically.
That becomes increasingly powerful as your game gets larger.
7. Structs Group Related Information
Arrays are excellent when you have a collection of values, but sometimes you want those values to have descriptive names.
That is where structs become useful.
Consider an RPG item:
sword =
{
name: "Iron Sword",
damage: 15,
value: 100
};
You can then access individual properties:
sword.damage;
sword.name;
A struct acts as a container containing multiple variables, and those variables can themselves hold different data types. GameMaker also allows additional variables to be added to a struct after its creation.
Structs are extremely useful for organising complex information.
A character struct might contain a name, health value, level, inventory array, and Boolean status:
player_data =
{
name: "Nova",
health: 100,
level: 5,
inventory: ["Sword", "Potion"],
alive: true
};
Instead of having several unrelated variables scattered across your code, related data stays together in a more managable structure.
8. How to Check a Variable’s Data Type
Sometimes you may not know exactly what type of value a variable currently contains.
GML provides the typeof() function for checking.
For example:
var _value = "Hello";
show_debug_message(typeof(_value));
This returns information indicating that the value is a string.
Current GameMaker documentation lists possible typeof() results including number, string, array, bool, int32, int64, ptr, undefined, method, struct, and reference-related types.
This can be particularly helpful when debugging data loaded from external files or when working with functions that may return different types.
You will not necessarily use typeof() every day, but it is useful when your code behaves strangely and you suspect a value is not what you expected.
9. Common Variable Mistakes Beginners Make
One common mistake is creating variables without thinking about their scope.
For example, using global.player_health when the health only belongs to one player instance may create unnecessary dependencies between systems.
Another problem is mixing incompatible data unexpectedly. A variable containing "10" is a string, while one containing 10 is numerical. They may look similar when printed, but your program can treat them very differently.
Naming also matters.
Something like:
x1 = 20;
may work, but:
enemy_damage = 20;
explains its purpose immediately.
Clear variable names make debugging much easier, especially when you return to your project weeks later.
Finally, initialise important variables before using them. Trying to access information that has not been properly created can lead to errors or undefined values.
Good variable habits may feel insignificant in a tiny project, but they become increasingly important as hundreds of scripts, objects, and systems begin interacting.
Understanding variables and data types in GML gives you one of the most important foundations for programming games in GameMaker.
Variables store the information your game needs, while data types determine what that information represents.
Numbers handle calculations, strings store text, Booleans represent true-or-false states, arrays organize collections, and structs let you group more complicated information together.
Variable scope is equally important. Local, instance, and global variables each solve different problems, and choosing the right one keeps your code easier to understand.
Do not try to memorise every advanced GML type immediately. Start by creating a simple object with health, speed, name, and state variables, then experiment with arrays and structs as your project becomes more complex.
The fastest way to understand these concepts is to actually use them in a small game.
