• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker layer_script_end not executed due to event_type=/=0

svenh

Member
Hi all,

I have a tile layer in my room that I want to use as a surface together with other layers in a shader.
In the object that sets the shader in the draw event, I have this in the create event to transfer the tile layer to a surface:
GML:
SurfaceTileLayer = layer_get_id("LightingLayer");
layer_script_begin(SurfaceTileLayer, SurfaceLayerSet);
layer_script_end(SurfaceTileLayer, SurfaceLayerReset);
With the following scripts:
Code:
function SurfaceLayerSet(){
if event_type == ev_draw {
    var ViewWidth    = camera_get_view_width(view_camera[0])
    var ViewHeight    = camera_get_view_height(view_camera[0])

    if (!surface_exists(global.ColDepLightSurSurface)) {
        global.ColDepLightSurSurface = surface_create(ViewWidth,ViewHeight);
    }
 
   if event_number == 0 {
       surface_set_target(global.ColDepLightSurSurface);
       draw_clear_alpha(c_white, 0);
    }
}
}
Code:
function SurfaceLayerReset(){
if event_type == ev_draw {
   if event_number == 0 {
       //draw_text(object0.x,object0.y,"Layer closed")
       surface_reset_target();
    }
}
}
To test if the surface exists/looks correct, I have the following (among others) in the draw event of the object that sets the shader:
Code:
draw_surface(global.ColDepLightSurSurface,viewx,viewy)
The surface is not shown.

I narrowed the problem down to the fact that if event_type == 0 {} is not executed in the SurfaceLayerReset function. In the SurfaceLayerSet function it is. This I don't understand.

A second thing I tried is to use if event_type == ev_draw_begin, so that the scripts are executed before the draw event with the shader.
This simply draws the tile layer in the room, but the surface still does not exist/is not drawn. This I don't understand either.
Is someone able to help me with this problem?

Many thanks in advance!
 
Last edited:

svenh

Member
Why is this a hardcoded zero? The named constants for event_number are in the Manual and you should be using those. What happens when you make the appropriate change?
I assume it means the main draw event will be taken. Which is also said in this part of the manual.
But I also tries it with ev_draw_begin which doesn't work either.
It's overall strange as the larger part is exactly the same as the example in the manual linked.
 

Nidoking

Member
Why would the layer end drawing in the Draw Begin event? And why are you concerned with which Draw event it is, anyway?

Perhaps more importantly, if the event_number isn't zero, what is it? And which constant does it correspond to?
 

svenh

Member
Why would the layer end drawing in the Draw Begin event? And why are you concerned with which Draw event it is, anyway?

Perhaps more importantly, if the event_number isn't zero, what is it? And which constant does it correspond to?
I don't quite understand what you are trying to ask? Normally, the scripts are called at the end/beginning of each draw event. The draw_event is checked so that the script will run only during that specific draw event.
My understanding is that during the main draw event, SurfaceLayerSet is called, the layer is drawn (on the surface) and then SurfaceLayerReset is called.
SurfaceLayerReset is called but not during the main draw event as event_number is not 0. I don't know why. That's what my question is/was about.
 

NightFrost

Member
The manual is a little obtuse here because the main explanation is on event_perform and its extended examples page and it seemingly doesn't want to repeat content. The hardcoded zero comes from the examples and is only explained in the event_perform syntax: "numb: The specific event constant or value, if one is necessary (otherwise, just use 0)."

Looking at this and other event_perform examples, it looks like the proper way to detect main Draw Event is to check that event_type == ev_draw && event_number == 0 while Draw Begin would be event_type == ev_draw && event_number == ev_draw_begin. I assume any code left outside event_number check would be ran in all draw events.

(I can't actually test any of this at the moment.)
 

svenh

Member
The manual is a little obtuse here because the main explanation is on event_perform and its extended examples page and it seemingly doesn't want to repeat content. The hardcoded zero comes from the examples and is only explained in the event_perform syntax: "numb: The specific event constant or value, if one is necessary (otherwise, just use 0)."

Looking at this and other event_perform examples, it looks like the proper way to detect main Draw Event is to check that event_type == ev_draw && event_number == 0 while Draw Begin would be event_type == ev_draw && event_number == ev_draw_begin. I assume any code left outside event_number check would be ran in all draw events.

(I can't actually test any of this at the moment.)
Thanks, that works like I expected. Do you perhaps know why everything in event_number == 0 {} is not executed in the SurfaceLayerReset function but it is in the SurfaceLayerSet function? This is a mystery to me and prevents the shader from working.
 

svenh

Member
I did a little more testing and the code in SurfaceLayerReset is executed. A debug message is showing, but when uncomment the draw_text line in the function it doesn't show.
The draw_surface line still doesn't draw the surface. I don't get this at all :/
 

NightFrost

Member
Is the object0 you're referencing set far into the room? Because the draw_text isn't going to behave as if framed in camera, and will treat (0,0) as the top left corner of the surface, not the top left corner of the room. So if the object is at something line (2000,2000) that's the surface position the text will be drawn to. Try a very small offset in the draw.
 

svenh

Member
Is the object0 you're referencing set far into the room? Because the draw_text isn't going to behave as if framed in camera, and will treat (0,0) as the top left corner of the surface, not the top left corner of the room. So if the object is at something line (2000,2000) that's the surface position the text will be drawn to. Try a very small offset in the draw.
No it's the player's object. Putting the same draw_text in the same position of the SurfaceLayerSet Function is showing the text. Here is the room in the room editor.
The colored surfaces are what I'm trying to draw on a surface. It is used by the shader to cast light on a surface depending on the direction of the light sourse/surface that is illuminated. The shader works. But now I'm trying to simplify the use of the colored surfaces by make it possible to put them in a tile layer, instead of (what I'm doing currently) give a sprite to an object and let every object with the same parent draw that sprite onto a surface.
1639753122064.png
 

svenh

Member
I found the problem! The surface used to draw the tile layer on had the size of view_width and view_height and was subsequently drawn on the x- and y-coordinates of the view. This doesn't work since the tile layer has the size of the room. Thanks for the help guys! I appreciate it. Will post something soon with the result!
 
Top