• Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

GMS 2.3+ Debugger Help

TsukaYuriko

☄️
Forum Staff
Moderator
Pause the game by clicking the pause button.

Switch to the Instances tab. The Instance (sans s) tab inside of that shows info about whatever is currently in scope. The All Instances tab shows info about all instances.
 

Roldy

Member
Review the manual: Watches
Debugger


When running in Debug mode the debugger needs to break and pause the application before it is very useful.

Either:
  • set a break point
  • press the pause button on the debugger toolbar
The tabs towards the bottom (Locals, Instances, Variables, Watches etc.. ) will give you the most useful info.

Another useful bit of info is when inspecting data structure types (List, Maps etc..) the variables will just show the index number of the structure, but you can view them as a proper structure if you right click them and choose the appropriate 'view as' context option.
 
Pause the game by clicking the pause button.

Switch to the Instances tab. The Instance (sans s) tab inside of that shows info about whatever is currently in scope. The All Instances tab shows info about all instances.
That explains a lot, the tutorial I watched wasn't clear on "you have to pause the game first" part
 
Pause the game by clicking the pause button.

Switch to the Instances tab. The Instance (sans s) tab inside of that shows info about whatever is currently in scope. The All Instances tab shows info about all instances.
Okay, I get the debugger to open and show the code for a random object in the room it's choosen when I pause but I can't figure out to switch instances in the debug code window because the instance list is only showing that one random object as in scope despite the player an and enemy being on screen

I also can see that enemy as the selected instance but can't get his code to show, just the general code for all instances that enemy
 

Attachments

Roldy

Member
Please read the manual:
Debugger
Watches
breakpoints

In the screen shot you showed you can see the 'Instances' tab. It list all instances currently in the game. You can open each and inspect there current values and variables.

To get to specific places in code use breakpoints to stop the debugger when and where you want. Unfortunately the GMS debugger does not support conditional breakpoints so you will have to do it the old school way:

GML:
// Some examples

// If you want the debugger to pause after 30 frames do something like

if (frameCount >= 30) {
    var breakHere = 1; // Set a breakpoint on this line
}
frameCount++;

// If you wanted to stop the debugger on a specific instances draw event then add a line
// at the start of the objects draw event

if (id == 1000120) { // some id for the specific instance
    var breakHere = 1; // Set a breakpoint on this line
}

// If you want the debugger to pause when something collides with the player
var collision = instance_place(...);
if (collision.object_index == obj_player) {
    var breakHere = 1; // Set a breakpoint on this line
}
Usually though you don't have to be so conditional. Just put breakpoints in your existing code where you want to pause. e.g. want to pause on the players step event, then put a breakpoint at the beginning of the players step event.
 
Last edited:
Please read the manual:
Debugger
Watches
breakpoints

In the screen shot you showed you can see the 'Instances' tab. It list all instances currently in the game. You can open each and inspect there current values and variables.

To get to specific places in code use breakpoints to stop the debugger when and where you want. Unfortunately the GMS debugger does not support conditional breakpoints so you will have to do it the old school way:

GML:
// Some examples

// If you want the debugger to pause after 30 frames do something like

if (frameCount >= 30) {
    var breakHere = 1; // Set a breakpoint on this line
}
frameCount++;

// If you wanted to stop the debugger on a specific instances draw event then add a line
// at the start of the objects draw event

if (id == 1000120) { // some id for the specific instance
    var breakHere = 1; // Set a breakpoint on this line
}

// If you want the debugger to pause when something collides with the player
var collision = instance_place(...);
if (collision.object_index == obj_player) {
    var breakHere = 1; // Set a breakpoint on this line
}
Usually though you don't have to be so conditional. Just put breakpoints in your existing code where you want to pause. e.g. want to pause on the players step event, then put a breakpoint at the beginning of the players step event.
1)If documentation and tutorials at all helped me I wouldn't be asking how to work it here, now would I?

