SOLVED Draw End Event not happening

ELB

Member
Hi, I have a long standing project I recently moved from GMS 1.4 to GMS 2, and although the transition has been very clean, (props to the GMS 2 dev team on that one,) I came across what I’m thinking is a bug in GMS 2. My game is a top down game, where I am shifting the depth of the instances in the game based on their Y position. I’m sure you’ve all seen a similar technique done a million times, which made me surprised I only found one post about a similar bug here.


missing draw end.gif


So what’s actually happening? When the depth is shifted higher, (and further down on the managed layers,) sometimes all the draw events other than the main one will just not happen. If I disable my depth shifting, it doesn’t happen. As you can see in this gif of my game, the HUD, which is drawn on the End Draw event, will not draw. I’ve tested to make sure the entire event is in fact just not happening. Although I don’t know the direct cause, I do know that it’s affected by multiple instances going to the same depth. As you can see in the gif, I have 30 other creatures in the zone to the right, and those creatures have weapons (their heads) that can shift depth as well. Although they can shift their depth as well, they have not, due to not moving. If there are no other depth shifting instances (creatures and weapons) in a room, this bug will not happen, (though it will still happen if the creatures were there, then were destroyed due to dying). Although it’s easy to reproduce the bug, I have not yet figured out the specific cause. Haven’t seen any real patterns, other than the fact that when it does happen, the bug only activates when I move upward, which causes the depth value to increase.

So what the heck? Does anyone know anything about this bug? Is there some pitfall I may have missed when it comes to how depth is handled in GMS 2? I know that GMS 2 now has layers, which are preferred to depth, but depth isn’t deprecated, and mostly still works the same. I’ll be happy to report the bug on proper channels if it’s not already known.

Edit: Just realized I put in the wrong image. Here's the one I meant to use, which shows the enemies off to the side.
 
Last edited:

ELB

Member
Gms2 creates a new layer when you change depth. So there could be an issue with layers blocking each other.
I know that GMS 2 places instances on what's known as a managed layer if you modify the depth through code, but I don't understand how that affects the draw end event. Is layers blocking each other a potential pitfall in GMS 2? Got any sort of resource that talks about that and how to avoid it?
 

Yal

🐧 *penguin noises*
GMC Elder
Are any of the depths outside the range -16,000 ~ 16,000 ? Those are the new limits for valid depths; anything that is outside that span will be treated as having the same depth and will essentially be drawn in a random order. There's a function to lift this limit and force using the old 64-bit depth, but it slows down performance.

The GMS2 way to do this would be having depth-sorted objects added to a priority queue (using y as priority) and then have a controller object draw them in that order rather than them drawing themselves. (Just make them non-visible and then use event_perform in a with loop to execute their draw event)
 

ELB

Member
Are any of the depths outside the range -16,000 ~ 16,000 ? Those are the new limits for valid depths; anything that is outside that span will be treated as having the same depth and will essentially be drawn in a random order. There's a function to lift this limit and force using the old 64-bit depth, but it slows down performance.

The GMS2 way to do this would be having depth-sorted objects added to a priority queue (using y as priority) and then have a controller object draw them in that order rather than them drawing themselves. (Just make them non-visible and then use event_perform in a with loop to execute their draw event)
There are no depths outside that range. They should be closely following the y coordinate.

Thank you for the suggestion though. I'd been so stuck on trying to get my method to work, I'd not thought of something like that at all. I'll give it a shot, then update on whether or not my bug somehow persists, (though I doubt it will if I drop using depth entirely.)
 

TheouAegis

Member
Well depth isn't the issue, or it shouldn't be, because I just did a test project where I increased depth by 1 each step and drew the depth in the Draw End event; no issues. I figured maybe it was because it changed depth so fast, so I tried again but set it to depths of multiples of 100 every 100 steps; no issues.

