Help re reducing texture memory usage in horizontal scrolling game? (image sizes, off-screen culling etc)

@Corona/all - really need some good advice re how to finish off a game I’m 90% through - a horizontal sliding game that was originally only going to be 2 screens wide, however now I am going 3-4 screens wide and 2 screens deep.  Started off doing a full background image (png) in photoshop for each background (which had sky + ground that forms tunnels for player).   Very nice & easy as:(a) your develop the whole background (e.g. say 3 screens wide worth) in one hit in photoshop, (b) the overlay pieces (ground, walls etc) being positioned there in the one image, and © can input the ground (less background) image into Physics Editor to create the physics boundaries.   So obvious issues with this approach now are:

a) texture size of the largish background images 

b) amount of file space in application with separate background image for each level (x3 for resolutions)

So I need some help/clarification around having to transition what I have to something better.  Any advice/direction would be appreciated. Here are some specific questions:

Q1 - Assume I should have one background image only in the whole app, and then overlay with smaller images that form the walls/ground etc?  

Q2 - Re Background Image - Should this best be one large image, then you render the same image multiple times, enough to paint the current screen + the next one the player is walking into?

Q3 - Corona & Off Screen Culling - Does corona now automatically handle managing texture memory such that off screen display objects (images or sprites) won’t take up textureMemory?   In other words specifically:  

Q4 - For a repeating image or sprite (that is already rendered on current screen) can these be created (separate instances) in all off-screen portions of the level as well, knowing that corona will ensure there is NOT a memory overhead?

Q5 - Same as Q4, however this time in the case that you have images off screen that aren’t currently rendered on screen.  In this case can I create this (as sprite or image) knowing Corona will manage?

Q6 - So if the answers for Q4 & Q5 are Yes, then this implies the basic principle is (a) break images down in to pieces, and (b) reuse same images as much as possible, and © don’t worry about managing when to create a display object (image/sprite) just create it up front for the level and corona will manage

Q7 - If answers to either Q4 & Q5 are no then this implies you need to manually manage when to create/remove your various display objects yourself then?  So you need to manually track where the player is relative to the width of the level (e.g. 4 screens wide) and then decide when to create/remove?

Q8 - Re Q7 is there any existing shared code that implements such a solution?

Q9 - Re Q7 - Any software/photoshop addon’s that make it easy to create an overall level (4 screens wide) in one PSD file in layers, and then break it out into pieces (per layer) but in a manner in which the position of the pieces can be written to file (ideally LUA file) to be used in the corona code?

Great questions… I’ll do my best to answer them from my experience.

Q1. You might want to look into tiled maps. These can be created with Tiled and loaded with one of the (three, I think) tiled map loaders currently existing for Corona SDK. I’m a collaborator on Ceramic Tile Engine (you can read the whole story here), which is an opensource library for tiled map loading that’s ridiculously easy to use, not to mention “opensource” --> “free” :smiley: It can handle off-screen culling.

Q2. You could try several smaller background images (enough to cover one screen + a little more) and shift the position to the other side as the player moves - never done it before, but there’s a sample code in the sample code base you get when you download Corona called JungleScene that has a repeating ground - just an idea.

Q3. Unfortunately, yes and no. Corona does greatly reduce texture memory taken up by offscreen objects, but it’s not entirely gone. For example, you can’t go building 1,000,000 images at once, even if they’re all offscreen.

Q4. See Q3. There will be a memory overhead no matter what - unless you completely remove objects as they go offscreen.

Q5. See Q4.

Q6. See Q3-5

Q7. Yep. The basic principle is “player moves left, delete tiles on right and draw tiles on left. Player moves right, delete tiles on left and draw tiles on right.” And then the same with the Y-axis.

Q8. Ceramic can do that automatically with what’s called tile culling. You can find documentation for it here.

Q9. Try Tiled - it doesn’t do that exactly, but it’s what’s used for Ceramic loadable maps. You create a tileset (a bunch of little images that can be used to create an entire level) and then draw the map using the tileset. Tiled then saves the map as a .json or .lua file and you can load it directly into Corona with Ceramic.

  • C

Hi Caleb - thanks helps for the leads - I’ll have a look at these…   

One question.  I’m assuming Ceramic implements the window manager type function you mention from Q7 correct?  If yes, and Ceramic is then being used for this, can it also be used for the various smaller Sprites you might have on the screen, or even the player itself.   For example if I think of my horizontal scrolling game I have:

a) background image (e.g. blue sky)

b) tunnels (made up out of ground/earth color)

c) sprites at various points (e.g. stars), some my have physics enabled

d) player itself that moves

So I’ve been targeting with my question reducing texture memory for a) & b) which are taking up quite a bit.  But if I use Ceramic as the “window manager” so to speak in my game, then do I need to use it (or can I use it), to manage the sprites I talk of in c) as well?

