If you want to create a checkerboard level for a chess game, or a turn-based game like Advance Wars 2 (which by the way is a great game, if you don't know it, play it!), you're in the right place to start. In this tutorial, we will learn how to create a grid using a 2-dimensional board. Then we'll fill in the grid with the different objects in our level.

Quick introduction: the 2D table
When I talk about a 2D array in GameMaker Studio, it is simply an array where each entry contains... another array. Most development languages have this type of variable, and it is a must in video games. In this way, you can store a lot of information in an orderly way, whether it's your future level or a list of characters and their favorite colors:
// Player
array_2d = [
["Mario", "Red", 1],
["Luigi", "Green", 2],
["Peach", "Pink" , 3]
];
// Output result
array_2d[0,0] = "Mario";
array_2d[0,1] = "Red";
array_2d[0,2] = "1";
If you want to know more about the Game Maker Studio boards, please visit this documentation page.
Initialization and creation of the grid
To begin, we will create an object called oGrid
and initialize in its create event
a 2D table which will be used as a level. We wish to obtain a level of 20 squares in length and width, with squares of 32 pixels.
// Create event oGrid
depth = -1000;
// Width & Height size
gridWidth = 20;
gridHeight = 20;
// Box size
boxSize = 32;
// Create 2D array filled with 0
for(var i = 0; i < gridWidth; i++){
for(var j = 0; j < gridHeight; j ++){
global.grid[i, j] = 0;
}
}
Let's put this object in our room and... Congratulations! We have an object oGrid
which contains a 2D array:
depth -1000
so that the grid is above the restgridWidth
andgridHeight
is the size of the gridboxSize
is the size of each square- And
global.grid
the variable that contains our grid, currently all cells contain the value "0
As you have seen, we use the word global
to define our grid. Being an essential element of our game, and as we will use it often, it is better to use this type of variable.
A basic description of a global variable is one that, once declared, it belongs to no instance in particular and yet can be accessed by all.
Game Maker Studio
Draw the grid with the draw_line() function
To view our 2D table we can use the debugging tool provided by Game Maker Studio, and then look at what is in the variable global.grid
. The second solution is to draw it on the screen. Knowing that this solution facilitates our life during the debugging phase, here is what we must write in the draw event
of the object oGrid
to make our grid appear:
// Draw event oGrid
// Set opacity & color
draw_set_alpha(.5);
draw_set_color(c_green);
// Loop trought each row and column
for (var i = 0; i < gridWidth; i+=1){
draw_line(0, i*boxSize, room_width, i*boxSize);
}
for (var j = 0; j < gridHeight; j+=1) {
draw_line(j*boxSize, 0, j*boxSize, room_height);
}
// Reset opacity & color
draw_set_color(c_white);
draw_set_alpha(1);
With these few lines of code, we now display the 400 cells (20 * 20, I'm a math whiz, but this is good) of our level:
draw_set_alpha
anddraw_set_opacity
allow you to change the opacity and color of the lines- The two loops
for
go through the grid - And
draw_line
draws horizontal and vertical lines at each iteration

Adding walls in the level
Let's add elements to our level and then transfer them to our grid. I propose that we add walls: to do this, we need to create a oWall
and assign it a sprite
. For this tutorial, I advise to use a sprite of 32px by 32px.
Then use the room editor in Game Maker to place the object in question in the level. To make it easier let's set the grid size to 32px
and use the snap
This way the elements will always be positioned on a multiple of 32.

At this point we have a grid drawn and objects in our level, but the two are not linked. Indeed, the objects are present in the room, but at no time have we added them to our global.grid
. I don't want to keep the suspense going any longer, that's what we'll do now.
Inserting the walls in the grid
// Create event oWall
// Array position
var _x = x / oGrid.boxSize;
var _y = y / oGrid.boxSize;
// Add id to the array
array_set(global.grid[_x], _y, id);
Congratulations, every object oWall
of our room is now added to our grid when it is created. Be careful, for this to work, make sure that the oGrid
is created before your objects oWall
in the order of creation of your room, otherwise you will try to access a variable that does not yet exist.

Add objects on several squares at the same time
Let's imagine a world where one of your walls is 32px wide and 16px high (incredible, I know). With our code, it will be added only on the square where it originates, and not on all the squares it overlaps. Here's how to fix this problem:
// Create event oWall
// Array position
var _x = x / oGrid.boxSize;
var _y = y / oGrid.boxSize;
// Obj size
var _width = sprite_width / oGrid.boxSize;
var _height = sprite_height / oGrid.boxSize;
// Add the id of the object on the grid
for (var i = 0; i < _width; ++i) {
for (var j = 0; j < _height; ++j) {
// Add id to the array
array_set(global.grid[i + _x], j + _y, id);
}
}
- We calculate the size of the object in relation to its variables
sprite_width
andsprite_height
- We translate this into number of cells with
/ oGrid.boxSize
- We loop on these and modify
array_set()
to add the object on the boxes in question
Detect the walls contained in the grid
That's great, now our grid contains the ID of the objects added to the room. Let's try to modify our code to view the grid to show the boxes blocked by walls.
// Draw event oGrid
// Set opacity & color
draw_set_alpha(.5);
draw_set_color(c_green);
// Loop trought each row and column
for (var i = 0; i < gridWidth; i+=1){
draw_line_width(0, i*boxSize, room_width, i*boxSize, 1);
}
for (var j = 0; j < gridHeight; j+=1) {
draw_line_width(j*boxSize, 0, j*boxSize, room_height, 1);
}
// Display values
for (var i = 0; i < gridWidth; i+=1) {
for (var j = 0; j < gridHeight; j+=1) {
var _value = array_get(global.grid[i], j);
if(_value != 0) {
draw_set_color(c_red);
draw_rectangle(i * boxSize, j * boxSize, i * boxSize + boxSize, j * boxSize + boxSize, false);
}
}
}
// Reset opacity & color
draw_set_color(c_white);
draw_set_alpha(1);
- Our table is browsed with the loops
for
- Then the values contained for each iteration are retrieved with
array_get(global.grid[i], j)
- And finally, if it is different from 0 which is our base value, we display a red rectangle with
draw_rectangle()

Conclusion
We have a grid, which contains the walls of our room, and we know how to detect them. And that's it for this tutorial! Here is what you can do next:
- Add more than one object per box
- Destroy a wall by clicking on the right square
- Adding elements on the fly
- Move a character square by square, checking for collision
- Or use path finding algorithms to ensure that a path is available
If you have any questions about this tutorial or a specific need, let me know in comments so we can talk about it together.
See you later!