GMS 2 Unlimited Alarms

Shavv

Member
GM Version: Studio (all)
Target Platform: all
Download: n/a
Links: n/a

Summary:
This guide will help you out with your projects running out of alarms to use on objects in a very neat way and will completely eliminate using alarms. Hence, provides you with a cleaner overview of your objects and will improve your project drastically.


Alarms are pretty limited in GameMaker and always have been. Thats why I have decided to post up a tutorial about how to use alarms but better, since I still see people struggeling with alarms to this day. This guide will help you out with your projects running out of alarms to use on objects and able to customize them properly.

For the custom alarms, we will not use an index of an alarm but a string. We want to make a variable out of that string, that does not have to be created before it can be used in for example the Create Event. This allows us for easy acces and setting up alarms when we need them instead of preparing them in front of time.

Since we will use strings, alarms are way easier to oversee what they are for also!

To start creating our custom alarm, we first have to create a new script with the name "timer_init". We will use the name timer for our custom alarm scripts. In that script we paste this code in there:
GML:
///@description timer_init()
///@argument "timer_string"

//setting up local variable
var variable_name="timer_"+string(argument0);

//check if variable exists
if !variable_instance_exists(id,variable_name)
{
    variable_instance_set(id,variable_name,-1);
}
    else
{
    //countdown timer and set to -1 once reached 0
    if variable_instance_get(id,variable_name)>0
    {
        variable_instance_set(id,variable_name,variable_instance_get(id,variable_name)-1);
    }
        else
    {
        variable_instance_set(id,variable_name,-1);
    }
}

As you can see illustrated above, we will make a variable_name out of a argument for the script with a string "timer_" attached to the front of that argument. This will make sure all your variables in the object will not conflict with the timer names. Below that we create the timer as a variable once it does not exist. This makes sure that this script can be used when you need it and that you don't need to first initialize the timer before you can use it. This also makes the timer count down in constant running events.

Normally in GameMaker an alarm goes down by -1 every step (depending on room speed). So a good place to put your timer_init script is in the Step Event. We will use a timer called "demo".
GML:
//timers
timer_init("demo")

And we are basically done setting up the timer for use in the object. Notice that you can still use the variable "demo" and have it be seperated from the timer name since we put "timer_" in front of every timer variable name.

Now we want to set the timer to a value or get its value. We can create two scripts that are quite similiar to existing scripts in gamemaker that exists for alarms already:

timer_set
GML:
///@description timer_get()
///@argument "timer_string"
///@argument value

//check if variable exists
var variable_name="timer_"+string(argument0);
variable_instance_set(id,variable_name,argument1);

timer_get
GML:
///@description timer_get()
///@argument "timer_string"

//check if variable exists
var variable_name="timer_"+string(argument0);

if variable_instance_exists(id,variable_name)
{
    return variable_instance_get(id,variable_name);
}
    else
{
    return -1;
}

We can use the timer_set script to set a timer to a value. And use the timer_get script to get a value. As you can see in the timer_get script, it first checks if the variable exists and if it doesn't returns a -1 meaning the timer is deactivated. This way you can check on a timer without first actually setting one or even initializing it. The same goes for timer_set, but the timer doesn't run if you dont use the timer_init script.

Since we took every step to succesfully read, set and init timers we can look at a good way to use them:

- Check if a timer is running with using a timer_get on the correct string name and seeing if the value is >0 if timer_get("demo")>0 { /*timer is running*/}
- Check if a timer is done with using a timer_get on the correct string name and seeing if the value is 0 if timer_get("demo")=0 { /*timer is done*/}
- Check if a timer is deactivated using a timer_get on the correct string name and seeing if the value is -1 if timer_get("demo")=-1 { /*timer is not running*/}


I hope this all helped you in your game dev journeys and if there are questions feel free to respond on this post

Ofcourse customize the timer scripts to fit your own projects if you miss additional features

If you have suggestions about making improvements such as increasing a argument count on the timer_init, feel free. But this tutorial has been made to be as clear and simple as it can be.



Shavv.
 
Last edited:

chance

predictably random
Forum Staff
Moderator
There are times when you need more than twelve alarms in an instance. And being able to name each timer might be nice. So I suppose this could be useful.

But being so accustomed to built-in alarms, I'm not sure I'd use this approach. The feature I'd miss the most would be keeping each alarm code in separate event windows, rather than bringing it all back into STEP. I find that easy to use and organize. But that's just my preference.
 
Last edited:

Shavv

Member
There are times when you need more than twelve alarms in an instance. And being able to name each timer might be nice. So I suppose this could be useful.

But being so accustomed to built-in alarms, I'm not sure I'd use this approach. The feature I'd miss the most would be keeping each alarm code in separate event windows, rather than bringing it all back into STEP. I find that easy to use and organize. But that's just my preference.


