Simple Lighting (Surfaces)

As requested, I’d like to do a quick entry about simple lighting systems in Game Maker Studio. The following does not use any extensions or complex code. All you will need is a controller object and some basic knowledge of how surfaces work in Game Maker.

Instead of going to far in depth about this, I’ll just show you what I’m doing and I’ll let you do some further research if you’d like to accomplish more with your lighting system.

To begin, you will need an object that will handle your lighting. In my project, I call it ‘objDarkRoom’ because it actually makes the room dark as well as handling the light sources.


// Create a surface the size of the current room
// You could also create a surface the size of the current view, but I won't get into that
surf = surface_create(room_width, room_height);

// The following two lines clear the surface
// There is no guarantee that the surface doesn't contain garbage info post-creation
draw_clear_alpha(c_black, 0);

// Reset to application surface


// Surfaces are volatile 
// Always check that they haven't been destroyed 
if (surface_exists(surf)) {

    // The following three lines set the 'dark' overlay
    draw_rectangle(0, 0, room_width, room_height, 0);

    // Setting the blend mode to 'subtract' is what allows us to "cut holes" out of the overlay
    // Draw circles in the overlay with your different light sources
    // Note that I add randomization to the position and radius to mimic a flicker effect
    with (oLantern)
        draw_circle(x + random_range(-1, 1), y + random_range(-1, 1), 30 + random_range(-1, 1), false);
    with (oParticleLantern)
        if (image_xscale > 0.25)
            draw_circle(x + random_range(-1, 1), y + random_range(-1, 1), 2 + random_range(-1, 1), false);
    // Reset all of your draw stuff
} else {
    // Again, surfaces can be a pain
    // Create a new one if there were issues
    surf = surface_create(room_width, room_height);
    draw_clear_alpha(c_black, 0);

// Apparently I moved my fog layer with 'objDarkRoom', haha
background_x[1] -= 0.5;


// Clean up the surface memory manually
if (surface_exists(surf)) 


NOTE: I am using the DRAW END EVENT rather than the DRAW EVENT. I'm not sure if there is any drawback to this. I use it because I can guarantee that 'objDarkRoom' will run its draw code LAST. If you use the typical draw event, be sure that this object is on the highest layer (lowest number), otherwise objects/tiles could draw on top of the overlay.

// Draw the surface or create a new one
// Be sure to use views, even if it isn't necessary for your game
// This trick bypasses an issue with resizing the game window
// DX requires that surfaces be destroyed when resizing
if (!surface_exists(surf)) {
    surf = surface_create(room_width, room_height);
} else {
    if (view_current == 0) {
        draw_surface(surf, 0, 0);

Questions, comments, concerns? Shoot me an email at zbell91[AT]comcast[DOT]net.


Simple Lighting (Surfaces)

2 thoughts on “Simple Lighting (Surfaces)

    1. DirectX requires that all surfaces be destroyed when resizing a window. There is currently no way around that. I believe there is an event pertaining to window resizing. You could create a new, resized one.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s