GameMaker: Simplest possible custom alarms

This is a small blog post about a thing that I've now explained so many times that it became obvious that it needs a blog post.

People are constantly asking about how built-in alarms work and how they could be replicated with custom GML code (for having >12 alarms, organization, or else).

Quality of explanations and equivalent code often varies, so here I explain both.

The logic

The logic behind alarms and alarm events is all pretty simple:

For each alarm,
	If alarm[i] is greater than 0,
		Decrease alarm[i] by 1
		If alarm[i] is no longer greater than 0,
			Perform Alarm #i event

As a bonus fact, alarm[] values are integers, rounding to the nearest number on assignment.

The code

Translating the shown logic to code is all pretty simple.

Create Event:

    myalarm = 0;

Step Event:

    if (myalarm > 0) {
        myalarm -= 1;
        if (myalarm <= 0) {
            // trigger
        }
    }

However, believe it or not, the Step event can be written in even shorter form:

Step Event:

    if (myalarm && !--myalarm) {
        // trigger
    }

I assume that this is a point where a decent amount of readers might have questions, so:

  • By GML' rules, a value is considered "true" if it's larger than 0.5. therefore the > 0 comparison can be omitted.
  • --myalarm is standard (C-like) syntax for decrementing a variable before retrieving it's value.
    For example, a = --b would be the same as b -= 1; a = b;.
    In this case, it allows to omit a nested if-layer that only decreases that variable.
  • Logic inversion operator follows the same "truthness" rules, therefore !a yields true if (a <= 0.5) and false if (a > 0.5). This allows to omit the second comparison too.
  • Finally, by the rules of boolean AND (short-circuit evaluation), the right-side expression is not evaluated if the left-side expression is not "true". This prevents the variable from being decreased into negative infinity after reaching zero.

In other programming languages, this would be best written as

if (myalarm > 0 && --myalarm <= 0) {
    // trigger
}

Since most of them do not evaluate "truthness" of values the same way as GameMaker does (either assuming anything but 0 to be true, or always requiring explicit comparisons).

And that's it. Have fun!.

Related posts:

7 thoughts on “GameMaker: Simplest possible custom alarms

  1. I’m getting a strange behavior out of that.

    (if my_var && my_alarm && !–my_alarm)
    versus
    (if my_alarm && !–my_alarm && my_var)

    Assuming that my_var is always 1, for some reason the only the second line works. Any idea?

  2. Pingback: GameMaker Tutorial: Delta Time - csanyk.com

  3. I’ve been doing something like this for a while now.
    I usually use an array to index the alarms I have like this:
    a[0] = -1;
    And to check if the alarm has sounded I just check to see if a[0] = 0

  4. Very intelligent work around. It took me a few seconds to see how the code worked.

    Brilliant.

    • I generally use a variable called t, t_2, or t_reload, etc for this exact thing. In almost all my objects I have something similar to this. This post has completely changed how I will program moving forward, so thanks :)

      if t>0
      {
      t-=1
      }
      
      if t = 0
      {
      //Event
      }

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.