I still lean toward an issue with visible or image_alpha, possibly a misdirected variable reference. Is this in GMS2.2 or in GMS2.3? If it's in GMS2.2, move the object drawing the HUD down the resource tree so that its object_index gets changed (this doesn't work in GMS2.3).

Why aren't you using the GUI event? Just for sake of interactivity?
 

Roldy

Member
When are you doing the layer shifting?

If you are doing it during the draw phase then I would imagine you are going to have problems. For instance if you do the shift during the actually Draw Event and you shift to a layer that has already been drawn then the Draw End event would not be triggered. (I cannot test atm but I believe that would be the correct behavior).
 

TheouAegis

Member
When are you doing the layer shifting?

If you are doing it during the draw phase then I would imagine you are going to have problems. For instance if you do the shift during the actually Draw Event and you shift to a layer that has already been drawn then the Draw End event would not be triggered. (I cannot test atm but I believe that would be the correct behavior).
That was a great hypothesis, but I tested just now by moving my depth++ code (both versions) to the Draw Event, and the Draw End event still ran even at depths. That was a great idea though.
 

ELB

Member
Thank you all for the responses and thoughts. I have yet to take the time to implement Yal's suggestion.

Well depth isn't the issue, or it shouldn't be, because I just did a test project where I increased depth by 1 each step and drew the depth in the Draw End event; no issues. I figured maybe it was because it changed depth so fast, so I tried again but set it to depths of multiples of 100 every 100 steps; no issues.

I still lean toward an issue with visible or image_alpha, possibly a misdirected variable reference. Is this in GMS2.2 or in GMS2.3? If it's in GMS2.2, move the object drawing the HUD down the resource tree so that its object_index gets changed (this doesn't work in GMS2.3).

Why aren't you using the GUI event? Just for sake of interactivity?
I think I made a test project where I was able to get the bug to trigger at some point, though I don't think I saved it. Just now I tried to make a test project to trigger the bug, but I was unable. As far as I've been able to tell, it's because multiple things are at the same depth at once, which is why this bug only triggers when at the same level as the enemies, because they're at the same depth.

Considering I didn't have this bug until I went from GMS 1.4 to GMS 2.2, I don't believe it's an issue of visible or image_alpha, though I'm not discounting those suggestions in case there's some new thing about how code is dealt with that I don't understand. That being said, I tried to run show_debug_message(current_time) from the very first line of draw_end event, and it doesn't show the message when the bug is occurring, which leads me to believe the event itself is not running.

If I recall correctly, I didn't use the GUI event so I could keep the pixel size uniform no matter what size the game window was at. I don't know if that changed with GMS 2, or if I misunderstood how that worked in GMS 1.4.

When are you doing the layer shifting?

If you are doing it during the draw phase then I would imagine you are going to have problems. For instance if you do the shift during the actually Draw Event and you shift to a layer that has already been drawn then the Draw End event would not be triggered. (I cannot test atm but I believe that would be the correct behavior).
I only change depth during the end step event.
 

kburkhart84

Firehammer Games
I think with 2.3 in beta, it would be extremely helpful if you could reproduce it in a small project. Someone(I wouldn't mind volunteering if you aren't already doing the beta test yourself) should import into 2.3 and see if it still happens, and then report it in the beta forum. I personally have never ran into this issue, but if its reproducible, its likely a bug we can get fixed. If you have to, you could submit the project as is, they won't steal your sprites or anything.
 

Yal

🐧 *penguin noises*
GMC Elder
That was a great hypothesis, but I tested just now by moving my depth++ code (both versions) to the Draw Event, and the Draw End event still ran even at depths. That was a great idea though.
I'm pretty sure that at the start of the draw event, everything is just priority-sorted by the current depth and added to a big list of stuff to be drawn, and further depth changes might not affect anything until the next step. But there's a total of 24 total invocations (8 views x begin, standard, end) and the sorting might be redone for each of those. (One of the old GM8--->GMS1 performance issues was that each draw event did a bubble sort of all instances, so the just-in-time sorting at least existed in the past... it's more optimized now when the layer system gives fewer things to sort, but we're caring about event ordering now, not performance)

