Ways on Keeping My Game From Eating RAM

Pages: 1234
Well I just finished my MapManager class which allows me to easily switch maps.

I'm currently programming a new object called warps that warp me to new areas in the map.

Now that my program holds maps in memory, how can I keep my map from being a RAM hog? The maps don't render if not selected, that's one way I reduced ram usage.

Any more ways? I'd like my players to switch through maps without being forced to wait through a loading screen, so the least amount of time spent loading would be my target.
Don't load all the maps at once. Is there a way to tell in advance when the player will switch maps? If so you could silently load the next map before they switch to give the impression that there is no load time. If not, then you'll just have to deal with load screens. I doubt you're maps take so long to load that you'd really need them though.
how can I keep my map from being a RAM hog?


How much memory does each map use? If having a loaded map only consumes like 2K of memory, you'd have to have thousands of them loaded before you have to worry about "hogging" memory.

(and even then... 2K per map * 1000 maps is only 2 MB of memory. On a machine with 8 GB that's practically nothing).

The maps don't render if not selected, that's one way I reduced ram usage.


Rendering has nothing to do with RAM usage. That's CPU/GPU time usage.

RAM usage is how much memory you're using. IE: variables and memory buffers allocated. Anything that the game has to "remember" while its running.

Any more ways?


If you're really worried about memory usage (but again note you may not need to be), the obvious solution is to only keep maps loaded for as long as you need them. So when the player moves to a different map, unload the old map they're no longer using before (or shortly after) loading the new map.

I'd like my players to switch through maps without being forced to wait through a loading screen, so the least amount of time spent loading would be my target.


Unless you have very large and/or complicated maps, I'm pretty sure your maps will load virtually instantaneously.
Last edited on
Alright thanks. But when it loads from the file, it takes a decent amount of time. Is that ram or CPU usage?
Neither. That would be Disk I/O which is orders of magnitude slower.
closed account (o1vk4iN6)
How much time ? I've had 200 MB+ map files loaded into memory before (was on a tablet) that only took about 5-10 seconds to load, and it was using a binary format that required all the pointers to be updated. Loading files into memory is considered slow but I guess it really depends on what kind of processing you are doing. In this case if your maps are only 2K I doubt loading it into memory is what's causing it to be slow.
Last edited on
+1 @ xerzi

This depends on the maps and how they're being loaded.

Disk I/O is definitely slow, but for it to be noticable the files would have to be very large.


EDIT: I'm assuming Fredbill30's project here is small-scale. I'm not anticipating very large maps. I'm wondering if they're slow because he's doing some weirdness with how he's loading them.
Last edited on
It isn't binary, it's a text file.

Once I finish my map editor I'll change it to binary.
What does loading a level involve? ie. Are you also loading all the assets for the level (sound, sprites, etc.) or are they already loaded in some form of asset manager? Are you doing anything else with the data other than dump it into memory?
closed account (o1vk4iN6)
Well that might not be your problem, maybe if you could post some code with an example map. Cry engine has most of it's files in text format and that makes it easily portable and modifiable rather than a binary file (depending on how it's implemented but still things like float point precision are a bit harder to deal with).
Last edited on
Lach all resources are loaded in the resource manager, minus the maps.

