• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GML Is there anything similar to wait() ?

HerkusX

Member
In other languages, it is easy to set up when stuff will happen. For example :
GML:
repeat(5)
{
    x += 1
    wait(1)
} // This makes you move 5 steps every second.
 

chamaeleon

Member
No, time passing implies you let steps execute at the speed of your room speed. If you want to wait, you use an if statement with a proper condition in the required event, and ensure the condition is true when sufficient amount of time has elapsed, or you use alarms.
 

Mr Magnus

Viking King
Your closest built-equivalent are alarms. Alarms tick down one frame per frame and execute their code at 0. You can write your own "wait()" functionality if you want using the step event, alarms, real-world date and time functions, and so on and so forth.
 
So you could do this:
GML:
///wait(ms)
/*
Pauses code execution for given amount of milliseconds
1000 = 1 second

DISCLAIMER: Don't use this for anything more than debugging!
Normally, this type of function pauses the code. But this code traps the cpu in
an indefinite loop, which is very resource intensive and if you delay for too long
(11 seconds or more on windows 10), the OS will start assuming your app is dead
*/

var pauseStamp = current_time;
while pauseStamp+argument0 > current_time
    {
    // Waste CPU
    }
There's also this, but it's an extension, and presumably only works for GM1.4 (I don't know compatability of 1.4 extensions for GM2). But it's possible you can find an equivalent for GM2, or even ask the creator?
 

TheouAegis

Member
You're not only wasting CPU, you're causing the program to hang. And if it hangs too long, the operating system might flag it as a crash. That's why they removed the sleep() function when Studio came out.
 
That is missing the point of the GMS event model. Doing what you suggest just hangs the game, stopping everything from doing anything at all for all instances, until the time has elapsed (except perhaps music running in a different thread).
Well that is also what delay would do. Music in another thread is a good point though

You're not only wasting CPU, you're causing the program to hang. And if it hangs too long, the operating system might flag it as a crash. That's why they removed the sleep() function when Studio came out.
Yes, as mentioned in the comments of the function.

It's for debug use only, for example: Perhaps you want to simulate a client crash without having to hold and drag the window.
 

chamaeleon

Member
Well that is also what delay would do. Music in another thread is a good point though
This is just about never what people want or expect when they ask the question. They only want the code within the block to be delayed for some time, not everything else that makes up the game.
 
This is just about never what people want or expect when they ask the question.
Well that's subjective

From the arduino documentation on its delay function:
https://randomnerdtutorials.com/why-you-shouldnt-always-use-the-arduino-delay-function said:
delay() is a blocking function. Blocking functions prevent a program from doing anything else until that particular task has completed. If you need multiple tasks to occur at the same time, you simply cannot use delay().
From some visual studio documentation
https://www.theengineeringprojects.com/2013/10/how-to-add-delay-in-microsoft-visual.html said:
You should take much care in using this delay because this delay simply makes your software to sleep and thus while the delay is in process, your software won't do any other task

I even found examples of others doing what I did
1.
https://c-for-dummies.com/blog/?p=69 said:
C:
void delay(int milliseconds)
{
    long pause;
    clock_t now,then;

    pause = milliseconds*(CLOCKS_PER_SEC/1000);
    now = then = clock();
    while( (now-then) < pause )
        now = clock();
}
2.
https://www.geeksforgeeks.org/time-delay-c/ said:
C:
void delay(int number_of_seconds)
{
    // Converting time into milli_seconds
    int milli_seconds = 1000 * number_of_seconds;

    // Storing start time
    clock_t start_time = clock();

    // looping till required time is not achieved
    while (clock() < start_time + milli_seconds)
        ;
}
3.
https://www.sitepoint.com/delay-sleep-pause-wait/ said:
JavaScript:
function sleep(milliseconds) {
  const date = Date.now();
  let currentDate = null;
  do {
    currentDate = Date.now();
  } while (currentDate - date < milliseconds);
}

console.log("Hello");
sleep(2000);
console.log("World!");
I am aware it's not a good practice but if you need a wait function, that will do it.
 
Last edited:

chamaeleon

Member
if you need a wait function, that will do it.
In the context of writing a program in GMS it is useless. It is not why people ask about a pause function or keyword in GML. Really. I'm going to predict that what @HerkusX is asking about fits all other past topics on this board on the same subject, and the answer has never been to completely halt the execution of the game.
 
In the context of writing a program in GMS it is useless.
This is subjective. If you want to throw a program together really quickly to test something, then it can be useful. It could save you 2 minutes of your time.

I'm going to predict that what @HerkusX is asking about fits all other past topics on this board on the same subject, and the answer has never been to completely halt the execution of the game.
Quite possibly, I don't think anyone disagrees on the idea that wait() is not a good longterm solution.

But it's also possible that other people may come across this topic from google, looking for a wait() function specifically in GMS. And there it is, if they want it. At their peril.
 

HerkusX

Member
This is subjective. If you want to throw a program together really quickly to test something, then it can be useful. It could save you 2 minutes of your time.


Quite possibly, I don't think anyone disagrees on the idea that wait() is not a good longterm solution.

But it's also possible that other people may come across this topic from google, looking for a wait() function specifically in GMS. And there it is, if they want it. At their peril.
You guys make it sound really complicated, all i want is to do some pauses in the game. For instance :

Npc goes 3 blocks to the right. Waits 3 seconds. turns around. walks 3 blocks to the left. (Like a royal guard). But i guess alarms will do. I'm just not sure how to set the time on alarm ( when will it execute). Ill try reading the manual.
 

chamaeleon

Member
If we're going to list different implementations there are also these:
I didn't bring any of these up from the start because I felt it is better to get a solid grasp on the event model before reaching for shortcuts and convenience libraries.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Guy's might I suggest that you tailor your answers to the OP's level? The fact that they ask about how alarms work should tell you that throwing higher level solutions at them is pointless at this moment in time. What they need is help to LEARN how to overcome this problem as simply as possible and move on. All you are doing is confusing things and possibly even scaring them off programming (or at least the GMC). Honestly, is it SO hard to just explain briefly how to make a timer variable or use an alarm?

So, @HerkusX here's what you need to know. To start with using an alarm... An Alarm is an event that will trigger after a specific number of frames (steps) has past. T use one in code you would set the alarm to a value, then add something into the alarm event so that is performed. The simplest way to do this is as follows:
GML:
// CREATE EVENT
alarm[0] = room_speed * 3; // Alarm is set to 3 seconds, since the room_speed value is the number of steps in one second
direction = 0;
speed = 0.5;

// ALARM[0] EVENT
direction -= 180; // Reverse the direction
alarm[0] = room_speed * 3; // reset the alarm so it is called again
And that's it! Now the instance will move in a direction for 3 seconds, then turn around and move in the other direction for 3 seconds, etc... This can also be done using your own variables and the STEP event, so if you want to know about that then let us know.
 

chamaeleon

Member
And that's it! Now the instance will move in a direction for 3 seconds, then turn around and move in the other direction for 3 seconds, etc..
Sorry, but that's not what was asked for. :) It was move an unspecified distance and time (I have no idea how to put 3 blocks into time or distance)., then don't move for 3 seconds, then move again in the opposite direction.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Sorry, but that's not what was asked for. :) It was move an undetermined distance and time., then don't move for 3 seconds, then move again in the opposite direction.
See? All this debate about stalling the game has even ME muddled. :p

So, looking at the actual code posted in the very first post... If I was doing this I'd use a variable and an alarm. The variable will control the stop/start of the instance, and the alarm will time when this stopping and starting happens, like this:
GML:
// CREATE EVENT
move = true; // This variable will control if the instance moves or not
alarm[0] = 5;

// STEP EVENT
if move == true
{
x += 2; // "move" is true, so move the instance!
}

// ALARM[0]
if move == true
{
move = false;
alarm[0] = room_speed; // Setting the alarm to roomspeed means that the instance will pause for 1 second (60 frames)
}
else
{
move = true;
alarm[0] = 5; // Setting the alarm to 5, means the instance will move for 5 frames
}
 

chamaeleon

Member
Building on @Nocturne's code
GML:
// CREATE EVENT
horizontal_speed = 2;
move = true; // This variable will control if the instance moves or not

// STEP EVENT
if move == true
{
    x += horizontal_speed; // "move" is true, so move the instance!
}

if (x < 20 || x > 400) // just some sample condition of course, better values based on instances, room extent, or view boundaries may be more desirable
{
    move = false;
    alarm[0] = 3 * room_speed;
}
// ALARM[0]
horizontal_speed = -horizontal_speed;
move = true;
Given a horizontal speed, move until the instance is far enough to the left or far enough to the right.
When this happens, stop movement, set an alarm to trigger in 3 seconds.
In the alarm, reverse the direction of movement and enable movement.
 

GMWolf

aka fel666
I think we need to recap a few things for OP:

In game maker your step even code runs once fully for each frame. What that means is that you will only see the results of your code once all events have executed fully.
Nothing happens in between lines of code.
Code:
x += 5;
x += 5;
x += 5;
The above may look like the player will move right by five pixels at a time. But nothing happens in between each line of code. SO the net effect is the object moving by 15 pixels in one frame.
Code:
x += 5;
wait(3);
x += 5;
wait(3);
x += 5;
wait(3);
// Where wait is a magic function that blocks for n seconds
This still has the same problem, nothing happens between each lines of code (it does no render a frame between each line of code.)
So all you will see is the game lock up for 9 seconds (3 x 3) and then the object will move by 15 pixels.

What you need to do is allow the game to update between each move.
In game maker your step even code runs once fully for each frame.
So what you can do is time haw many frames/seconds have passed in the step event to decide if you should move or not (or use alarms.)
This allows you to have a delay, without blocking the game.
The above posts explain how.

If you want to learn more about that style of programming, you can look up state machines. They are very useful when working with a game maker style event loop, and there is plenty of both game maker and non gamemaker related learning material about them.


I hope this helps clear some things up :)
 
Top