@One question: Yep - tiles are removed as they are no longer visible, and added as they become visible. You can add your player or other sprites to a layer and they’ll move with the built-in camera system for Ceramic, but they won’t be culled.

If you build your tunnels out of tiles, they will be automatically culled with Ceramic’s tile culling. That would solve that. If your tunnels are physical, you can read the documentation for Ceramic to find out how to add physics (including custom shapes!) to tiles in a map, using tile properties.

As for the background, that’s the tricky part. Try making everything else tile-based and see if the background can stay without optimization.

And, as for the sprites, you can build them out of tiles, too - if they’re physical, you can add physics. Unless you’re accessing them a  lot , you can turn them into tiles, and thus, they’ll be automatically removed. If you don’t want them automatically culled, you can simply add them to the layer by accessing it and :insert() -ing them into it, just like a display group.

  • C

Sounds good. Probably have to jump in at this stage and try. Maybe there’s a Tiled/Ceramic Corona example project?

What was the issue re the background itself? Whilst it would be easy to have one single age for this, for all levels, if a level was 5 screens wide the no doubt you would want to braeak it down and do culling. In which case you’d want to use Ceramic too right?

When you download Ceramic (from the pull request, not the main page - the repository owner hasn’t yet merged the two, and the main page version is older), there are three sample projects to try out.

The issue with the background is that large images take a lot of texture memory - besides, they can’t exceed the max texture size for the device. Cutting them into tiles is “dangerous”, too, because making a solid background of tiles can be *taxing* on Corona + Ceramic.

Of course, the larger the tiles are, the faster the culling system works, so you could just break your background into tiles a bit larger and no one would be the wiser :slight_smile:

  • C

HI Caleb - can I ask:

a) not exactly sure how to download?  Do you mean navigate to say “https://github.com/GymbylCoding/CoronaTiled” and download zip?  

b) Also with Tiled + Ceramic:  How granular can the physics boundary be?   Can a physics boundary cut across one (1) tile?  For example if the tile itself was an rounded edge of the ground, and you want to make sure the player does collide with the edge of the tile that is transparent, i.e. they would need to go into the tile say 1/2 way until they hit the ground itself?   (background - currently I’m using photoshop & physicsEditor to create the physics LUA file shape definition, so you really do have the player only crashing when they really touch up against the actual line boundary of the ground)

c) how does the physics collections end up working in Corona?  i.e. would you get a collision started then finished for each tile the player crosses, even though you might really want it as they hit the initial object tile, and then again when they exit the final object tile?  (assuming the objects was multiple tiles wide)

a) You can download it there, yes.

b ) The physics boundary is defined by the tile or layer propery physics:shape. If you check into the documentation I linked to, it’ll have the guide to adding properties like physics. You can make the physics shape with the ability Ceramic has with JSON tables; prefix the value with !json!.

c) Well, physics are added to each tile. So a collision is started with they hit a tile, and a collision is ended when they stop hitting the tile. For more customizable physics, you could use object layers - they’re more flexible, and can thus be useful as physics shapes.

  • C

thanks Caleb - this is really helping me determine whether I should dive in or not re what I’m trying to do - can I ask a question about physics boundaries however & round/trip type developing.  Perhaps a good way to ask is to give a simple example re using Tiled + Ceramic:

Scenario:  Want a level with say two large circles each of which has physics enabled.  Each circle is say several tiles wide, so definitely not 1 circle per tile.   

a) drawing the circles - so this would just be in Tiled and your ability to create tiles that replicate the edge pieces.  So should be doable/ok

b) sounds like for coarse gain physics you could define in Tiled which tiles have physics enabled, and then Ceramic would pick this up and automatically create the path you need for the display object to have physics?  is this correct?  (i.e. you don’t need to manually define the path, or use another tool like PhysicsEditor to create it?)

c) for fine gain physics, so in my scenario you want the play not to collide with the corner of one of the circles, but rather only after it enters the corner tile to the point it touches the actually circle itself.   So in this case (same questions as be b)  you could define in Tiled which tiles have physics enabled, and then Ceramic would pick this up and automatically create the path you need for the display object to have physics?    Is this possible?  If yes I assume this is the object layers you were referring to and I assume these are Tiled object layers you’re talking about?

thanks again

As a beginning note, you actually could use two tiles to do your two-circle scenario with Ceramic - simply use physics:radius = [size of several tiles]

a ) Yes

b ) Not quite. Corona doesn’t give us pixel access, so you’d have to define it yourself.

c ) If you see my opening note, you could make a tile in the center with physics:enabled and physics:radius and simply draw the circle with tiles; or you could use object layers (I’m talking about the layer type that uses objects instead of tiles - it’s a completely different type of layer). With object layers, you could define physics:enabled and Ceramic automatically adds radii to circle objects.

  • C

