How best to combine "only one action when event loops" and deactivating groups?

Welcome to our brand new Clickteam Community Hub! We hope you will enjoy using the new features, which we will be further expanding in the coming months.

A few features including Passport are unavailable initially whilst we monitor stability of the new platform, we hope to bring these online very soon. Small issues will crop up following the import from our old system, including some message formatting, translation accuracy and other things.

Thank you for your patience whilst we've worked on this and we look forward to more exciting community developments soon!

Clickteam.
  • I've often been a fan of using Only one action when event loops, because often you want something to happen every time something first happens, but not otherwise. A simple example: you want a "thud" sound to play when a player lands on the ground after jumping. So you play the sound if onGround=1 but Only one action when event loops so that the sound plays each time the player first lands on the ground, but not on the subsequent frames that the players is touching the ground immediately afterwards.

    But now I'm in the somewhat dispiriting process of going through my game's code and removing just about every instance of Only one action when event loops that I've put there over the past 7 years. The reason? Pausing. I've realised that pausing and Only one action when event loops don't mix, at least not the way I do pausing, which is by deactivating the main event group so that it won't run if the player has paused the game. The problem is that once the player unpauses and that group is reactivated, every one of those Only one action when event loops conditions inside will now fire anew. So, to use the above example, while the player is on the ground, the "thud" landing sound will play every time the game unpauses. This is just a cosmetic example, but there are situations in my game where if the player paused/unpaused at the wrong time, it could lead to glitches, cheats, or game-breaking behaviour.

    I understand that this is not a bug, but just a quirk of the underlying logic, as Please login to see this link.:

    Quote

    "Only one action when event loops" means pretty much what it says - if the conditions for the event are met on a cycle, then the actions are not carried out even if the conditions are met on the next cycle. The only time they are carried out is the first time the conditions are met. If the conditions are not met on a cycle, then the loop is broken and the actions will be performed again the next time the conditions are met.

    So I guess that in some technical sense, the condition (onGround=1) is not met, because the whole event is not processed as usual, since the group is deactivated. Perhaps each event has an invisible event is available condition in it that becomes false whenever its parent group is deactivated, which then triggers the Only one action when event loops to reset.

    Anyway, has anyone figured out a good way to be able to still use Only one action when event loops inside a group that may get deactivated? Maybe there's some clever way to trick Only one action when event loops into not resetting when it's in a deactivated group?

    Please login to see this link.
    My Fusion Tools: Please login to see this link. | Please login to see this link. | Please login to see this link.

  • While I don't know of a way to trick the condition into not resetting, I think you could set up a system to detect when this happens and force such events to essentially be ignored one time after unpausing.

    Here's a rough idea off the top of my head. It might get more complicated or difficult to do in certain situations, but based on a very quick test with my own games events, it seems to work and is relatively simple.

    First set up two values. These can be global variables, normal variables, or whatever. One of them (Game is Paused) is set to 1 when the game is paused, and set to 0 when the game is unpaused. The other one (Paused_DO_NOT_FIRE) is set to 1 when the game is paused, and also whenever "Game is Paused" is 1 and "Paused_DO_NOT_FIRE" is 0. These events should probably be placed towards the top of the event sheet.
    Please login to see this attachment.

    Next, at or near the very end of your event sheet, add an event to set "Paused_DO_NOT_FIRE" to 0 whenever it is 1 and "Game is Paused" is 0.
    Please login to see this attachment.

    Now that this system is set up, any events that use 'Only one action when event loops' conditions need to be modified with child events. Change them so that the parent conditions include everything they already had, but place all of the normal actions into a child event with its own extra condition of checking to see that "Paused_DO_NOT_FIRE" is 0. Add a second child event to this which has a condition to check for "Paused_DO_NOT_FIRE" being 1 and add a 'break' action to it. By doing this, the event will trigger regardless of whether or not "Paused_DO_NOT_FIRE" is 1 or 0, but will only fire the normal actions when the game is running normally and not an additional time when the game gets unpaused.
    Please login to see this attachment.

    I'm not sure you actually need to have a separate child event checking for "Paused_DO_NOT_FIRE" being 1 with a 'break' action, but I added it in my test so I would know if the event was still trying to fire or not.

  • Unless I'm mistaken though, this solution could have an issue if the player unpauses the game just at the exact time when one of the Only one action when event loops events was supposed to fire. The event wouldn't fire (because it detected that the game was unpaused right at that moment), even though it should have. This probably wouldn't happen often, but it'd happen eventually, and would be more likely if the player spammed the pause key for whatever reason. It'd be better than before (where unpausing would always cause misfires), but it still could create bugs (because unpausing could still occasionally cause misfires). I can't think of a way around this problem :( Can you?

    Please login to see this link.
    My Fusion Tools: Please login to see this link. | Please login to see this link. | Please login to see this link.

  • So is the situation you're describing one where an event that should fire due to the game being unpaused does not fire? Or the other way around? Because if the player unpauses and the event detects that the game is unpaused, then it should fire correctly. Sorry if I'm misunderstanding, it's a bit of a confusing thing to think about. Could you give a specific example of an event where this could happen?

    Speaking of potential issues, I was testing it a bit more and I realized a couple interesting things about the solution I mentioned. In the 3rd image of my previous post, the green collision condition is above the 'Only one action when event loops' condition. Normally this is the correct order, but the event in my game actually has the order of those two conditions flipped so that the collision condition is below the 'Only one action when event loops' condition, making the collision condition be colored red. I reordered them for the example image because that's usually the correct order for such green collision events to be in. However, I just realized that my solution does not work for collision events like this if you order the conditions as shown in my 3rd example image. The event will misfire upon unpausing despite the child event checking if the value is 1 or 0. It will only work if you 'incorrectly' order the conditions as shown in the corrected image below.
    Please login to see this attachment.
    (Please note that I'm not using the most recent version or beta, so perhaps this behavior won't be experienced by everyone.)

    The other thing I noticed is something which I'm wondering might be related to the potential issue you pointed out. For an event where a key or mouse button is pressed, it's possible to unpause and press the key or button at the same time. This causes the game to both unpause and fire the action(s) for the event(s) that should only be fired when the game is still paused. One way around this is to add a 3rd child event with conditions to check for instances where the game is no longer considered paused, but the "Paused_DO_NOT_FIRE" value has not yet reset to 0 at the end of the event sheet. In this situation, the event could either once again not do anything, or you could have some different actions occur if you need them. Importantly, the situation where it fires the events in a condition where both values are 1 is never met.
    Please login to see this attachment.

    Or maybe I'm still not grasping the actual issue. XD

  • True. It's a very old event and I haven't bothered to just switch it out with an actual overlap since it's been functioning as intended anyways. But I needed to point out the special condition order in case anyone tried to actually recreate the initial example and found that it didn't work as intended. If I could edit the post I'd just replace the image with a better one.

  • if i want a game pause; i will make an entire group that holds the running game part; this is what i will deactivate; outside of this is a group that control the pause and related actions; ie animations movement _ they will be paused if the game group is paused.
    as far as only 1 action, i always try to avoid it, and your example of sound, i use a variable which will be turned off/zero'd once its been played.
    if the game was paused; then unpaused, the variable has yet to be played and will trigger once its activated; if i do want something to trigger even when paused, i will put that part in the "outside" group

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!