Quick answer: Surfaces live in volatile GPU memory and can vanish on alt-tab, resolution change, or device loss. Check surface_exists every frame and recreate + repopulate when gone.

A game caches a lighting buffer in a surface. After the player alt-tabs, the screen goes black — the surface was freed by the OS and never recreated.

Always Guard Surface Use

// Draw event
if (!surface_exists(light_surf)) {
    light_surf = surface_create(surf_w, surf_h);
    rebuild_lighting();   // repopulate contents
}

surface_set_target(light_surf);
// ... draw lights ...
surface_reset_target();

Never assume a surface persists across frames. Check, recreate, repopulate.

Separate Creation from Population

Keep the “rebuild contents” logic in its own function. Both initial setup and post-loss recovery call it. Don’t duplicate the drawing code.

Application Surface

The built-in application_surface can also be lost. GameMaker recreates it automatically, but if you draw to it manually, guard with surface_exists(application_surface) too.

Resolution Changes

Switching fullscreen/windowed or changing resolution often invalidates surfaces. If you size surfaces to the window, recreate them on the Window Resize event as well.

Verifying

Alt-tab away and back. The lighting surface rebuilds; no black screen. Toggle fullscreen; surfaces resize and repopulate.

“Surfaces are volatile GPU memory. Treat every frame as if the surface might be gone.”

Wrap surface access in a helper: get_surface(ref, w, h) that checks, creates, and returns — one safe path instead of scattered surface_exists checks.