Thanks to our Muffel asset, this is now real Game Maker code:
I'm not kidding, that's not pseudocode. I literally wrote that code into the create event of an object to make it spin. Not in the step event and without alarms*.
Isn't it beautiful?
Thanks to new in-line functions in GameMaker 2.3 and macros, we can now start a parallelly** executed code without alarms or events, in a beautiful syntax resembling simple english. We have two features:
Delayed execution: run code-block after x seconds or frames
Periodic execution: run code every x seconds or frames forever until you abort it
Let's say when your player is hit, you want him to be invincible for a second, you can do this:
Let's be honest, how would you have done this before? You would have either routinely checked if one second has passed in your Step-event or you would have created an alarm, written your code into the alarm event, disabled the alarm etc., just to set one variable to true.
Now you can do all of this inline!
Example usage might be everything involving "do this later" or "do this periodically":
Create a new enemy every three seconds
Let the screen shake for 50 frames and then stop
When enemy is attacked, let him be confused for a few seconds
Tower Defense: let a building fire only every five seconds
Yes, you can do all of this with alarms and step events too, but it's inconvenient and you lose track of which alarm does what and when, your step event becomes unreadable, etc.
How to install
You need Game Maker 2.3 to use this asset. Unzip our asset file somewhere. Open Game Maker. Go to "Tools" in the menu bar and select "Import local package". Now select the "com.ribbyte.muffel" file that was unzipped.
Read the "README.txt" file for more details, troubleshooting, how to abort the execution blocks, etc.
You might know the Coroutine feature in Unity (Invoke, StartCoroutine, WaitForSeconds or yield), with this asset you can basically solve similar problems in Game Maker.
* Internally, it still uses alarms, but you don't have to deal with alarms, set anything up and create the events etc. You don't even notice it's using alarms inside.
** It's not really parallel (as in multithreading) but it's the simplest description I have to describe the result. Look at this:
What does it print? That's right: "aaa" then "ccc" then "bbb". Why? Because the "bbb" code is only executed two seconds later, while the main script continues. So it first prints "aaa" then "ccc" and then, two seconds later, it prints "bbb". Basically, the code in a "execute after" or "execute every" block is executed after your script is finished. So it feels like it runs in parallel (or asynchronously).
What I can gather from your error log is that the object which is calling the "execute after 60 frames" was deleted/destroyed in the meantime? I thought I caught all errors of that type, but I might have missed a checked somewhere. I will look into it and update when I find the error.
It would be really helpful if you could share your project with me, so I can debug it faster (you can also create a new project that reproduces the same bug). You can reach me via ribbyteapps at-symbol gmail.com
If you find any more bugs, feel free to report all of them.
I just sent you the file that reproduces this bug. The problem is, I think when you try to use Muffel system in objects that weren't put manually to the room. If the object has some muffel functions and is created by another object, then you will get the error.
For completeness' sake: The bug probably occurs when using "instance_create_depth" which adds a new layer for that specific object and Muffel can't find it (due to limitations of GM). I have not heard back from Dave if this resolved his problem yet, but I would be surprised if not. If anybody else has the same problem, feel free to contact me! Here is the fix if you want to try it for yourself:
Either use "instance_create_layer" instead of "instance_create_depth" in your own script, or do the opposite in the Muffel script (replace "instance_create_layer(0, 0, layer, obj_muffel)" with "instance_create_depth(0, 0, 0, obj_muffel)")