Quick answer: Game End event fires only when game_end() is called. Window close (alt-F4) does not fire it directly. Catch the close request in an Async System event, run save logic, then call game_end().
Here is how to fix GameMaker Game End event missing when the player closes the window via the title-bar X or alt-F4. Window close is a system signal that needs explicit handling before the engine actually quits.
The Symptom
You put save logic in Game End event. Editor stop button triggers it. Building and alt-F4 the running game does not; save logic never runs and player progress is lost.
What Causes This
Game End requires game_end() call. Direct shutdown via OS does not run it.
Async System event needed. close_requested arrives via Async System; you have to subscribe.
OS-level kills. Force-kill (Task Manager) bypasses everything.
The Fix
Step 1: Add Async System event to controller.
// oController Async - System event
var _ev = async_load[? "event_type"];
if (_ev == "close_requested" || _ev == "OS_close_request") {
save_game();
game_end();
}
The handler captures the close request, saves, then triggers the actual shutdown.
Step 2: Make the controller persistent.
// Create event
persistent = true;
So it survives room changes and is alive when the close request arrives.
Step 3: Handle Game End for cleanup that should always run.
// Game End event (oController)
// flush logs, close network connections, etc.
flush_logs();
network_close_all();
Game End runs after game_end() invocation. Save here too as a fallback.
Step 4: Test alt-F4 in actual build. Editor stop is different from shipping quit. Build and alt-F4 to confirm save fires.
Step 5: Acknowledge force-kill limitation. Task Manager / kill -9 cannot be intercepted. For critical data, save periodically during play, not just on quit.
“Async System catches close. Game End runs cleanup. Periodic saves cover force-kill.”
Related Issues
For window event mouse leave, see Window Mouse Leave. For async HTTP truncation, see Async HTTP.
close_requested -> save -> game_end. Periodic saves for force-kill insurance.