A downloadable asset pack

Download NowName your own price

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:


Damn, if this isn't nice, I don't know what is

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.

Notes

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).

Download

Download NowName your own price

Click download now to get access to the following files:

muffel.zip 5 kB

Comments

Log in with itch.io to leave a comment.

(1 edit)

ribbyte, can you look at my error log please? 🙏

ERROR in

action number 1

of Alarm Event for alarm 1

for object oPlayer:

Unable to find instance for object index -4

 at gml_Script_execute_every_n_frames (line 44) -        inst._interval = n

###############################

gml_Script_execute_every_n_frames (line 44)

gml_Script_execute_after_n_frames (line 51) -        inst = execute_every_n_frames(n, callback)

gml_Script_execute_after_n (line 113) -        execute_after_n_frames(interval, callback);

gml_Object_oPlayer_Alarm_1 (line 5) - execute after 120 frames

What could go wrong? Thanks.


Edit: I solved it, but I still don't know what caused this.

(+1)

Hmm, did the object get deleted by any chance? I think I have a check if the object that’s executing the code still exists but I may have missed a check somewhere.

Alternatively, how do you create the object? You might have the same problem the other commenter had. 

If you still have the old code with the bug, you can send it to me at ribbyteapps@gmail.com 

(3 edits)

Here it is:

var inst = instance_create_depth(0,0,-9999,oWarp); //create Warp object, which will change room with fade-in and fade-out animation
    inst.target_x = oPlayer.x; //
    inst.target_y = oPlayer.y; //
    inst.target_room = RoomTV; //change room and teleport player when screen is covered (it takes ~~1.5 sec)
execute after 3 seconds // I think the timer stays in the last room, which caused the error because it can't run from previous room
var inst = instance_create_depth(0,0,-9999,oWarp);
    inst.target_x = oPlayer.x; //
    inst.target_y = oPlayer.y; //
    inst.target_room = Room1; //this code returns the player to the previous room in 3 seconds
done

if you still have questions, please ask

(1 edit)

It looks like this is the same error Dave encountered in the comment below. I posted the fix there (change instance_create_depth to instance_create_layer or adjust the Muffel script the other way around, refer to the comment below for more details).


I‘m not sure yet how to fix Muffel to allow both of those functions to be used, might have to look into it later.

Very nice idea, but it is very buggy. For example: when I used this in one object, everything works well, then tried it with another object and got this error:

ERROR in
action number 1
of Create Event
for object o_element:

Unable to find instance for object index -4
 at gml_Script_execute_every_n_frames (line 44) -        inst._interval = n
############################################################################################
gml_Script_execute_every_n_frames (line 44)
gml_Script_execute_after_n_frames (line 51) -        inst = execute_every_n_frames(n, callback)
gml_Script_execute_after_n (line 113) -        execute_after_n_frames(interval, callback);
gml_Object_o_element_Create_0 (line 3) -                       execute after 60 frames
gml_Script_instance_create (line 7)
gml_Script_engine_ne (line 120) -                (    0 + _spc + _xplus  +        (i-1)  * ( ( (room_width - _spc*2)  / (_noeol-1)) ) ,
gml_Script_scr_new_task (line 27)
gml_Script_anon_anon_gml_Object_o_program_Create_0_1590_gml_Object_o_program_Create_0_1798_anon_gml_Object_o_program_Create_0_1590_gml_Object_o_program_Create_0 (line 53) -                      scr_new_task();
gml_Object_obj_muffel_Alarm_0 (line 11) -        _my_callback(self);


I used very simple line in event create:

execute after 60 frames
      audio_play_sound(snd_score,3,0);
done

Thanks for the report!

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.

Did you have time to look at the example with this 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)")

Yep, it works. Instance_create_depth caused the problem. Sorry for not replying. 

(+1)

This is pure Genius! Thanks!

Glad you like it!