Game Development Community

Any ideas how to reduce memory usage?

by Sean Yeomans · in Torque Game Builder · 08/04/2008 (5:15 am) · 8 replies

Hi guys,


The game I'm working on in TGB has some extreme memory usage when I open the task manager. It's taking over 700,000K which I don't think is right for a 2D game with not much going on yet.

I'm really new to TGB and I'm not sure if there are proper ways to handle loading/unloading images, but heres a few notes to help you help me:

- All of the static and animated sprites have preload turned off
- The camera size is 2000x1000 (could this be too large? What is a good camera size?)
- The resolution is 1024x768
- I'm not using any methods of drawing only what the camera sees, is this already built in, or is it up to the programmer to write their own method?
- Though there isn't much going on yet code-wise, there is a huge amount of animated and static images that are in use
- Because of the camera size, the world is huge; 71792 x 3210 pixels


Any ideas on how to reduce the memory usage?
Thanks!

#1
08/04/2008 (12:07 pm)
- I'm not using any methods of drawing only what the camera sees, is this already built in, or is it up to the programmer to write their own method?

That is built in. But even though things offscreen will not be drawn (and their textures may or may not be loaded), they do still exist which takes some memory. If you really have a "ton" of sprites in your level, you might consider ways to reduce that number.

Also you might want the t2dImageMapDatablock(s) to have "allowUnload" = true. If a lot of your sprites have unique imagemaps, that could save you memory.

Any transparent / white space around your sprite images does take up memory, so if you can trim your images (or just reduce their resolution) this will save you memory usage.

- Because of the camera size, the world is huge; 71792 x 3210 pixels

TGB is definitely not optimized for a world of that size. Although I don't know if that affects memory usage it might affect collision detection and container queries. I suggest at least trying to reduce the scale of things to something more reasonable and seeing the results.
#2
08/04/2008 (1:00 pm)
Thanks for the reply, James.

What would you suggest is a good camera size? Would 1024x768 be a decent size?

Thanks again
#3
08/04/2008 (2:43 pm)
Thats still really big. The default in TGB is 100 x 75 I believe.
#4
08/10/2008 (5:37 pm)
I always looked at it this way. Take your smallest object, eg a projectile or whatever. That object should be the size of 1 world unit. You then scale everything based on that unit size. So for example, if your smallest object was a 16x16 projectile then 1 world unit would = 16 pixels. Then scale everything else based on that.

Make sense ?
#5
08/10/2008 (7:44 pm)
I would personally leave the scale 1unit = 8pixels. If you read through Melv's pdf on TDN about the underlying framework of TGB, you will understand why. TGB works of a "bin" system. When objects are selected to be rendered the engine searches through the bins of the scene and grabs all of the objects inside. If your objects are much larger than they should be, then they are going to take up a lot of bins.

For example: A regular object is 10x10 (units) and is inside 2x2 = 4 bins (I'm not 100% sure, but it is just an example). If you scale up all of your objects to be 10 times larger than they should be, your object is 100x100 and takes up 20x20 = 400 bins.

When the engine attempts to render the screen, it will search all of the bins in its view. In the above example, the engine might search a hundred or so in the normal situation, and a thousand or so in the later situation. This is a hell of a lot of additional work!

I have seen people talk about using 1unit = 1pixel. This is really, really bad in my opinion. Stick with a camera size of 100x75 (adjust it to keep screen/resolution aspect ratio correct, but keep height of 75 constant).

Disclaimer: I am not 100% sure on the size of the bins, I haven't messed around with that code for a while, but the idea is the same. Larger objects are inside more bins, more bins = more work for the engine.
#6
08/10/2008 (11:09 pm)
I did some more reading in that pdf I mentioned earlier (found here). I advise you to read the whole document, but in this case pages 8 through 10 are the most pertinent to this situation.

Quote:In TGB the container bin size is in world-units and the top-left of the container bin (0, 0) is at world-coordinate (0, 0). The default container bin size is 20 world-units and the container bin quantity is 256 giving a total of 256*256 = 65536 container bins by default.

More interestingly because the container bin size is 20 and there's 256 in each axis it means that the container system wraps the bins at the world coordinate 20*256 = 5120, 10240, 15360 etc.

Also it wraps in the negative direction so you get a wrap at -5120, -10240, -15360 etc. What this means is that if your scene is no larger than 5120x5120 then your collision searches won't encounter the wrapping issue detailed in the previous section "The Infinite World".
In the "Infinite World" section of that doc, it details how memory is saved by wrapping the bin system over large sections of the level. For example: when a level is too large, objects in positions (0,0) and (5120,0) share the same bin. If your world is 71792 x 3210 units TGB is wrapping the scene's containers at least 14 times.

Melv then discusses what the engine does to cope with large objects:

Quote:As efficient as the container-system is, there's a reasonable limit to how many bins you should be updating for any individual object.

To manage this, TGB has a structure called the "overflow" bin. It's a single container-bin where objects that are over a specified threshold are placed instead of the bins within the container-system. TGB internally manages this differentiation. What this means though is that the container-system will always return the objects in the overflow bin no matter what the bounding-box.

...

If the container bin sizes / quantity are configured correctly though you won't notice any reasonable difference in performance.
If you do not alter the source code in any way, then there will be significant performance problems. If you are upscaling your scene by a factor of X, then you will need to manage your bins accordingly to ensure that there isn't a performance problem.

I will stand by my statement made earlier, in that you shouldn't mess around with the overall scale of objects in TGB. Even if you have access to source, it would be better to leave this stuff alone unless you strongly feel that you need to mess around with it.
#7
08/14/2008 (7:07 pm)
Is there a performance hit when we change the scene size to 800x600? I didn't know that. I certainly haven't noticed a performance hit.
#8
08/17/2008 (2:41 am)
The recent build of TGB (1.7.4) was meant to have a "resizeContainerBins" function included in it. Presumably this allows one to set the size of the bins used in TGB, thus world wrapping should not be an issue. Only problem is, it wasn't included by accident (which I posted about).

You can actually setup a t2dSceneGraphDataBlock to set the "containerBinSize" and "containerBinCount" of the world, however, the level builder will not save these values out the next time you save the level, effectively deleting them.