Why do you have to split actions into multiple lines sometimes for things to work?

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'm new to fast loops so I'm trying to understand things.

    I've got a very simple example that shows my question, press the up or down arrow.

    It's supposed to destroy any existing numbers and then use a fast loop to create some numbers next to the object.

    Upon pressing up:
    +Destroy objects
    +Set object position
    +Run fastloop

    The numbers previously don't get destroyed.

    But if I duplicate the action like this it works?

    Upon pressing up:
    +Destroy objects

    Upon pressing up:
    +Set object position
    +Run fastloop


    Just wondering what I'm missing? Is this a quirk or something I'm doing wrong? Thanks.

    Please login to see this attachment.

  • We expect Fusion to do this:

    1. Destroy all the numbers
    2. Move the green block up or down
    3. Run the loop.


    But it was explained to me before that Fusion executes the commands as follows:

    1. Destroy 1 Number
    2. Move the green block up or down
    3. Run the loop
    4. Destroy the next number
    5. Destroy the next number etc.

    Now in your case because you've created more numbers with your loop - Fusion is doing this:

    1. Destroy 1 Number - the last number previously created.
    2. Move the green block up or down
    3. Run the loop
    4. Destroy the next number - the last number newly created - and then stops.

    Probably it stops because there's now a confusion between the numbers that were there and the new numbers - but I don't really know.

    It is quirky and there are lots of ways to get past this - the way you solved it by splitting the commands is probably the best.

    (To see the last number being destroyed just make your frame width wider - to about 1000 pixels - you'll see it's always destroying 2 numbers - the last one previously created, and the last one newly created.)

    Casual games: Please login to see this link.

  • Thanks for the explanations. Interesting that it doesn't destroy all the numbers, but happy to know it's a quirk and my way round it works.

    I have another question that may be another quirk? I want to stop the loop when it reaches the red blocks, so it's counting the squares upto and including the red blocks but not after it.

    Oddly it seems to work sometimes and not others?
    Please login to see this attachment.

  • Yes, it's another quirk by design.

    The overlapping and collisions were designed to be used with moving objects and there are certain blocks and conditions built into them. When you use them with static objects they don't always work beyond the first time - in your case they're working every 2nd time. It has something to do with a design feature - Fusion waits for something to "change" before checking the condition again and with static objects that "change" doesn't happen.

    You can solve this by inserting this:

    * On loop "createXposcrosspath"
    + Y position of blocker = Y( "Active" )
    + Active 3 is overlapping blocker
    [INDENT]Special : Stop loop "createXposcrosspath"[/INDENT]

    Because now Fusion is forced to re-check because there's a change in a particular condition every time - and then the loop also works every time.

    Casual games: Please login to see this link.

  • triggering fastloops in an event sometimes breaks scoping. ForEach dont have the same issues but regular ones often benefit from being in their own event.

    Vol did a great deep dive on scoping here Please login to see this link.

    Please login to see this link.
    Please login to see this link.|Please login to see this link.|Please login to see this link.

  • Fastloops always break object scoping, this is a technical limitation of fastloops.

    There seems to be at least one exception. Someone recently showed me Please login to see this link. where you can combine a fastloop with a forEach loop and, incredibly, it keeps scope across events. I was practically trembling with nerves when I tried it in my own code, but was amazed that it actually worked X)

    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.

  • I used fastloops extensively for the first couple of years of my project, but I use almost forEach loops almost exclusively now. I used to be turned off by forEach loops because of how fiddly they seem to be to create, but once you're used to how they work, they're actually very straightforward, and because they keep scope nicely they often save you these sorts of headaches.

    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.

  • There's some weird bugs with creating fastloops inside events, I have to use child events to split them up to avoid bugs.

    Please login to see this link.

    Please login to see this link.

    Please login to see this link.

  • There's some weird bugs with creating fastloops inside events, I have to use child events to split them up to avoid bugs.

    Really? So before 2.5+ you never used fastloops or everything you created had bugs in it? Going all the way back to 2014?

    Because I've never used a parent / child event and all my fastloops work just fine.

    Casual games: Please login to see this link.

  • No I did use fastloops, but I use loops to trigger sfx and they break the scope in the rest of the condition for some reason. Before child events, I'd have had to do twice as many conditions rather than putting everything in the same one.

    Please login to see this link.

    Please login to see this link.

    Please login to see this link.


  • It's supposed to destroy any existing numbers and then use a fast loop to create some numbers next to the object.

    Upon pressing up:
    +Destroy objects
    +Set object position
    +Run fastloop

    The numbers previously don't get destroyed.

    When you have multiple instances (duplicates of the same objects), they don't all execute the actions at the same time, instead, you can think of all the actions being copy pasted to the bottom if there's still another instance waiting to execute the actions related to it.

    For example, if you have 2 "A" objects, and 3 "B objects", and you have those set of actions:
    + Destroy "A"
    + Destroy "B"
    + Run fastloop

    it will really execute this:
    + Destroy 1st "A"
    + Destroy 1st "B"
    + Run fastloop
    + Destroy 2nd "A"
    + Destroy 2nd "B"
    + Destroy 3rd "B"

    As Simon said, fastloops do not preserve selection, this means that any action after it that relies on instances like the example above will be broken.

    There seems to be at least one exception. Someone recently showed me Please login to see this link. where you can combine a fastloop with a forEach loop and, incredibly, it keeps scope across events. I was practically trembling with nerves when I tried it in my own code, but was amazed that it actually worked X)

    That's not an exception, this just filters the objects in the fast loop event just like an ordinary "Value of Object = " condition would. The selection before the fastloop happened is still lost, but since there was only one object to begin with (as it is a for each loop) it doesn't have as great of an effect. What would break more is if you selected an outside object within the for each loop as well as the fast loop.

    I have another question that may be another quirk? I want to stop the loop when it reaches the red blocks, so it's counting the squares upto and including the red blocks but not after it.
    Oddly it seems to work sometimes and not others?
    Please login to see this attachment.

    Objects that are destroyed actually still linger in the frame until all events finish. Then they are finally destroyed before the game frame renders. So, the "Destroy" action really marks objects for removal and doesn't immediately do it.

    If you use one of the flags and set it on when you use "Destroy", you will be able to filter out objects that are marked for removal before you do the overlap condition in event 8, as those objects are still capable of overlapping and therefore stop the loop prematurely.

    For-each loop runs by the reverse of creation order of objects, and sometime this may cause weird bugs, e.g. save and load once by For-each loop will reverse the order.
    If you want to control loop order manually I suggest to use fastloop+spread ID.

    For each loops execute ascending the spread order so fastloop + spread ID is identical to for each, while for each loops have the benefit of preserving selection (e.g. actives with flag off -> start for each).

    - BartekB

    Join the Click Converse Discord! - Please login to see this link.

  • There seems to be at least one exception. Someone recently showed me Please login to see this link. where you can combine a fastloop with a forEach loop and, incredibly, it keeps scope across events. I was practically trembling with nerves when I tried it in my own code, but was amazed that it actually worked X)

    Oh this is interesting. I do a lot of Fast loops + ForEach loops, but I just do the old trick of running a ForEach, grabbing the fixedID (and saving it to a variable) and then starting a Fast Loop and comparing the fixedID of the object to maintain scope. I use it for pixel perfect movement and collision detection of hundreds of bullets on screen at once and it works perfectly, but this way seems to cut out that extra step. I never knew you could put the ForEach right into the Fast Loop!

  • That's not an exception, this just filters the objects in the fast loop event just like an ordinary "Value of Object = " condition would. The selection before the fastloop happened is still lost, but since there was only one object to begin with (as it is a for each loop) it doesn't have as great of an effect. What would break more is if you selected an outside object within the for each loop as well as the fast loop.

    OK, I realise I got a bit lost in some of the nuances involved. I think when we talk about preserving selection, it's helpful to remember that there are at least two somewhat separate ways to understand this term. Sometimes, these two issues happen at the same time, as in this example:

    Please login to see this picture.

    There are two ways that the fastloop doesn't preserve selection in the above example.

    --Firstly, it doesn't inherit the selection for itself: it doesn't honour the Y("pear")> 100 scoping from its parent event, and so it fades all the pears.
    --Secondly, it interrupts the scoping of the parent event: once Fusion returns from the fastloop in event #2 to event #1, even the parent event itself no longer honours the Y("pear")> 100 scoping, and so the 45˚ tilt is applied incorrectly (ie. only to the most recently created pear)

    These are obviously related, but are two somewhat separate issues: the first applies to how the fastloop functions within itself, while the second replies on how the fastloop affects the events outside of it. For me, the second problem was always the more concerning one - that fastloops had the potential to ruin a parent event's scoping.

    You rightly point out that the first issue (fastloops don't inherit scoping) never really goes away, even when you add ForEach loops into the equation. However, the second issue (fastloops interrupting the scoping of their parents) does seem to go away when you introduce ForEach loops.

    If we insert a forEach loop into the above example, it suddenly works as expected. Not only do the correct pears (Y>100) get faded (because the fastloop inherits the scoping), but the correct pears also get tilted (because, for some reason, the fastloop no longer interrupts the scoping):

    Please login to see this picture.

    I initially thought this was a result of the clever trick of inserting the forEach condition ("on each one of.....") into the fastloop event. It certainly seems to be, when we remove that condition:

    Please login to see this picture.

    Now, we're back where we started, with the pears neither fading or tilting correctly. But after playing around a little now I see that there's something about forEach loops more generally that does seem to protect from fastloops interrupting scope, at least in some circumstances. In this next example, we take away the clever trick of inserting the forEach condition, as before, but we also split out the actions in event #2 into two separate events:

    Please login to see this picture.

    Now the pears in are no longer correctly faded in #4, of course. But, unlike in the very first example (or the previous one), the pears are correctly tilted. You probably have a better idea than me of why this is - for me it's not immediately intuitive as to why it would work this way. For one thing, why does event #2 break in the second example, but not in the third example, even though they are identical events?

    But either way, the difference seems clear: somehow the presence of a forEach loop in the second and fourth example prevents the fastloop from breaking (interrupting ) scope in the way that it does in the first example. I maintain that this is in its own way some sort of exception, though to the interupting mechanism, if not the inheriting mechanism.

    Ironically, I used to be scared of fastloops because, after seeing how they can interrupt regular events, I assumed that they would break the scoping in a long chain of forEach events too. But actually it seems that the addition of forEach loops can actually protect scoping integrity. Though how exactly this works is still opaque to me.

    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.

    Edited once, last by Volnaiskra (September 20, 2020 at 8:00 AM).

  • [MENTION=15682]Volnaiskra[/MENTION] The quote talks roughly about those two ways you've mentioned.

    Internally, Fusion only ever has one selection list. You can think of this as a manager that marks which objects are selected at any given moment in an event.
    For each object type you have in your fusion frame/game, the manager keeps track of:

    1. The event number (at what event the selection was made)
    2. The number of currently selected objects
    3. A list of the selected objects
    4. Some other values, but I will omit them to make this explanation simpler

    When a fusion event comes across an object's condition, this updates the event number of this type to fusion's "current event number".
    When the event number and "current event number" are equal, fusion regards this selection as valid, if not, it assumes all objects are selected by default.

    This is very important, because when fusion jumps to a new event, this "current event number" increments, invalidating all selections that were made beforehand but also validating all selections done in the fastloop event within the fastloop caller after it jumps back. That makes functions like fastloops and any other actions that jump to a new event dangerous, and cause the very two problems you have mentioned:
    - The new event/condition, like fastloops, do not inherit the selection from the event that called it/the caller. (Which in my opinion, is good)
    - When fusion eventually comes back to the fastloop caller event, you have (almost) absolutely no idea what modifications have been made to the selection and result in undefined behaviour for the rest of the actions after the loop. (This is what caused for the original post in this thread)

    That's why the for each loop action really queues the loop to start when all actions finish, so as to avoid the second issue. Fastloops don't do this.

    As it turns out, the way fusion executes the actions according to the selection list is complicated, but adding the for each condition to the fast loop helps because you reintroduce the roughly the same selection as it was in the fastloop caller event, so when fusion comes back from the fastloop to the caller event, enough of the properties inside the selection list (manager) are still correct. In addition, for each loops handle objects one by one so you are guaranteed to experience less selection issues because of this fact.

    tl;dr : Those two problems you mentioned are both caused by the same thing: the fact that fusion only keeps one selection list. It can be overridden by event jumping like you can do with fastloops causing the first problem, which then the event that called the fastloop takes as its own causing the second problem. I'm assuming this was programmed during the early life of Fusion i.e. klik n play, and event jumping (fastloops) weren't taken into account back then, so it now exists as a technical limitation of the engine.

    Sorry about the lack of visuals, I think they would have greatly helped here. Maybe I'll do some some other time :)

    - BartekB

    Join the Click Converse Discord! - Please login to see this link.

    Edited once, last by BartekB: Removed child/parent naming to avoid confusion with F2.5+ functionality (September 20, 2020 at 3:57 PM).

Participate now!

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