I've been playing around with For Each loops as I want to implement them as a way of simulating a function call and I'm a bit stumped by some of the behaviour. I'm made a file with three groups (which you have to manually activate before testing). Version 1 and Version 2 behave as I would expect but Version 3 does not. Version 2 is not really relevant but Version 1 and Version 3 are identical except the last event in Version 3 is split into two events in Version 1. I don't understand why they behave differently. If I replaced the For Each loops with Fastloops then both versions would behave the same. Why the difference?
Understanding For Each Loops
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.
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 confused as to why you're using for each loops this way. For each loops will run loops equal to the number of copies of an instance of an object and cycle though each instance individually. So if you had 3 copies of your Active, it would run 3 loops, one for each Active. Then it would scope each Active specifically. Previously if we wanted to target each Active individually we had to use a Spread Value ID and compare a fastloops index to that ID to single each one out.
There's no reason for you to use for each loops for function calls, regular fastloops do what you want. The only reason for each loops would be useful here would be if you need to cycle though each copy of your active.
As to why it doesn't work, it seems like there's a problem with the group activation/deactivation in conjunction with the for each loops. As you noticed in your other examples if you put the activation/deactivation on separate lines it works as you would think. I don't activate/deactivate groups often so I'm not sure exactly as to why it works like that. Maybe someone else can give some more insight for that. The only difference in my mind between for each loops and fastloops would be object scope so maybe that's doing something.
-
Hi Sumo, thanks for picking this up.
As you say; fastloops would be a good way of achieving what I want. I was going to do this but kind of got scared off them a bit because of the possible performance hit they might cause (Please login to see this link.). I was wondering about using For Each Loops with an active where only one instance exists as a halfway house. It's very possible I've got hold of the wrong end of the stick though and I would just be better off using fastloops.
Another thing I wasn't sure about (but think I've found the answer to now) was whether containing fastloops within groups and only opening the group when firing the loop was a good way of increasing performance or whether firing a fastloop causes it to scan all lines of the Fusion code regardless of whether or not it's in an activated group. I remember hearing collisions get tested for even if they are within a closed group (is this true?) and know Fusion has a few other quirks so I wasn't sure but it seems that closed groups don't get checked for fastloop events.
All in all I'm still a bit confused about the way Fusion handles loops. I've been told the runtime is halted whilst a fastloop is performed and they should be used if you need something to happen very quickly but what I don't really get is how this is any different from another event. Even if the loop is performed immediately, won't it's effects only been seen when the frame gets redrawn at the end of the next frame rate tick? Still struggling with this a bit so if anyone can shed some light on this I'd really appreciate it.
-
I guess, with reference to my original question, what I want to know is whether For Each loops behave as I thought (ie like Fastloops in terms of order of execution) and there is just some quirk with closing a group within the same event or whether there is a more fundamental difference in the way they are executed and I'm going to get all kinds of unexpected behaviour occurring if I recode my project using them and only discover I've made a mess of things after a lot of work.
-
I would say try and run some performance tests with fastloops on your target device to see how it'll hold up. How many fastloops do you plan on using and how often do you plan on running them? It depends on what you're going to use them for. If it's something like a complicated custom pathfinding widget that has to check hundreds of tiles each loop, then yeah it'll lag on a phone. But if its not something crazy like that, then I think it'll be fine.
And yes the main difference between fastloops and regular loops is that the runtime is paused, the fastloop events are only triggered, and the screen will only redraw until the fastloop finishes. So for small stuff, you might not think there's any difference between fastloops and normal loops. However for more advanced stuff in which you want to load a bunch of stuff quickly or do a bunch of calculations instantly, it's very useful.
The amount of times the game loops through your code is tied to your FPS of the game. So if your game is running at 60 FPS, Fusion will loop through your code 60 times a second (the always condition). On the other hand you can run way more than 60 fastloops in a second. So if you need to do a lot of code instantly, such as loading a huge level by reading from an array, fastloops will let you do that.
To demonstrate this point, I'll share a file I made as a randomized world example for a game jam that I was in. The file runs around 3000 fastloops at the start of the frame and it runs instantly. There's fastloops for randomizing land or water, checking coastline edges of land to switch tile animations to smooth it out, reading a perlin noise map for biome temperatures, drawing the map, spawning events, adding in nature, etc. Obviously this wont work well on a phone, but as an example there's no way I could do something like this without fastloops without having the player wait for stuff to generate for possible minutes instead of instantly.
-
Thanks, I really appreciate you taking the time to give a detailed answer and your example file. What I'm doing is very simple and I'd be surprised if it caused any noticeable performance decrease at all. I think just listening to some people talk about best practices with regards to performance made me unduly concerned. I can see if you are doing something big this could make an important difference but what I'm doing is not CPU hungry; most of the loops are called with just one iteration and I'm using them as a way of tidying up the code. Even the loops that truly "loop" only do so a few tens of times (don't think any even iterate 100 times).
I suppose it's all a matter of perspective; I guess some of the answers in other threads I've read are by people working on big projects and obviously things that hit performance are on their minds but I'm working on something simple and I probably don't need to worry much about fastloops' impact on performance.
Just out of interest, does the game in your example manage to keep close to 60fps at the start when it does the loop? I don't have one of the extensions it needs so I can't test it at the moment.
-
By reading your original post, I saw the word Function Call. Immediately, fastloop springs to mind. If you want something done and done immediately, catch the function call with a fastloop for immediate execution. Fastloops are superbly optimized, it's what you do *inside* the loop that adds overhead.
I would stay away from ForEach loops for Function Calls. ForEach loops are much better for iterating through multiple objects/instances and getting quicker/deeper scopes on pools of objects/instances.
Apologies if Sumo already has you covered, I only had chance to skim-read before I go out. Just wanted to throw my 2 cents in.
-
Not at all Danny, your two cents is always appreciated.
I guess fastloops it is then. Just one more quick question; will breaking a fastloop into two events be significantly worse performance-wise than containing everything within one event? Since you say they are "superbly optimized", I assume the only real thing that will hit performance is the number of times you perform the loop but I guess it's best to check whilst I've got you here.
eg
On loop "loop"
- Set Array (1,1,1) to 1
- Set Array (1,1,2) to 1Vs
On loop "loop"
- Set Array (1,1,1) to 1On loop "loop"
- Set Array (1,1,2) to 1Sometime there are instances where it is easier to read things if you break it into two events. This applies to other events too but I try to avoid splitting anything other than an always event.
-
Looking at the practical example there, no difference at all really.
Again, it's not about the number of loops that can cause the "stutter effect" it's what you do inside each loop. I have many fastloop effects running on mobile for the slots engine and even using a Galaxy S3 which is ~2012/2013 model, it runs at 60fps still. It's all about how you optimize the actions inside of the loop.
Trial and error is always good. Drum up a routine that you want to do with a fastloop, roll it onto mobile and test. If it's a bit wobbly, try and optimize the actions (ie: when scaling, use 0 flag for no anti-aliasing) etc.
-
Okay, thanks Danny. My project and the loops are pretty simple so I guess I probably won't have to worry too much. Most of what they do is perform a calculation or move a sprite in a custom movement. Nothing graphically or computationally intensive and many of them only "loop" once. I think I'll just dive in and start incorporating fastloops more liberally. If performance becomes an issue then I'll reassess but, from what people have said, I think I'll be fine.
-
Oh you'll be absolutely fine. Even in the very early stages of the Android Exporter (2011/2012) I made a Sokoban engine that purely uses fastloop movement (with some intense graphics) and it worked a charm. We've come along way the last 6-7 years and fastloops are about 50% more optimized even more now, than back then! Good luck with the project!
-
Thanks Danny! And thanks for taking the time to help; I really appreciate it.
Participate now!
Don’t have an account yet? Register yourself now and be a part of our community!