Too many layers? (4 Layers in background)

Hi Guys,

We’ve been working on a side scrolling shooter game for a couple of weeks, and we’ve gotten to the point where we’re integrating the graphics now.

We’re facing some performance issues and I’m not sure how best to proceed, so I thought I’d reach out to the community for some advice :slight_smile:

Essentially right now we have 4 background layers (scrolling at different speeds), a foreground layer (with the players ship and the enemies) and a GUI layer.

I suspect it’s the backgrounds that’s really killing the performance, but I’m out of ideas on how to improve things.

I started off with Peach Pellen’s tutorial here and then modified it to load and destroy 5 different images per layer. I then changed it so that I would move the display group (essentially the entire layer) rather than the individual sections.

What I’d like to know is am I asking too much of Corona/the hardware? or is there just a better way of doing this.

Currently just scrolling the background layers plus a small number of enemies (2 or 3) bring the FPS down to 14 (sometimes as low as 5) on the iPhone 4.

Any help/pointers/tips would be greatly appreciated.

Ali [import]uid: 10499 topic_id: 13472 reply_id: 313472[/import]

Sounds like you are doing something really wrong.

Are you loading the backgrounds before the game starts?

Otherwise without seeing all the code / assets its hard to say… [import]uid: 5354 topic_id: 13472 reply_id: 49451[/import]

Have you tried changing the framerate in your config file to 30? If you’re using physics this might help with performance. Are you using any high resolution (1024x1024 or higher) images? High res images will eat up texture memory in a hurry. [import]uid: 27965 topic_id: 13472 reply_id: 49470[/import]

On iPhone 4 texture memory not that much of an issue. It was the 3 and original that suffered from the 22mb limit.

You can throw about a bunch of stuff and Corona won’t drop fps on an iPhone 4.

This is why it seems to me like something is wrong in the code / how the images are loaded and handled. [import]uid: 5354 topic_id: 13472 reply_id: 49472[/import]

I’d suggest some brute force debugging to isolate the culprit(s). Switch off game components one at a time and test the performance on the actual phone each time.

Try turning off ALL background layers first. If the performance still lags at least you’ll know its not the background causing the problem. If it improves but not by much then there’s likely still a problem with one of the other elements in the game. If it runs smooth as silk without any background then start adding in one background layer at a time and testing on the phone each time to see if a particular layer starts to bog things down.

FYI, in my game I have 6 layers (4 background, 1 foreground, 1 UI) and can get 50-60 fps on an iPhone 4. Here are a few suggestions to keep in mind to keep the frame rate speedy:

  1. Try to avoid filling each background layer with many overlapping graphics that obscure each other (“fill rate”). For a particular pixel, if you have 4 layers of graphics one on top of the other, only the top layer’s pixel is visible but the phone is still rendering 4 pixels. Multiply that over an entire screen’s worth of pixels and it will kill frame rate, especially on older phones. Obviously not completely avoidable.

  2. Too many display objects lowers the frame rate. How many is too many? Probably in the low 100s. If you have backgrounds made up of hundreds of sprites, such as with a tile engine, and then render dozens of spaceships, particle effects, and text objects on top of that, you will kill your framerate, even if most of the objects are off screen. You can work around this by manually sorting through every display object and setting its alpha to 0 if it’s off screen. Corona is dumb in this regard and shouldn’t render off screen objects by default, but it does!

  3. Too many dynamic physical objects kills frame rate. Every time you add 1 new dynamic object to the physics simulation it must be checked against every other object. Dynamic objects that are resting (not moving) are supposed to “sleep” to improve physics performance, but I’ve noticed in my own Corona-based game many objects that aren’t moving or ever been touched fail to sleep. It’s the one thing I wish Ansca would fix since it kills performance, affects level design, and there doesn’t seem to be a workaround.

  4. Use spritesheets where possible, rather than hundreds of individual textures. Each texture requires a costly step in the OpenGL frame rendering process, but if all textures are on one spritesheet it only has to do that step once per frame.

  5. Make sure you’re not going over the phone’s texture memory limit. For iPhone 4 it’s 24 mb total for textures and texture buffers. That’s like 6 1024x1024 32-bit textures so It’s not that hard to use it up if you’re not careful.

  6. Check for, and fix, regular old nasty bugs and oversights. When testing my own game I accidentally created a level without a background, only to find the entire background of the previous scene still hanging around. Of course is was killing performance, but had been completely invisible to me until then.

[import]uid: 9422 topic_id: 13472 reply_id: 49486[/import]

To counter point 5. There is no memory limit for textures on an iPhone 4 or 3GS, it was limited on earlier models but the newer iPhones / iPad are using a different memory / chipset architecture so it doesn’t matter. [import]uid: 5354 topic_id: 13472 reply_id: 49489[/import]

@Matthew Pringle

Thanks for that info. I wasn’t aware of the new architecture for 3GS and beyond. Reading up on it a little it seems to be a “unified memory architecture” meaning all the memory of the device can be theoretically used as texture memory.

So perhaps 24mb is not the limit on iPhone 4. Still, there must be a physical limit based on the fact that there is not unlimited memory on a device, and everything including the OS, multitasking apps, and the currently running app must also use that memory. I couldn’t find any solid guidelines for what a real world texture limit is for the new architecture. The official Apple docs seem to suggest keeping texture memory use under 24 mb. [import]uid: 9422 topic_id: 13472 reply_id: 49493[/import]

Thanks a lot guys!

Really appreciate the help.

@Mathew Pringle
Regarding loading the backgrounds before the game starts, I initially tried that, but the memory usage was sky high. I need to explain a bit more about what we’ve got exactly. Each layer is actually made up of 5 sections (each one being the full width of the screen).

Initially each layer was one huge (i.e. 2400 px wide image), but that killed the memory, especially when we tested out Retina graphics. So what we’ve done is split the images into 5 section. When one section goes off screen, it’s removed and the next slice in the sequence is loaded and tacked onto the other end of the screen.

@calebr2048
I’ve reduced the framerate to 30 fps and that seems to have helped with the consistency quite a bit. The biggest textures that I’m loaded are the background layers, which are 4 full screen images (so 320x480 and 640x960 depending on the platform). Again, there are 5 sections for each layer.

@XenonBL
That’s a very sensible suggestion and frankly I’m kicking myself for not trying that first! I’ll give it a go and try to narrow down the culprit.

Again, thanks guys for taking the time to help out. Never ceases to amaze me how great the Corona community is.

Ali [import]uid: 10499 topic_id: 13472 reply_id: 49666[/import]

Like I said texture memory is not an issue if you are going 3GS or above. Obviously the device has physical limitations and other apps will be using some but you can get away with a lot more,

Your problem is if you are loading images while the game is running Corona will pause while the image loads. Corona cannot keep running while loading assets. This means the game will be choppy if you are loading lots of images while it is running. [import]uid: 5354 topic_id: 13472 reply_id: 49692[/import]

I see. So from your experience it would be better to go back to the original solution of have the very long single images which are essentially loaded only once, rather than the different sections being loaded/removed as they scroll into/out of view?

I guess I’ll give that a go again and see.

Thanks again,

Ali

[import]uid: 10499 topic_id: 13472 reply_id: 49701[/import]