Optimization/Load Time info - Please add what you've learned
I have been working very hard on optimization for the past week, and through some really long test procedures and lots of reading on the forums I'd like to share what I've found.
Small amounts of anything seem to be ok without too much drawback to load times and resource usage. This includes spawning, timers, constrain, and change attributes (each of these being on the big no no list but sometimes unavoidable).
What I've found is that if you have relatively few actors (30 or less) with optimized graphics and audio, "creating the scene" after the initial load works nicely. That is to say you need an app that can utilize this. If everything you're going to be using in the game is shown on the screen right off the bat, you're probably stuck, but if you have off camera actors, there is some hope.
I stagger spawning by 1 second each instance of an actor. If these actors don't have to go through a list of rules that change their attributes (i.e. if self.x = 15 change the color to whatever, if self.x = 16 change to a different color) then there is no drop in frame rate and ram usage increments up normally. What I've found, and am desperately trying to work around, is if you do have a (large) list of rules that change attributes based on an attribute, each spawn EATS RAM like it's been trapped in the desert for a week. An example of this is a .1 meg image used on an actor will spawn and add .1 RAM usage when there is not a large rule list. If this actor goes through a large list of rules, then for some unexplained reason, the RAM usage for each actor jumps to about 1 meg each. This does affect frame rate and causes the game to stutter. That's unacceptable, and if you're trying to load 100 actors, it's going to crash your app.
So, staggering spawns of actors WORKS just fine if you don't have a large list of rules the actors go through. I know some objective -c and I can tell you that there is something very buggy going on with this. Possibly storing of RAM after each rule is determined to not be in effect. This would normally need to be flushed, but instead they stick around until you reset the scene or restart the application.
Next is that having a large amount of actors will up your load time. I've been working with an app and attempting to keep a load time of around 7 seconds on a 4th gen ipod touch. This translates to about 13 seconds on an iPhone 3g. Adding in 100 actors (with a single tiny image used in each one), the load time went up but about 5 seconds. Keep in mind that these actors are not even in use in the actual game. They are just sitting in the actor pool. The biggest thing I learned from this was to get rid of every actor that you don't absolutely need. Even if they aren't used they are eating into initial load time.
Also I've noticed the power of the device processor is diminished when using viewer and sending info back to your mac. This is kind of a nice thing to know because it means you're actually getting very slightly better results when not running through viewer and sending info back.
I know this is probably a little long winded, but I like having more information than I need rather than scrapes from multiple places. Essentially what I've found is this:
Even the no-no's of GS behaviors won't significantly crush resource usage if used sparingly. In fact, often times they can help by taking time away from the initial load time.
Staggering spawning of actors works very nicely to reduce load time, but make sure the actors you spawn don't have any rules in them that change their attributes based on location (or possibly any other variable). If you think about it, it would take less time to load an initial 50 megs of RAM rather than 60. So stagger out the last 10 megs throughout 20 or more seconds after the game loads. The user won't know what's going on while they are playing, and the load time they have to deal with will be less. If it's just a straight up spawn of an actor, there won't be a lot of repercussions to deal with in terms of RAM. This only works with relatively small amounts of actors to spawn. In my experience you can spawn about 10 actors, each on their own second or half second, over a hundred times without any visual notice to the user.
Keep organized and experiment a lot. And share what you find that works, even the little things. It doesn't matter if someone thinks what you write is insignificant or obvious. It won't be obvious to SOMEONE out there, and that's the person that you're writing for.
Good luck to you, and to me!
Small amounts of anything seem to be ok without too much drawback to load times and resource usage. This includes spawning, timers, constrain, and change attributes (each of these being on the big no no list but sometimes unavoidable).
What I've found is that if you have relatively few actors (30 or less) with optimized graphics and audio, "creating the scene" after the initial load works nicely. That is to say you need an app that can utilize this. If everything you're going to be using in the game is shown on the screen right off the bat, you're probably stuck, but if you have off camera actors, there is some hope.
I stagger spawning by 1 second each instance of an actor. If these actors don't have to go through a list of rules that change their attributes (i.e. if self.x = 15 change the color to whatever, if self.x = 16 change to a different color) then there is no drop in frame rate and ram usage increments up normally. What I've found, and am desperately trying to work around, is if you do have a (large) list of rules that change attributes based on an attribute, each spawn EATS RAM like it's been trapped in the desert for a week. An example of this is a .1 meg image used on an actor will spawn and add .1 RAM usage when there is not a large rule list. If this actor goes through a large list of rules, then for some unexplained reason, the RAM usage for each actor jumps to about 1 meg each. This does affect frame rate and causes the game to stutter. That's unacceptable, and if you're trying to load 100 actors, it's going to crash your app.
So, staggering spawns of actors WORKS just fine if you don't have a large list of rules the actors go through. I know some objective -c and I can tell you that there is something very buggy going on with this. Possibly storing of RAM after each rule is determined to not be in effect. This would normally need to be flushed, but instead they stick around until you reset the scene or restart the application.
Next is that having a large amount of actors will up your load time. I've been working with an app and attempting to keep a load time of around 7 seconds on a 4th gen ipod touch. This translates to about 13 seconds on an iPhone 3g. Adding in 100 actors (with a single tiny image used in each one), the load time went up but about 5 seconds. Keep in mind that these actors are not even in use in the actual game. They are just sitting in the actor pool. The biggest thing I learned from this was to get rid of every actor that you don't absolutely need. Even if they aren't used they are eating into initial load time.
Also I've noticed the power of the device processor is diminished when using viewer and sending info back to your mac. This is kind of a nice thing to know because it means you're actually getting very slightly better results when not running through viewer and sending info back.
I know this is probably a little long winded, but I like having more information than I need rather than scrapes from multiple places. Essentially what I've found is this:
Even the no-no's of GS behaviors won't significantly crush resource usage if used sparingly. In fact, often times they can help by taking time away from the initial load time.
Staggering spawning of actors works very nicely to reduce load time, but make sure the actors you spawn don't have any rules in them that change their attributes based on location (or possibly any other variable). If you think about it, it would take less time to load an initial 50 megs of RAM rather than 60. So stagger out the last 10 megs throughout 20 or more seconds after the game loads. The user won't know what's going on while they are playing, and the load time they have to deal with will be less. If it's just a straight up spawn of an actor, there won't be a lot of repercussions to deal with in terms of RAM. This only works with relatively small amounts of actors to spawn. In my experience you can spawn about 10 actors, each on their own second or half second, over a hundred times without any visual notice to the user.
Keep organized and experiment a lot. And share what you find that works, even the little things. It doesn't matter if someone thinks what you write is insignificant or obvious. It won't be obvious to SOMEONE out there, and that's the person that you're writing for.
Good luck to you, and to me!
Comments
QS
Dr. Sam Beckett never returned home...
Twitter: https://twitter.com/Quantum_Sheep
Web: https://quantumsheep.itch.io
QS
Dr. Sam Beckett never returned home...
Twitter: https://twitter.com/Quantum_Sheep
Web: https://quantumsheep.itch.io
Here is what im doing to reduce load time , in All of my scenes , all of the actors that are outside the "camera" or that their alpha is 0 in initial load of that scene, dont have their graphics on but a small 2x2 white square , then "after 1 sec" , a manager actor changes all of their images to the correct one .
Roy
What I did was this:
I created a new actor and dropped a 2x2 image i made (this may be where I misunderstood you)
I created a new game attribute and called it imager: text because I like Typing "Yes" or blank when making rules
In the new 2x2 actor I made a rule that said if imager is Yes then change image to ____
I have a spawner/controller actor that changed the imager attribute to "Yes" after 1 second.
The actor stays 2x2. It turned the color of the new image but the size didn't change. If you have to change the width and height attributes inside each actor you're going to end up using more RAM than necessary throughout gameplay. This would definitely be one way to drop load time though. I think its benefits would be on a project to project basis.
Please inform me further. Something about what you wrote clicked with me but I feel like I'm missing something.
And thanks for sharing!
but maybe it will give you a chance to aviod spawning and place the actors in the scene already
Ok here is what i do:
i have lots of actors that the player dont see in the first look at the scene (cause maybe they are off screen or any other reason)
*in my project i have an image 2x2 simple white square.
thoes actors are already sized and placed, but the image i give them is this tiny square that almost dont take RAM , cause there is no need to load their original (big) image at the first second (which i belive make the loading of the scene faster)
instead of giving each and every one of this actors a rule to change their images to their actual graphics ,(which will be lots of rules cause i have lots of thoes actors) i have the 1 manager that have 1 rule and make the change for them!
now in the manager actor - instance NOT prototype
i have this rule :
When self time > 1 (or any other trigger you like)
change Current scene>Layers>"Your LAYER">"Your actor">Image to the disairable image (for example - "manu-button.png")
i came up with this method recently so i dont have proof that it decrease loading times , but my simple logic tells me it does..
im sorry for my english
i hope it helps..
Roy.
I don't understand EVERYthing you've been doing,
but it seems each programmer is developing their own work arounds to the current limitations
"change Current scene>Layers>"Your LAYER">"Your actor">Image to the disairable image "
I'm using Change Attribute and I've selected Current scene>Layers>"Your LAYER">"Your actor">Image but I'm at a bit of a loss as to how to choose the image I would like it to change to. If you wouldn't mind making this a little bit clearer for me I'll be happy to do a masssssssive test tomorrow to see if it reduces load time. The more detailed the better. Don't worry about your English, you're writing a lot clearer than many native speakers I know
I have to say, I'm excited to try this out once I know how to change the image in this manner. Hopefully it's a solid fix to loading times and RAM usage. I'll probably stagger the image change of around 200 instances (one every second) to see how it reacts.
What I personally need for the project I'm on is a way to individually change the size of around 200 instances total made from 3 different actors without it killing load times or RAM usage. My attempts thus far have been to no avail, but I'm positive there will be a workaround for it.
But yes, you can avoid constrains , or at least activate them only when needed with triggers , use "self.time" when possible instead if timer behavior , uncheck "Movable" in the NONE moveable actors or even with some of the NONE colliding actors , Uncheck visible in the NONE visible actors like invisible walls and stuff ,
well the rest is up to the code you make , try make things as efficient as possible , off course you get better and better from one project to the next
Roy.
You actually write the image name in quotes
Roy.
I tried it out and got the image to change, but the image size isn't changing. It still sticks with the 2 X 2 initial size..
Are your actors starting as 2x2 and changing size when you change the image? If so, I'm doing something very wrong.
The change image is just changing the image , not the size
off course in the same way you have access to the size attributes if you want to change them , its up to you
Roy.
The main concern I have is that using the change attribute feature to change large amounts of actors' variables caused some major RAM usage issues. We'll see if that comes up or not.
In any event, this is exciting! I'm going to be putting in a number of hours to these tests, so please be patient with me. I'll be back with results tomorrow. Thanks for the input.
Roy.
Night all. Best of luck to you, and to me.
Have you tried using Instruments to gather performance data?
Roy.
Using Instruments ( /Developer/Applications ) you can analyse the performance of any application or running process. Basically you attach to your app (either already running or started by Instruments) and then chart the performance of just about anything you want. From memory leaks ( NOT the primary cause of the GSC slowdown by the way ) to OpenGL and CPU performance, its all available to be analysed and poked at. iPhone or Mac you can directly see what effect certain actions are having.
Quick Start here http://tinyurl.com/62o3vg2
and a whole chapter here (old but totally relevant)
http://www.informit.com/articles/article.aspx?p=1229351
but in the meantime .. don't know if you found this old thread but a did a few performance tests relating to overlapping images:
http://gamesalad.com/forums/topic.php?id=15723
and this was a good one on images:
http://gamesalad.com/forums/topic.php?id=8164
the other concerning issue is of course that Gamesalad updates reportedly are addressing numerous know issues with memory leak and that each update should have some (but not all) fixed. Thus some of these issues may be improved over time so for example a work around of recycling actors could become unneeded if teh spawn/destroy issue gets resolved.
I will create a template to show the issue I covered in my post and upload it. Perhaps we can combine numerous test projects into one file that everyone can download and do self tests with and that way each GS update can be compared to the old?!?! Thoughts?
I'm a paid customer, but didn't realize how "beta" it still was, before I got into this So, what IS the primary cause, btw?
I'm working on another game, this one with a LOT of (instances of) actors onscreen,
trying to figure out how much stuff I can reasonably deal with at a time.
does anyone have similar detailed research about the spawning of actors vs. slowdown and eventual crash?
do I understand this right:
every spawned actor is given a place in memory, but that memory is NOT recycled,
even after that actor may be "destroyed", thus with continual spawning, eventually memory will run out,
hence the "memory leak" terminology, right?
and thus "recycling" actors is the only way to guarantee against an eventual crash?
The slowdown appears to be caused by ever more intensive processing loops (which ultimately lead to beachballing). I think it is down to garbage collection but the GS devs must have an idea of the real cause.
Even the truly vast quantity of leaks that GS seems to suffer from would take a long time to seriously start eating memory. GS starts beachballing in under ten minutes if you switch modes a lot, thats not memory leaking but endless prrocessing loops that consume every drop of CPU power. There are people using GS in 8gigs of RAM they all suffer the same problems.
Loads of applications leak the odd byte here and there, Safari and Mail are quite bad I believe!
Here are two recent changes that I've been doing to speed up loading times...
Using Pause...
http://gamesalad.com/forums/topic.php?id=17911
If I'm going to switch to a scene, and then switch back, it's better to use pause. That's because it doesn't have to reload the original scene. The problem is that this can drain performance and use extra RAM. It works for light scenes.
Optimizing my images...
Even though the same amount of RAM is used, images that are compressed with programs like ImageOptim seem to load much faster.
I should probably mention that app in The Unofficial GameSalad Textbook. It seems to be a great companion to GameSalad.