ok thanks Caleb - I’ll look read up on Tiles “object layers”… thanks for the pointers

Hi Caleb - got updates from Tiler flowing through to Corona in the sample code ):     Having a few issues with the Tiler image and object layers.    Can I ask:

a) Does Ceramic support the Tiler Image and Tiler Object layers?  

b) Do have an example of use of these with Ceramic through to Corona?

Is there any Ceramic doco on what specific Tiler parameters/names are significant? i.e. is there anything you need to know about how Ceramic works so that when you build/name layers in Tiler it will flow through correct?

c) Can I also throw in a question re resolution handling for Ceramic/Corona:  Where abouts in the chain of Tiled & Ceramic to Corona can you produce the 3 different resolution versions?  and is this automated?

a) Yes, Ceramic does support both. Image layers are currently quite basic, but that only comports with the level of functionality with image layers in Tiled - they seem to be almost a prototype. Object layers are supported - each object is created according to be as near as possible as the object you created in Tiled.

B) The platformer sample code for Ceramic has basic object layers - each platform is an object.

Ceramic reserves several “prefixes”; i.e. prefix a value with physics: and it will be added to the physics table; prefix a value with objects: (or tiles:) and it will be added to the objects or tiles in the layer; etc. You can find a more complete documentation in the docs found here.

Besides prefixes, there are also a couple of reserved property names themselves. These properties are layerScale, xParallax, and yParallax. More might be added if needed, but so far, this is it. Most properties can be set through default-ness.

c) Not exactly sure what this question means…?

P.S. I hate how you can’t ever write b ) without a space or it turns into that little emoticon…

  • C

sorry re ©.  Just wanted to understand what the approach is regarding use of Corona dynamic scaling, so where you have 3 versions of each image (e.g. higher res versions for iPad retina etc).  With SpriteHelper2 for example it automatically creates the 3 different (a) PNG sprite files plus (b) LUA files that can used accordingly.    I think the LevelHelper product does the same.  So I’m just wondering how I would cater for automating dynamic scaling for Corona when using Tiler with Ceramic?     

Ceramic itself doesn’t do that, but if you have your suffixes set up (@2x, etc) and your settings correct, Corona should do that automatically. (or at least I’m pretty sure it does)

  • C

There needs to be the actual creation of the other size images resolutions at some point.

I know - I mean if you name your images correctly after you’ve created them with names like “image.png”, “image@2x.png”, etc., you can create the corresponding image sizes in config.lua under “imageSuffix”. Then you put your suffix and the scale it denotes. For example, if you have a retina image for devices with twice the scale of normal devices, you name your retina images “image@2x.png” and in the config set image suffix as this:

[lua]

imageSuffix={

  ["@2x"]=2

},

[/lua]

If you do that, I’m pretty sure Corona automatically detects the resolution and uses the appropriate image; if the scale is 2 check for images ending in @2x, etc.

  • C

so I guess then if you create the different size versions of your Tiled “tileset” images using this approach then hopefully then it all works ok 

*Hopefully* :smiley:

  • C

Great questions… I’ll do my best to answer them from my experience.

Q1. You might want to look into tiled maps. These can be created with Tiled and loaded with one of the (three, I think) tiled map loaders currently existing for Corona SDK. I’m a collaborator on Ceramic Tile Engine (you can read the whole story here), which is an opensource library for tiled map loading that’s ridiculously easy to use, not to mention “opensource” --> “free” :smiley: It can handle off-screen culling.

Q2. You could try several smaller background images (enough to cover one screen + a little more) and shift the position to the other side as the player moves - never done it before, but there’s a sample code in the sample code base you get when you download Corona called JungleScene that has a repeating ground - just an idea.

Q3. Unfortunately, yes and no. Corona does greatly reduce texture memory taken up by offscreen objects, but it’s not entirely gone. For example, you can’t go building 1,000,000 images at once, even if they’re all offscreen.

Q4. See Q3. There will be a memory overhead no matter what - unless you completely remove objects as they go offscreen.

Q5. See Q4.

Q6. See Q3-5

Q7. Yep. The basic principle is “player moves left, delete tiles on right and draw tiles on left. Player moves right, delete tiles on left and draw tiles on right.” And then the same with the Y-axis.

Q8. Ceramic can do that automatically with what’s called tile culling. You can find documentation for it here.

Q9. Try Tiled - it doesn’t do that exactly, but it’s what’s used for Ceramic loadable maps. You create a tileset (a bunch of little images that can be used to create an entire level) and then draw the map using the tileset. Tiled then saves the map as a .json or .lua file and you can load it directly into Corona with Ceramic.

  • C