Speed things up..

Monkey Targets Forums/Android/Speed things up..

Paul - Taiphoz(Posted 2013) [#1]
Wondering what techniques other people use to keep their frame rates as high as possible..


therevills(Posted 2013) [#2]
* Atlases
* Pooling Lists
* Limited Sounds
* Don't use "new" in your main game loop
* Precache images
* Don't load any new resources in the main loop


Amon(Posted 2013) [#3]

* Atlases
* Pooling Lists
* Limited Sounds
* Don't use "new" in your main game loop
* Precache images
* Don't load any new resources in the main loop



At least leave some room for others to chime in. :D


Paul - Taiphoz(Posted 2013) [#4]
care to throw some detail in with those buzz words therevills ?.

Atlases or sheets I use, would be nice to get everything on a single sheet but some times its not practical, does sound really have that big of an impact on frame rate, its not something I have personally noticed.

Whats your method for not using new in the main loop ? I have a fair guess at what you mean but would love some more info there, I use new any time I create a new effect, explosion, or spawn in new sprites to the level so I probably use new a lot, but then I have not really noticed slow down in relation to these calls, the frame rate drops I see, seem to be coming from me drawing to much to the screen, I tend not to get drops in frames when new stuff is being created.


Volker(Posted 2013) [#5]
Using android:minSdkVersion=9
Kicks around 15% of the user but avoids the stuttering because of the old not concurrent garbage collector.

What's that, where is the preview button?


therevills(Posted 2013) [#6]
* Atlases
- Try precaching (see below)
* Pooling Lists
- Create all your objects first and reuse them over the game. For example, say you have a bullet list and you want to create a bullet every time the player fires... you can "guess" how many bullets the player can fire so instead of just calling "new bullet(x,y)", grab one from the pooled list of bullets.
* Limited Sounds
- Yes I have seen sound affects FPS
* Don't use "new" in your main game loop
- Depending on what version of Android you are targeting, in the dark days (1 - 2 years ago, not sure now since Volker's post about the GC - got any info on that?) when you create a new object, it gave the GC a change to kick in and cause a slow down (sometimes). See above with pooling.
* Precache images
- When loading your images just draw them off screen so they are already on the GPU, so when you go to use them they are ready to go.
* Don't load any new resources in the main loop
- For example don't load images or sounds - say you create a bullet sprite and just "quickly" load a new image for it, this will cause I/O and hurt your FPS


Paul - Taiphoz(Posted 2013) [#7]
Thanks I suspected most of it, never thought about caching the images first tho, I guess thats why I get a stutter when a sprite is drawn for the first time, its not a massive issue really but def worth doing, would I be right in saying that it only needs to be a single sprite from a sheet tho given its on the same image ? or how would grab image be effected would grabbed images from existing sheets need to be cached as well...

that's given me something to think about, thanks for the info.. anyone got any other ideas ?


Paul - Taiphoz(Posted 2013) [#8]
Talking about a bullet as an example, how do you go about it I was thinking giving the class an Active boolean which can be set to true or false when its active and on screen, and then when I shoot a new bullet just look for the first InActive sprite and move it, set its image to the right image and then set it active, or is there a better way ?

Would it be worth creating a second list for active objects and a list for all InActive objects... I think that might actually cause more overhead tho.


Paul - Taiphoz(Posted 2013) [#9]
Oh talking about pre-caching could you not code that into diddy so that it does a quick offscreen render of all images in its map when the first screen is drawn or something ?


Volker(Posted 2013) [#10]
Garbage collection:
http://developer.android.com/about/versions/android-2.3-highlights.html
The new GC is integrated since Android 2.3.
So minSdkVersion=9 forces to use the new one.
http://developer.android.com/guide/topics/manifest/uses-sdk-element.html
Under the old GC it could take 30-50 ms to finish which results in stuttering.
The new one should be finished under 3 ms.

I was tired about all the pooling stuff, so I decided to target only the higher versions.


Paul - Taiphoz(Posted 2013) [#11]
My current issue sadly seems not to be tied to the above, I am trying to draw 400+ sprites and I think the hardware just aint liking it, I wonder if I have approached the max a decent phone will play nice with in terms of the total number of sprites being rendered.

the good thing is that I can cut nearly half of that simply by removing the call to Glow() and can probably reduce it more by not using every single tile space available for a level which is find cos I have a lot of tile room.

anyway bed time.. gona book mark this thread I wana have a read at that stuff you linked Volker.


Wylaryzel(Posted 2013) [#12]
Thanks I suspected most of it, never thought about caching the images first tho, I guess thats why I get a stutter when a sprite is drawn for the first time, its not a massive issue really but def worth doing, would I be right in saying that it only needs to be a single sprite from a sheet tho given its on the same image ? or how would grab image be effected would grabbed images from existing sheets need to be cached as well...


At least what I have identified is that it should be sufficient to draw at least one GrabImage from a Atlas to move the whole Atlas to the GPU memory. I had stuttering myself but with drawing one image during the loading screen it went away.


Gerry Quinn(Posted 2013) [#13]
Monkey has a Pool class which can help with object re-use if you don't want to manage it yourself.


Paul - Taiphoz(Posted 2013) [#14]
wot......... is there an example of its use some where I didnt know it had that .. not seen it in the doc's although I am gona go look now.


Gerry Quinn(Posted 2013) [#15]
Just look in brl for pool.monkey. It's as simple as it could be, really. Just:

global thingPool:Pool< Thing > = New Pool< Thing>
...
' Somewhere in code
Local thing:Thing = thingPool.Allocate()
thing.Clear()
...
' Finished with it
thingPool.Free( thing )


I just put in a possible Clear() function there to indicate that the object may have been used before and contain old data. For example a Point object with x:Int and y:Int might not come with zero in x and y. Obviously you don't have to have a Clear() function, just remember that.

You can create the pool with any number of objects, depending how many you will need. Default creates 10 initially.


muddy_shoes(Posted 2013) [#16]
The Android dev kit comes with a pretty decent profiler that's easy to use via Eclipse. While all the general advice is fine to bear in mind when you're planning/writing code for Android if you've got running code with performance issues then you should be profiling that code to see what actually is wrong rather than taking informed guesses.

I'm happy to help you with profiling it via Google Hangout/Skype/IM if you want. Or you could send me the project and I'll profile it and offer advice if I can.


Paul - Taiphoz(Posted 2013) [#17]
muddy_shoes I will deff get you in the monkey hangout and get some help with that after xmas, it's something I don't really know much about, this is the first time its ever really been an issue for me thankfully.


Supertino(Posted 2013) [#18]
When I switch to using 2 1024x1024 atlas' for my Santa's workshop game from something like 30-40 individual images the speed improvement on my old HTC phone was like night and day, texture swapping where possible should be avoided.


bruZard(Posted 2013) [#19]
"Don't load any new resources in the main loop "
do you load all resources in App::OnCreate() ?!?


therevills(Posted 2013) [#20]
do you load all resources in App::OnCreate() ?!?

Depends on how big the game is... but I actually didn't mean that, I normally load common resources during OnCreate and other resources when loading levels - not in the main game loop (ie when the player is playing...)


Paul - Taiphoz(Posted 2013) [#21]
Yeah I have used the loading of levels to switch atlas's a few times, its handy since the player is prepped and prepared to wait during the process its far better doing it then, than trying to do it on the fly.