Anyone else getting slow downs when using 160+ Objects each with their own Arrays?

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 am using other programs/coding languages/etc while using this to test its limits.. I was shocked to find the for each object loops (or for loops with CountNumberOfObject......) as the means to manage individual arrays but I managed to push on... then I came to a problem, assigning each objects arrays. I am confused here. If I give one object one or two arrays and run for each loops to pick each object and update each array based on the owners parameters or even akin arrays and create 162+ objects I notice tremendous slow down in my project. Am I doing this wrong? I could easily do this in other engines without great slowdown approaching around 1000+ objects.

    Is alterable values the only real way to manage this amount of objects without great lag in Clickteam fusion or am I (I hope) doing some dreadfully wrong?

    Obviously this must be user error. If anyone has an example of a demo somewhere with arrays per object I would love to see it.

    This might account for why games such as The Escapists had such low unit counts.. I know this engine lacks real camera management functions so whats the best way to disable objects and their arrays when out of view of the frame atleast to manage overhead. Or do most people manage each array per frame or some such, save data PER object somewhere, and then destroy the objects and reload them on creation? Not sure how to do that with clickteam. Would be tons of files saved if using so many objects.... Not sure thats good either.

    Any help on this, or common usage would be appreciated.

  • Are you using the Array class or a different extension? You aren't supposed to instantiate the Array class in Fusion, so I'm curious what you're doing there.

    If you're using one Array and then identifying values in it based on a dimension linked to each object, you definitely shouldn't run a for loop to read from it. If you have to write to it, you're going to experience pretty significant slow-downs primarily because of the for loop with that many objects. One unrealized way to increase write speeds is by setting the size of the array before you ever write to it; this will keep Fusion (and any other language) from having to keep resizing it as you write to it. If it's already been enlarged, there isn't much you can do at that point to increase performance. Not sure though what kinds of writing you're doing; if you're doing a for loop and then looping through the array to write to it, you're talking about 160 objects * the number of loops * speed per write.

    As a rule of thumb, you shouldn't use the Array class in Fusion for large numbers of writes because it isn't designed to handle that. If you can, use local variables ("alterable values") for your objects. Local variables are extremely fast and you won't need to run a for loop to change them.

  • Are you using the Array class or a different extension?

    Just a note there Snail, calling it the Array "class" might be confusing to users, It is called the "Array Object". Using terms like instantiate is also unhelpful as Fusion never talks about use in these terms, it adds confusing and unnecessary lingo and jargon for average users - take care please.

    PotatoMerchantz5: could you explain what type of data you are storing in each array in the x/y dimensions, and how often you're accessing and updating it.

  • I spoke to Yves briefly about your issue and he recommends given the small size of your array data, that you should use alterable values for each object. These can be accessed using an index number instead of a named value and there are virtually unlimited values available in this manner. So you could start at index 100 and go up to 200 if you wish. You can easily convert that into coordinates if you wish too, so assuming data grid of 10 x 10, 100 + (y * 10) + x would give you the correct index value from 100-200.

    You should find this a lot faster.

  • I have done what Snail and Simon suggest and will now do what Bertard said and use inis to write values for storage. I was calling them as alterable values, so every frame a value was being read. Even when adding flags to disable rapid calls for initiated values or constants it was too slow for my taste.

  • I am not sure I understand --- What was happening when you used the alterable values?

    If you had some sort of example file you could upload I bet some of the super users here could figure out the best and most efficient way to accomplish the task.

    We have had some pretty large games created with the software.
    We have also had people who did things inefficiently (perhaps for Fusion only but you do need to work within the tools enviroment) and could get even their simple game to have decent performance.

    This game has a lot of stuff going on.
    Please login to see this media element.

    Please login to see this link.

  • The INI method is the slowest method you can implement for this. If you're experiencing performance issues, switching to an .ini file will not improve the situation at all unless you also change the method you're using for writing data. From fastest to slowest, the order's Global > Alterable > Array > INI. When practical, you should always transfer stored values to memory using static and local ("global" and "alterable") variables.

    For loops are expensive and you should avoid them when possible. This applies to everything; Fusion isn't an exception, it's just that its base speed is slower than a programming language's speed so the performance impact is more noticeable. Writing data, however, necessarily requires that you loop through your objects, so the challenging part is finding the most efficient ways of doing this.

  • Yeah, because you can't create multiple array, it's fairly difficult to work with for instances of objects unless you want to constantly loop through all of your objects. Technically you can work backwards to create instances of it but that would look really weird: Basically, to do that, you'd create an Array object for each Active object and then set a variable in each Active object to the fixed value of the created Array object. After that, any time you need to store object-specific data, you'd run a loop for each of your Array objects and each of your Active objects. If the fixed ID of the Array object matches the stored ID in the Active object, you'd write your data to the Array object.

    Why you'd want to ever do that with Fusion is something I don't know, but it's possible if you ever do want to assign an Array object to an Active object. What's more, I can't see how that'd improve performance in the least since you're still looping through your objects.

    Anyway. Because Fusion's Array doesn't have any abilities that the normal Active is missing, the better method to do this is to create instances of your Active objects in a forward manner: Create your main Active objects followed by helper Active objects. When you create both of them, store the fixed ID of the helper Active object in the main Active object. When you have to share values or strings across them, you just run a loop for each of your main Active objects and then if the fixed value of the helper Active object equals the stored value, write your values or strings to the helper.

    -Start of frame
    +Create Character
    +Create Helper
    +Set helperID("Character") to fixed("Helper")

    -Upon pressing Enter
    +Start loop for each Helper

    -On loop for each Character
    -fixed("Helper") == helperID("Character")
    +Write values and strings from Character to Helper

    The 10 String variable limit per object is quite challenging to work around especially when you need to achieve the highest performance possible, but it's doable in most cases. In the above example, I'm assuming that all the Characters have strings that all the Helpers needs; otherwise, just write your strings to the Helpers and you'll never have to run the loop for each Character. :) If a collision occurs, for example, Fusion automatically scopes that to the colliding objects, so when you run your loop for each Character, Fusion will only run a loop for each of the colliding Characters, not all of the existing Characters. This is incredibly efficient (and almost always necessary regardless), so understanding how this works and what Fusion is doing internally will save you a ton of time and allow you to do some really amazing things quickly and easily. I can put together an example of you'd like to see that?

    Edited once, last by Snail (August 24, 2015 at 11:10 PM).

  • As far I know INI or Array has no bearing on Clickteam Fusions' performance, Even at 20,0000 active objects running at once
    Fusion isn't using 4% CPU cycles. Would you be able to post an example to have a look?

    Would be able to post an example? I'll take a look, see if can find what the root of the challenge your experiencing.
    If don't want to share the source, you can PM me the an example.

    XD

    Please login to see this link.Please login to see this link.
    Take a course in Clickteam Fusion Please login to see this link.
    Youtube Please login to see this link.
    Please login to see this link.

  • You can store that externally in any format you like, but to do it efficiently, you'll need a way to identify the corresponding data for each object. The INI and INI++ objects should be able to help there. Internal List if you want to structure the data yourself. Array, however, is going to be the least efficient because you'll have to loop through it since you won't know ahead of time where the data is stored for any given object.

    Using an .ini file:

    -Start of frame
    +Run loop "Restore objects" 100 times

    -On loop "Restore objects"
    +Create Active object
    +Set id("Character") to loopIndex("Restore objects") + 1

    Start of frame
    -id("Character") < 10
    +Set Health("Character") to GroupItemString$( "Ini", "Monster" + str$(id("Character")), "Health")

    -Start of frame
    -id("Character") == Range(id("Character"), 10, 20)
    +Set Health("Character") to GroupItemString$( "Ini", "Constructor" + str$(id("Character")), "Health")

    With the Array object, you have no way to know which cell the Characters should read from, which is why you'd need to run the loop to do that. Here, you're taking advantage of Fusion's object scoping to pull all relevant data without performing a single loop.

  • As far I know INI or Array has no bearing on Clickteam Fusions' performance, Even at 20,0000 active objects running at once
    Fusion isn't using 4% CPU cycles. Would you be able to post an example to have a look?

    Would be able to post an example? I'll take a look, see if can find what the root of the challenge your experiencing.
    If don't want to share the source, you can PM me the an example.

    XD

    Sad to say I had deleted it, but all I did was run a fast loop on each object at the start, create an array, when each object was created, and set the first X in each one to the unique ID alt value per each. It takes quite a few for each loops but is very simple to do. Snail said it. And again for each loops to get back the same unique value. for loops dont seem to have any specific differentiating value even when using unique values? Even then I think the problem is a for loop still needs to run number of X array Count times to loop them all so you just end up using a for each loop anyway..

  • Yeah, you're going to be stuck running the same number of loops whether they're "fast" loops or for loops. A for loop just identifies each instance as it loops through them so you can write data specifically related to them. There's definitely no way around running a loop like that to write the data, but for reading it, you should never have to run a for loop.

    You can mimic the behavior of for loops using "fast" loops if you wanted to do that, but for loops make your life much easier and there's no downside to using them.

  • I'm using about 1500 array files 7 arrays at the same time with a range from 1..900 items within.
    Combined with this, I am using a lot of loops, and it's loading instantly for me.. Not seeing any slowdowns etc.
    And on top of that.. based on the amount of items in the array, it's creating an active.. Usually I have between 1200 - 2400 actives at once on my screen.
    loads within milliseconds, unless i am missing something here??

    As for INI's.. They are fast as well.
    Clearing individual items is somewhat slower. but not a showstopper.

  • This is actually the perfect example for you right now: Please login to see this link.

    How would you write those tiles to a storage file and then load them back?

    I am working on it, so far I've decided to expand an array with the amount of tiles and simply catalogue each actives current x and y and then I guess I will have to destroy them all and run a for loop that recreates the same active and with its same animation frame at each position with a for loop through the array. i admit i am unfamiliar with all the commands in fusion so its taking me awhile as I figure out a bunch of other stuff im doing. should I figure it out ill post a .mfa in that thread.

    I'm using about 1500 array files 7 arrays at the same time with a range from 1..900 items within.
    Combined with this, I am using a lot of loops, and it's loading instantly for me.. Not seeing any slowdowns etc.
    And on top of that.. based on the amount of items in the array, it's creating an active.. Usually I have between 1200 - 2400 actives at once on my screen.
    loads within milliseconds, unless i am missing something here??

    As for INI's.. They are fast as well.
    Clearing individual items is somewhat slower. but not a showstopper.

    I am having trouble figuring out how to use the ini ++, do I need to create the files first? the example wont load without the Move With Bezier.mfx. So I dont understand how to generate new Inis or rtf files or csvs. Am I right to say you just use loops to choose when to use certain arrays? maybe by counting 7 at a time in an index of objects such as 10000 objects, every 7 set to a global, loop from this global value at the end add 7, loop from the next set of objects with the id's 1-7, 8-14, 15-21? it is beyond me. perhaps I will recreate this and see what I did wrong.

Participate now!

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