Using regions, you can organize your timers perfectly. Here is a small introduction how you can use regions in a event to keep all your timers organized

GML:
#region Timers

    timer_init("d")
    timer_init("e")
    timer_init("m")
    timer_init("o")

#endregion


Example in a project to see structuring:



Note: this is only a GMS2 feature.
 
Last edited:

zendraw

Member
whats the problem with doing this? why wuld i go an extra mile for somthing so simple?
if (!timer)
{
//code
} else
{
timer--;
}

not to mention your method doesnt allow the user to learn how to better program.
 

zendraw

Member
Since you can run out of alarms to use.




This is purely a tutorial for unlimited alarms with every step explained in detail. Not a guideline to programming basics.
the alarms are just a timer, and you can have as meny timers as variables. alarms are just more newbie friendly.

and my point for it not allowing learning experience is that the user will not deal with gml itself, variables and such. if the user deals with variables he will learn how to use them in multiple ways thru experience. maybe your system wuld be useful for somthing else, experiment and find what that is, but a substitute for alarms, not a good idea.
 

Shavv

Member
the alarms are just a timer, and you can have as meny timers as variables. alarms are just more newbie friendly.

Alarms are already setup and have a "ease-of-use" factor. This has nothing to do with "newbie friendly". It doesn't matter how much or less you use GameMaker, they have their uses.

and my point for it not allowing learning experience is that the user will not deal with gml itself, variables and such. if the user deals with variables he will learn how to use them in multiple ways thru experience. maybe your system wuld be useful for somthing else, experiment and find what that is, but a substitute for alarms, not a good idea.

I can't follow you here. Your reasoning and your sentence makes no sense to me. And the fact that you say this is not a good idea as a substitute for alarms makes me even more confused. This works literally exactly the same but then without the restriction of only having a max of 11 alarm id's, without having to setup variables in the create event.
 
Last edited:

zendraw

Member
you fail to give a reason why wuld i use this instead of setting a variable and do a simple if else statement? variables are alredy unlimited alarms. and this is by default the best practice. and like i sayd your system may be useful for somthing else but not for alarms, what cant you understand? no1 will run the extra mile to write functions instead of just setting a variable to a value, unless they dont know what programming is, in which case your teaching people a bad practice.
 

Shavv

Member
you fail to give a reason why wuld i use this instead of setting a variable and do a simple if else statement?
I gave multiple reasons:
  • Creating variables in a unique string name, so you dont have conflict with for example: the timer "attack" and a variable called "attack". They dont conflict and you can use both.
  • Good structuring in a project
  • Ease of use, just like alarms
  • Not having to initialize a variable with a value before using it.

variables are alredy unlimited alarms.

This tutorial is using variables to make custom alarms.

no1 will run the extra mile to write functions instead of just setting a variable to a value, unless they dont know what programming is, in which case your teaching people a bad practice.

You have to run a extra mile to structure your project in a clean way. This is by no means a bad practice.
 

zendraw

Member
I gave multiple reasons:
  • Creating variables in a unique string name, so you dont have conflict with for example: the timer "attack" and a variable called "attack". They dont conflict and you can use both.
  • Good structuring in a project
  • Ease of use, just like alarms
  • Not having to initialize a variable with a value before using it.




This tutorial is using variables to make custom alarms.




You have to run a extra mile to structure your project in a clean way. This is by no means a bad practice.
a bit of conflict is nececery so the user learns to name his variables... and i dont see how this is good structuring or easyer then setting a variable, and not having to initialize a variable? thru the whole development process you will be setting variables and initializing them beforehand and structuring them in your codeblocks and naming them uniquely.

what is not using variables?

in this case no you dont.
 

Shavv

Member
a bit of conflict is nececery so the user learns to name his variables...
Necessary? If starting to use GML, yes. At this point we are far beyond that stage. This makes no sense and doesn't even have a place in this conversation.


and i dont see how this is good structuring or easyer then setting a variable, and not having to initialize a variable? thru the whole development process you will be setting variables and initializing them beforehand and structuring them in your codeblocks and naming them uniquely.
You said this is not good structuring or easier. But after that sentence you contradict yourself and saying its true that the whole process of setting up variables and initializing them beforehand is necessary.

what is not using variables?

in this case no you dont.
Wrong.

variable_instance_set is making a variable. And variable_instance_get only prevents errors since we can check on a variable without a value before using it.


Im going to stop responding after this comment on you, since I feel like this discussion doesn't have a place in a unlimited timer tutorial. I also feel that if you are stating that the user needs conflicting variables to have a better learning process , your inexperience is contradicting the original purpose of this tutorial. So as I said before:
This is purely a tutorial for unlimited alarms with every step explained in detail. Not a guideline to programming basics.
 
Last edited:
Top