2)Reading variables or breakpointing an entire object doesn't help figure out why complex code as a whole is not working right on a specific instance of it in the room hitting specific conditions. Especially if it's re-using gravity code that several objects are using as a script function.
 

Roldy

Member
2)Reading variables or breakpointing an entire object doesn't help figure out why complex code as a whole is not working right on a specific instance of it in the room hitting specific conditions. Especially if it's re-using gravity code that several objects are using as a script function.
o_O
 
To repeat myself:

If the object has several instances in the room just breakpointing that object so the first instance to run it pauses the code isn't going to help me. Especially when I can't figure out to view code in the debugger in a way that tells me which instance of the object it applies to

Especially if that code is a script function that's being used by two different enemy types AND the player because it's a basic gravity routine.
 

Roldy

Member
To repeat myself:

If the object has several instances in the room just breakpointing that object so the first instance to run it pauses the code isn't going to help me. Especially when I can't figure out to view code in the debugger in a way that tells me which instance of the object it applies to

Especially if that code is a script function that's being used by two different enemy types AND the player because it's a basic gravity routine.
You seem to be having problems and are frustrated. So I will give you the benefit of the doubt and assume you are saying silly things due to your frustration.

Calm down and read.

Especially when I can't figure out to view code in the debugger in a way that tells me which instance of the object it applies to
When the debugger breaks the 'Instance' tab shows you the current scope. In your screen shot I have highlighted it. Opening the 'Built-in variables' listing will show you the id of the current instance.
1617840613963.png

Every instance has an id. The second tab 'All Instances' shows you every instance currently in the game. Expanding those lets you inspect them: (This is highlighted in green below).
1617840733057.png

When the debugger breaks use the tools to step in, over, and out of code. Pay attention to the call stack it is highlighted below. Everytime you step, code is executed and values change. Step slowly, inspect what is relevant and get a solid idea of what has just happened, what is about to happen, what you expect the results will be, and how those results match your expectations.
1617841499023.png
The first step in trying to isolate bugs is to create a reproduceable case. 100% reproduceable is the goal, but you can't always get there. Just narrow down the conditions to get the issue to occur as often and reliably as possible; idealy in the exact same way every time or close to it. This allows you to not only reliably examine the issue but will also act as a test that you fix the issue once you fix it. The process of creating a reproduceable case will typically increase you understanding of the problem.

Once you have a reproduceable case then try and narrow down the exact conditions. This can be done by setting breakpoints at various places in the code and inspecting variables BEFORE and AFTER the issue. As well show_debug_messages can help in this regard to help isolate the exact timing and positioning.

The more conditions you can identify that cause the problem the more you will understand it and the more easily you can set conditional breakpoints to eventually break exactly before the problem occurs and STEP through and see it occur. Look at my previous post for an idea of what I mean by conditional breakpoints.

As a note of caution, be very aware of any code you have that is based on delta time. Pausing the runtime will typically have unwanted effects on code based on delta time. For debugging purposes consider refactoring so any reference to a delta time instead uses a fixed time.

These are the tools available. They are only tools and you will need to find ways to use them. You can't open the debugger and have it just show you the problem. Debugging is just as much a skill and an involved task as any other part of development. Use anything and everything you have access to (mainly your imagination) and try to figure out what is going on in your code.

The debugger along with the show_debug_message are invaluable tools but the main tool will remain your intelligence and imagination. Relax, take deep breathes and engage your brain.

I strongly recommend reading the manual. Read the manual, use the debugger to verify your understanding, when you run into problems then come back here and ask SPECIFIC questions.

Good luck.

EDIT: At times you will find the best debugging tools are those you make yourself. If you think you will do better with visual data then draw your data to the screen to help you see what is going on; like simply outputting text over your instances to show their values or drawing motion lines and collision points etc...
 
Last edited:
You seem to be having problems and are frustrated. So I will give you the benefit of the doubt and assume you are saying silly things due to your frustration.

