Quick answer: The alarm never fires because it is set to 0 (which means disabled, not “fire immediately”), the instance is destroyed before the alarm ticks down, or a persistent object’s alarm is reset during a room transition. Set alarms to 1 or greater, ensure the instance survives long enough, and guard persistent objects against duplication on room change.

Here is how to fix GameMaker alarm not firing. You set alarm[0] = 60 in the Create event, expecting the Alarm 0 event to fire after one second. It never does. You add a show_debug_message(alarm[0]) to the Step event and see it counting down: 60, 59, 58... then the object vanishes, or the room changes, or the alarm just sits at -1 and the event never triggers. GameMaker’s alarm system is straightforward, but it has a few gotchas that silently prevent the Alarm event from ever executing.

The Symptom

You set alarm[N] to a value in the Create event, Step event, or another Alarm event. You have a corresponding Alarm N event defined in the object with code that should execute. But the Alarm event never runs. There is no error message. The object continues to exist and process other events normally — Step, Draw, and collision events all work. Only the Alarm event is silent.

In some cases, the alarm appears to fire once but never repeats, even though you reset it inside the Alarm event. In other cases, the alarm fires in one room but not after transitioning to another room. And occasionally, the alarm fires for one instance of the object but not for a second instance created later.

What Causes This

Setting the alarm to 0. This is the most common mistake, especially for developers coming from other engines. In GameMaker, setting alarm[0] = 0 does not mean “fire immediately” or “fire on the next step.” It means “disabled.” Alarms only trigger the Alarm event when they count down to 0 from a positive value. If you set the alarm directly to 0, it is already at the termination value and will never decrement further, so the event never fires. To fire on the next step, set alarm[0] = 1.

Instance destroyed before the alarm ticks down. If the instance is destroyed via instance_destroy() before the alarm reaches 0, the Alarm event never fires. This happens when a separate collision event or a different object destroys the instance. It also happens when the room changes and the object is not persistent — all non-persistent instances are destroyed on room transition, and their pending alarms are lost.

Persistent objects duplicating on room change. When a persistent object moves to a new room that also has an instance of the same object placed in the Room Editor, GameMaker creates a duplicate. The persistent instance carries over with its alarm values intact, but the new duplicate starts fresh with all alarms at -1. If your code references alarm[0] on the wrong instance (the duplicate instead of the original), it appears that the alarm was reset. In practice, both instances are processing alarms independently, and the visible behavior depends on which instance your code interacts with.

Overwriting the alarm each step. A subtle bug: setting the alarm in the Step event without a guard condition resets it every frame. If your Step event contains alarm[0] = 30 unconditionally, the alarm is set to 30 on every step and never gets a chance to count down. It must be set once (typically in the Create event or behind a condition) and then left alone to decrement.

The Fix

Step 1: Set alarms to positive values and verify they decrement. Always set alarms to 1 or greater. Add debug logging to confirm the alarm is counting down as expected.

/// Create Event
alarm[0] = 60;  // Fire after 60 steps (1 second at 60 FPS)
show_debug_message("Alarm 0 set to: " + string(alarm[0]));

/// Step Event
if (alarm[0] > 0)
{
    show_debug_message("Alarm 0 countdown: "
        + string(alarm[0]));
}

/// Alarm 0 Event
show_debug_message("ALARM 0 FIRED!");
// To repeat the alarm, set it again here:
alarm[0] = 60;

If the debug output shows the alarm counting down and then stopping at 1 without firing, something is resetting the alarm back to a higher value before it reaches 0. Search your entire object’s events for any other assignment to alarm[0]. If the countdown reaches 0 but the Alarm event message never prints, verify that the Alarm event is defined on the correct alarm index — Alarm 0, not Alarm 1.

Step 2: Prevent premature destruction. If the instance might be destroyed before the alarm fires, consider whether the alarm action should happen in the Destroy event instead, or whether you need to delay destruction until after the alarm completes.

/// Step Event - guard against premature destruction
if (hp <= 0 and alarm[0] < 0)
{
    // Start death animation alarm instead of
    // destroying immediately
    alarm[0] = 30;  // 0.5 seconds for death anim
    sprite_index = spr_enemy_death;
}

/// Alarm 0 Event
// Now safe to destroy - animation has played
instance_destroy();

The pattern is: when the trigger condition is met (health reaches zero, timer expires), set an alarm instead of acting immediately. The alarm gives you a guaranteed window to play animations, spawn particles, or run cleanup before the instance is removed.

Persistent Objects and Room Transitions

For persistent objects, the alarm duplication problem is best solved by preventing the duplicate from being created in the first place. In the persistent object’s Create event, check whether another instance already exists.

Call instance_number(object_index) in the Create event. If it returns more than 1, the current instance is a duplicate and should be destroyed immediately. The original persistent instance keeps its alarm values and continues counting down uninterrupted. This is the standard singleton pattern in GameMaker and it solves alarm reset issues, position reset issues, and variable reset issues all at once.

If you need the persistent object to react to the new room (e.g., reset position but keep timers), use the Room Start event instead of the Create event. The Room Start event fires for persistent instances when entering a new room without creating a duplicate, so you can adjust position and state without losing alarm values.

Common Alarm Patterns

For a repeating alarm (e.g., spawning enemies every 3 seconds), set the alarm in the Create event and reset it at the end of the Alarm event. For a one-shot alarm (e.g., a delayed explosion), set it once and do not reset it — it automatically goes to -1 after firing. For a conditional alarm (e.g., fire only if a flag is set), check the condition inside the Alarm event and either act or reset the alarm to check again later.

Never use alarm[0] = 0 to mean “fire now.” If you need immediate execution, call a script or function directly. If you need “fire at the earliest possible moment,” use alarm[0] = 1 to fire on the next step.

“GameMaker alarms are not timers — they are step counters. Setting one to 0 is the same as setting it to -1: nothing happens. The Alarm event only fires on the transition from 1 to 0, not on assignment to 0.”

Related Issues

If your alarm fires but the code inside it does not behave as expected due to instance scope, see Variable Not Set Before Reading for instance variable initialization timing. If persistent objects cause other unexpected behavior on room change, check Persistent Object Duplicating on Room Change for the full singleton pattern.

alarm[0] = 0 means “off,” not “now.” Use alarm[0] = 1 for next-step execution.