GameMaker Tips For Beginners

Here are some tips which should help beginners do some things right and know what they might be doing wrong.

#1: Try reading the docs

Before Googling something or asking someone about an issue, make sure to check the relevant entry in the documentation – it may contain information that might help you solve your problem.

GMS 1 Docs

GMS 2 Docs

Suggested by Simon Gust

#2: Don’t copy-paste code without understanding

Sometimes you just want to make something work, so you copy over some code from a tutorial, even if you don’t understand how it works. While that appears to be fine, it’s only going to increase the trouble. In a project, you can’t have complete control over your workings if you don’t understand how any part of your code works.

You might think that it’d be a good idea to use a tutorial to build a game/system, but it’s not. Tutorials exist as a guide so that you can understand how things work. If you’re serious about something, code it yourself. Even if you do use code from a tutorial, do not attempt to modify it or expand upon it unless you understand how it works.

So before copying code over to your project, make sure you at least try to understand how it works. Read it. Google stuff. Ask others. Understand.

Suggested by Tthecreator

#3: Different values for different instances

Say you want to have two enemies, one with 4 HP and the other with 10. As a beginner, your first instinct might be to create another object and change the HP inside it. But there’s a solution.

When you place instances inside a room using the Room Editor, you can right click on them and open the “Creation Code” window (or in GMS2, double-click) and type code in it. This way, you can assign different HPs to different instances, inside their creation code.

Through the same menu, you can also change the scaling and rotation of the instance, and set a unique ID so that you can access that particular instance through code.

Suggested by Karolis Poviliūnas and John Benson

#4: Use place_meeting()

The function place_meeting() can be used for checking a collision with another object. It is better to use this function in a condition than using a collision event, since this way you have more control over how your collisions work.

place_meeting(x, y, obj)

The first and second arguments are the x and y coordinates where the collision will be checked, and the third argument is the object with which we’re checking a collision.

The first and second arguments to the function are usually set to x and y respectively. This is where to imagine your player is stationed in the room when the collision check is made. This is useful because you can check if the player is GOING to collide with an object by checking it with arguments like:

//check if the player is 5 pixels away from a solid wall on its right side
wall_on_right_side = false;
if (place_meeting(x+5,y, obj_solid)) {
    wall_on_right_side = true;

Suggested by Colton Phillips

#5: A better way of getting input

Most beginners use conditions to set input variables. For example:

var hsp;

if (keyboard_check(vk_right)) hsp = 1;
else if (keyboard_check(vk_left)) hsp = -1;
else hsp = 0;

However, there is an easier way. See:

var hsp = keyboard_check(vk_right) - keyboard_check(vk_left);

You know that keyboard_check() returns true if the key specified is being pressed, and false if it is not. But in GameMaker, true stands for 1 and false stands for 0 – they’re numbers, basically – so they can be used in an equation like this.

So if the right key is pressed, hsp becomes 1:

var hsp = 1 - 0;

If the left key is pressed, hsp becomes -1:

var hsp = 0 - 1;

And if nothing is pressed, it becomes 0:

var hsp = 0 - 0;

The same can be applied to the vertical position as well.

var vsp = keyboard_check(vk_down) - keyboard_check(vk_up);

Suggested by Isaac Steel

#6: Draw GUI event for HUD elements

For drawing the HUD in their games, some people either use objects, or draw it through the Draw event – adding their relative positions to the camera/view coordinates, so that the HUD follows the camera/view. But there is a simpler way of drawing HUD on the screen: the Draw GUI event.

Inside the Draw GUI event, you do not have to add the camera positions to make the HUD follow the camera. The event uses the game window coordinates instead of the room coordinates. So if you draw something at (0, 0), it will draw at the top left corner of the game window, not inside the room. So anything you draw there, stays there: its position is not affected by the camera in-game. It’s like having another layer over your base game.

#7: How the create functions work

In this tip, I will address something that creates confusion for beginner developers.

I am talking about the _create functions. These are functions you use to create something (surface, buffer, data structure, etc.) and store the result in a variable.

surface = surface_create(args);

list = ds_list_create();

buff = buffer_create(args);

Let’s take a DS list as an example. The function creates the list and stores it in the variable, right?

So this way, if I create the list in a local variable, it will be gone at the end of the event, because the variable is local. Right?

var list = ds_list_create();

Actually, that is not how it works. Whenever you create a list, it creates it inside the memory. That is where the list exists. The function just returns a pointer that points to the list inside the memory. So the variable you use as the “list” is just a pointer which allows you to access the actual list in the memory.

So, even if the variable is local, the list is not. Remember, the variable is just a pointer. So to destroy the list, you have to use:


This function will remove the list from the memory.

Also, when you do this:

list_1 = ds_list_create();

list_2 = list_1;

You’re not creating another list called “list_2” which is the same as “list_1”. You’re just copying the pointer value to that variable, so both of these variables point to the same list on the memory.

So this is the same with the other things, like surfaces, particle systems, and buffers. The variable is only a pointer to something that exists inside the memory until it is destroyed.

#8: Clear a surface when you create it

When you create a surface, it must be empty, right?

Well, that’s not always the case. See, when you destroy a surface, it frees up the memory, but does not clear it. So if you create a surface and it is created at the same memory block where a destroyed surface once existed, the contents from the destroyed surface might carry into the new one.

So when you create a surface, make sure you clear it:

surf = surface_create(32, 32);

draw_clear_alpha(0, 0);

Suggested by sp202

#9: Script execution vs. script ID

Say you have a script called getFive, with the following code:

return 2+3;

If you do this somewhere:

var store = getFive();

It will execute the getFive script, returning 2+3, which is 5. That value will be stored in store.

If you do this, though:

var store = getFive;

Then it will return the resource ID of the script, and will not execute it. That script’s ID will be stored in store. You will be able to execute that script later on using script_execute():


So, having parentheses executes a script, whereas not having them returns the script’s ID.

If you have any tip to suggest, tell us through the contact form on the About page.