I'm having a High RAM usage problem with my new 2D game and i'm trying to figure out why.
The way things are set up is that when the game launches I generate a huge randomized 2D world (a la snes final fantasy).
Basically I create a bunch of objects in my vectors.
My object classes are pretty much all made up of the following member variables:
string, int, booleans, SDL_Rect and SDL_Texture* (pointers to textures only each loaded once in my main game object).
Now up to now, when I generate my world, I create with (new) around 140,000 Objects, from ground tiles, to trees, rocks and building walls (all objects to create the world you are moving around in).
The problem I have is that already, after loading a small world (which is way to small for a real game) I'm up to 200 megs of ram, and if I load a big enough world, the ram goes up to 2 gigs and the game crashes at launch...!
Now I'm not sure if I'm using the right approach, am I wrong in generating all objects like this at once and then managing them? Should I be loading smaller parts of the world using text files and loading the world progressively as my character moves through it?
Does anybody have an idea on what I could do to fix this? It is an Open World Game, so you are not going through linear levels that can be loaded separately, you have to be able to have access any part of the world any time.
Now one distinction In would like to bring is that my world objects AI and Rendering are done when the Character is at about 2000 Pixel from the objects, so the game runs smooth. Its really just a question of RAM, the RAM cranks up at start-up when I Generate the objects and allocate them into memory.
You should have used the thread you created previously, rather than start a completely new one.
Is this a tiling sort of deal, a la Minecraft?
If so, then each object should be as simple as possible. Ideally, no larger than a 32- or 16-bit integer to identify what type of tile it is (empty, grass, stone, water, etc.). Then you use this ID as an index to a table describing the properties of that tile type, including how to draw it, its associated game mechanics (e.g. what happens when you walk over it), etc.
If you're still having memory problems after that, you'll have to generate the world in chunks and move stuff to and from the file system as you necessary.
Also make sure that you use a type of Resource Manager. This will hold all the resources that your game has loaded, and instead of loading every single graphic/other resource individually, just reference a loaded graphic/other resource.
Up to now Already Ive divided by three (3) my ram usage, from 190 megs to 60 megs simply by replacing all string member variables by int member variables.
It`s working great, there is more work to do, but it's awesome, the direction is good.
I will update this tread with the following improvements and their effects.
I was using strings has member variables to define my objects...
For example I have a ForestTreeClass which is:
#pragma once
#include "Sprite.h"
#include "RawResource.h"
class CForestTree : public CNatureDeco
{
public:
CForestTree(int a_TreeX, int a_TreeY, SDL_Texture* a_Tree, SDL_Texture* a_TreeTrunk, int a_Health, int a_TreeType);
~CForestTree(void);
SDL_Rect rect00; //Objects Real World Position
SDL_Rect rect01; // Objects Screen Position with Camera Computation
SDL_Texture* m_Tree;
SDL_Texture* m_TreeTrunk;
int m_Health;
int m_TreeType;
bool m_IsHit;
bool m_HasLoot;
int j;
};
)
But I switch string names, and use now int IDs.
m_TreeType used to be a string such as "MapleTree" , "OakTree" or ect...
So it stacked up pretty high, because at startup I create with a small world , about 5000 Trees and I create 140,000 tiles, which work similarily to CForesTree.
Here is for instance the CGroundBlock Tile, which is a ground Tile
#pragma once
#include "Sprite.h"
class CGroundBlock : public CBlock
{
public:
CGroundBlock(int a_GrassX, int a_GrassY, int a_GrassW, int a_GrassH, SDL_Texture* a_GroundBlock, int a_BlockType);
~CGroundBlock(void);
void Draw();
void DrawTitleScreen();
void DrawInventory();
int GetBlockType();
void ChangeBlock(int BlockType);
void SetPosition( int x, int y);
int GetX();
int GetY();