You could test this by having a low-depth object turn all layers invisible in its draw event and turn them visible again in its end step event, then have a background layer with a solid color below it and another background layer with a picture (or a different color) above it: if the upper layer draws, changes to visibility / depth won't affect an ongoing draw event.
 

ELB

Member
I think with 2.3 in beta, it would be extremely helpful if you could reproduce it in a small project. Someone(I wouldn't mind volunteering if you aren't already doing the beta test yourself) should import into 2.3 and see if it still happens, and then report it in the beta forum. I personally have never ran into this issue, but if its reproducible, its likely a bug we can get fixed. If you have to, you could submit the project as is, they won't steal your sprites or anything.
I've messed around with my test project and have been unable to reproduce the bug there. It's certainly very weird. I'm going to keep playing with it. For a moment I thought it might have been an issue with displaying multiple views at once, but that was not the case I found.

The GMS2 way to do this would be having depth-sorted objects added to a priority queue (using y as priority) and then have a controller object draw them in that order rather than them drawing themselves. (Just make them non-visible and then use event_perform in a with loop to execute their draw event)
So far implementing this has gone very well. I have other things I need to fix up, but this has gotten me around the bug. I'm curious how optimized this is compared to how it was, but there's no obvious performance dips. I had to run through copies of the queue multiple times to deal with the begin, mid, and end draw events, as well as to handle multiple views, so the single queue could be copied 24 times. Regardless, thank you very much for the suggestion. Despite a few hiccups at first, (because I forgot the draw event is called multiple times due to multiple views in use,) it's working very well.
 

ELB

Member
Update: Been slowly carving off absolutely everything from the game file that has no effect on the bug, and at this point I have real basic functionality left. There's more I can shave off, but I'm starting to become convinced this bug is born from the compatibility code. I no longer have 1.4 installed, so I can't truly verify this, and so far it's really just a hunch, after I've gone diving into the compatibility depth system. I'm going to continue removing anything I can, but it's getting far more difficult as I'm delving into some of the most core systems. I may have to begin replacing pieces of code with far simpler facsimiles in order to decouple the various systems. I'll also point out that the bug becomes far more pronounced if I restart the room. Where normally this bug would only happen when walking past the NPCs, if I reset the room for a few times, the bug continues upward, past the NPCs. It's very odd, and suggests it definitely has something to do with something in memory that isn't cleaned upon room restart.

 

ELB

Member
Update: It took me a long time, but I managed to isolate the bug enough to figure out what elements go into causing it, and I have somewhat of an idea. I discovered that the bug requires there to be a particle system at the same depth as the object that loses it's draw end event. The reason this is happening in my code is because each weapon (being each hand a creature has as seen in the gif of my previous post) has a particle system so it can do things like be on fire, covered in electricity, etc. This particle system will then change its depth to be on top of the weapon. As for why this bug only activates when going down in depth, I'm still unsure of. Regardless I managed to create a test project where I was able to recreate the bug. If you run this test project, it will constantly print a debug message with current_time and the number of instances with the same depth as the player character. The eyes and mouth on the face are being drawn in the draw end event, and when they vanish, it prints a higher number of entities being at that depth, in this case being 7, (6 hands + the 1 player character). I think this also explains, partially, why restarting the room was causing the issue to become more pronounced, being that restarting the room wasn't deleting the particle systems, so they were just adding to the bug.




I feel like I learned a lot about GMS 2, and it was an interesting experience tearing apart my own project to see where I can improve things for GMS 2, as well as just where I made weird choices. I'm planning on making a bug report if this is unknown, as well as set this thread to solved, but I'm going to wait a day first to see if anyone has anything else to add or point out. Thank you all for your help.
 
Top