Calm down and read.



When the debugger breaks the 'Instance' tab shows you the current scope. In your screen shot I have highlighted it. Opening the 'Built-in variables' listing will show you the id of the current instance.
View attachment 39370

Every instance has an id. The second tab 'All Instances' shows you every instance currently in the game. Expanding those lets you inspect them: (This is highlighted in green below).
View attachment 39372

When the debugger breaks use the tools to step in, over, and out of code. Pay attention to the call stack it is highlighted below. Everytime you step, code is executed and values change. Step slowly, inspect what is relevant and get a solid idea of what has just happened, what is about to happen, what you expect the results will be, and how those results match your expectations.
View attachment 39373
The first step in trying to isolate bugs is to create a reproduceable case. 100% reproduceable is the goal, but you can't always get there. Just narrow down the conditions to get the issue to occur as often and reliably as possible; idealy in the exact same way every time or close to it. This allows you to not only reliably examine the issue but will also act as a test that you fix the issue once you fix it. The process of creating a reproduceable case will typically increase you understanding of the problem.

Once you have a reproduceable case then try and narrow down the exact conditions. This can be done by setting breakpoints at various places in the code and inspecting variables BEFORE and AFTER the issue. As well show_debug_messages can help in this regard to help isolate the exact timing and positioning.

The more conditions you can identify that cause the problem the more you will understand it and the more easily you can set conditional breakpoints to eventually break exactly before the problem occurs and STEP through and see it occur. Look at my previous post for an idea of what I mean by conditional breakpoints.

As a note of caution, be very aware of any code you have that is based on delta time. Pausing the runtime will typically have unwanted effects on code based on delta time. For debugging purposes consider refactoring so any reference to a delta time instead uses a fixed time.

These are the tools available. They are only tools and you will need to find ways to use them. You can't open the debugger and have it just show you the problem. Debugging is just as much a skill and an involved task as any other part of development. Use anything and everything you have access to (mainly your imagination) and try to figure out what is going on in your code.

The debugger along with the show_debug_message are invaluable tools but the main tool will remain your intelligence and imagination. Relax, take deep breathes and engage your brain.

I strongly recommend reading the manual. Read the manual, use the debugger to verify your understanding, when you run into problems then come back here and ask SPECIFIC questions.

Good luck.
Okay, I'm almost there and this seems to be the Skully I need to check judging by his ID and the room creation order but how do I do I actually see inside the script function and break within it?
 

Attachments

Roldy

Member
Okay, I'm almost there but how do I do I actually see inside the script function and break within it?
Im not 100% sure what you are asking.

If in the screenshot above you have successfully paused in the Step event on the line gravity_step() and you want to know how to go into the gravity_step function?


At the top of the script debugger script window are some buttons:
1617842703424.png

Step in, Step Over, Step Out

These also have keyboard shortcuts F10, F11, Shift+F10
These are described in the manual: Debugger
If that is not what you mean then ask again with clarification.
 

samspade

Member
That explains a lot, the tutorial I watched wasn't clear on "you have to pause the game first" part
You can actually see the values in instances without pausing if (1) real time debugging is turned on, and (2) you are looking at the all instance tab and not the instance tab. However, code is obviously updating really fast (probably 60 times per second) and so only updates that are stable for seconds at a time are really going to be visible without pausing. Still, inspecting instances in the all instance tab while the game is running can be incredibly useful.

Okay, I'm almost there but how do I do I actually see inside the script function and break within it?
Choose the step into button function call button (F11) - this has to be a custom function you can't step into built in ones. (beaten to it)

Also, if you want to see the values inside of the function - you should have the locals debugger window open. This will show you the argument variables, temporary variables and so on for the function.
 
Im not 100% sure what you are asking.

If in the screenshot above you have successfully paused in the Step event on the line gravity_step() and you want to know how to go into the gravity_step function?