xerzi a map of mine consists of 2 files, the first to functions of my map loader explain it nicely. It's a lot better than I could explain in words.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
int Map::Init(std::string initfile, std::string mapfile)
{
	std::ifstream mapinitfile;
	// Set the colors
	Black.r = 0;
	Black.g = 0;
	Black.b = 0;

	// Set the mapfile location to equal the class's string
	s_mapfile = mapfile;

	// Attempt to open the map's initialzation file.
	mapinitfile.open(initfile.c_str());

	// If the the initialzation file is equal to NULL, output my message to
	// the console, close the map, and return an error value.
	if(mapinitfile == NULL)
	{
		std::cout << "Failure to load map init file.\n";
		SDL_Delay(5000); // Stop the program for a bit so the user can see the message
		                 // displayed

		mapinitfile.close();

		return 1;
	}
	Name = "";

	// Now get initalization information from the text file.
	mapinitfile >> Name;
	mapinitfile >> MaxTiles;
	mapinitfile >> MapW;
	mapinitfile >> MapH;

	std::cout << "\n\nLoaded values from map initialization file(debug):\n" << "========================\n";
	std::cout << Name << "\n";
	std::cout << MaxTiles << "\n";
	std::cout << MapW << "\n";
	std::cout << MapH << "\n";
	std::cout << "========================\n\n";

	MapW *= 32;
	MapH *= 32;
	MapW -= 32;

	// Use the Draw class to load the Tileset image.
	Tileset = Res.TileSet_IMG;
	std::cout << "Attempting to load Tileset\n";
	
	// If the Tileset fails to load, I output a message and return an error value
	if(Tileset == NULL)
	{
		std::cout << "Tileset failed to load.\n";

		return 1;
	}
	else
	{
		std::cout << "Tileset successfully loaded\n";
	}

	Font = TTF_OpenFont("Fonts/din-mediumalternate.ttf", 18);
	window[0].x = 500 + 2;
	window[0].y = 32 + 2;
	window[0].h = 32 - 4;
	window[0].w = 200 - 4;

	window[1].x = 500 ;
	window[1].y = 32;
	window[1].h = 32;
	window[1].w = 200;

	nameDisplay = NULL;

	nameDisplay = TTF_RenderText_Solid(Font, Name.c_str(), Black); 

	// If this function encounters no errors, return a
	// successful value
	return 0;
}

int Map::InitTiles()
{
	std::ifstream map;

	// Temporary variables to determine where tiles are spawned
	int x = 0;
	int y = 0;

	// Attempt to open the map
	map.open(s_mapfile.c_str());

	// If the map doesn't open, display an error message and
	// return an error value
	if(map == NULL)
	{
		std::cout << "Failure to set tiles.\n";
		return 1;
	}

	// A for loop to go through the tiles one by one
	for(int t = 0; t < MaxTiles; t++)
	{
		// Make a offset for the tile types
		int tiletype = -1;

		map >> tiletype;
		// If the map fails to get the tile id
		if(map.fail() == true)
		{
			// Display this message
			std::cout << "Map failed to load.\n";

			// Close the map file, then return an error value.
			map.close();
			return 1;
		}
		// If the tile type is a valid number, go on to work with them
		if((tiletype >= 0 ) && ( tiletype < TILETYPES))
		{
			// Add a tile to the vector at the coordinates of x, and y, then with the tiletype
			// loaded from the map.
			Tiles.push_back(new Tile(x, y, tiletype));
		}

		// If it isn't a valid number close the map immediately and return an error
		else
		{
			map.close();
			return 1;
		}

		// Add the value of x by 1 tile pixel width each time a tile is loaded
		x += TILE_W;
		// If the x value passes the level width we set x to 0 and
		// make the y value move on tile height down.
		if(x > MapW)
		{
			x = 0;
			y += TILE_H;
		}
	}
	std::cout << "Tiles successfully initialized\n";
	map.close();
	return 0;
}
Font = TTF_OpenFont("Fonts/din-mediumalternate.ttf", 18);


Why is a Map loading a font?


EDIT: and fonts are pretty big resources. Shouldn't that be going through a resource manager? I'm willing to bet this is what's taking long.
Last edited on
My resource handler actually is supposed to load the fonts. (I guess I forgot to change that bit to get the font from the Resource Manager class.

(Off Topic: How can I determine the absolute value of an integer?)
Last edited on
closed account (o1vk4iN6)
Pass by const reference whenever you can, that way you pass by reference but you can guarantee the original data isn't modified (to some degree).
int Map::Init(const std::string& initfile, const std::string& mapfile)

What type is "Tiles" ? If it's a vector you should do

Tiles.reserve(MaxTiles);

At least that way it won't be allocating and copying memory when you know how big the vector needs to be prior to filling it.

How big width and height wise is the map you are testing ?
Last edited on
I have 3 maps currently made.

My first is 41 by 41 I believe, the other two 50 by 50.

I'm looking for art inspiration, sorry for the long time with no reply.

Thanks disch for the absolute value thing

thanks xerzi for informing me about that.

(Off topic: Any footstep sounds?)
Last edited on
50x50 is nothing. I am now convinced that the font loading is the reason for the poor load performance.
It's not really bad, it takes only about 3 seconds of loading.
3 seconds is an extremely long time to load a 50x50 map. Even with a font.

Is that in a Debug build?
Yes. Don't forget I use system("TITLE <insert title here>"); to change the name of the console window.
Last edited on
Pages: 1234