At the top of the script debugger script window are some buttons:
View attachment 39375

Step in, Step Over, Step Out

These also have keyboard shortcuts F10, F11, Shift+F10
These are described in the manual: Debugger
If that is not what you mean then ask again with clarification.
Yeah, what I'm wanting to do is actually see the code that's being run inside my custom function so I can step through it and find where it's glitching out in regards to that instance running it
 
So I found an interesting bug in my code, I think?

For some reason when running this code it seems to be skipping over the while loops in some weird way that make him float in the air?

Yeah, 100% what's happening. Despite floating above the floor the check is returning false and I can't seem to find the cause.
 

Attachments

Last edited:

Roldy

Member
So I found an interesting bug in my code, I think?

For some reason when running this code it seems to be skipping over the while loops in some weird way that make him float in the air?

Yeah, 100% what's happening. Despite floating above the floor the check is returning false and I can't seem to find the cause.
In the future post your code using the code tool of the forum instead of a screenshot.
1617852222417.png

Without know exactly what you are doing I think you have several errors:

GML:
var T_Y = y + vspd; // Here T_Y includes y

// Now again you add y to T_Y so effectively you have 2*y+vspd
if collision_line(x+2, y+T_Y, x+R_X, y+T_Y, ...) {
...
}
As well even though your comment says "find ceiling" which would imply a vertical line, the collision_line is casting a horizontal line (start y and end y are the same). Review the documentation for collision_line and look at the parameters: collision_line

There are several magic numbers here in your code. Review your code and double check it makes sense. Give you magic numbers names along with explanations of why they are what they are.
 
In the future post your code using the code tool of the forum:
View attachment 39378

Without know exactly what you are doing I think you have several errors:

GML:
var T_Y = y + vspd; // Here T_Y includes y

// Now again you add y to T_Y so effectively you have 2*y+vspd
if collision_line(x+2, y+T_Y, x+R_X, y+T_Y, ...) {
...
}
As well even though your comment says "find ceiling" which would imply a vertical line, the collision_line is casting a horizontal line (start y and end y are the same).

There are several magic numbers here in your code. Review your code and double check it makes sense. Give you magic numbers names along with explanations of why they are what they are.
I just posted the code that way to show the variable values down the status window for reference.

Let me break code here:

1)It is a horizontal line being drawn above the players head that checks all the way across to check to see if there's a ceiling above them

2)Also, I don't think so. i think the way I have it written is object.y+T_Y = current position to check for collision. ( ie: look for floor object height + vspd from the top of it's sprite)
 
Last edited:

Roldy

Member
1)It is a horizontal line being drawn above the players head that checks all the way across to check to see if there's a ceiling above them
Ok, that could work.

Also double check the math for the y when checking floor and ceiling. Remember y increases downwards. I understand vspd may be negative or positive but make sure everywhere you are adding to y and meaning to look up or down that it will in fact be correctly positive or negative.

Hopefully you have the hang of the debugger now, which I believe was the point of the thread.
 
Ok, that could work.

Also double check the math for the y when checking floor and ceiling. Remember y increases downwards. I understand vspd may be negative or positive but make sure everywhere you are adding to y and meaning to look up or down that it will in fact be correctly positive or negative.

Hopefully you have the hang of the debugger now, which I believe was the point of the thread.
Yeah, I think I'm picking up on the debugger and wondering if maybe I should make another thread with the indentified problem that's stumping me.

The first big one I'm seeing already is that the ceiling check seems to be erroneously triggering every step when this should just be harmless checking a spot in the middle of the object for the floor and finding nothing if they're falling

GML:
//find ceiling and hit it
if collision_line(x+2, y+vspd, x+R_X, y+vspd, Solid_Floor_Obj, false, true){
   
    while !collision_line(x+2, y, x+R_X, y, Solid_Floor_Obj, false, true){
    y += sign(vspd);    
    }

vspd = 0;
}
 
Top