# XNA: Huge Tile Map, long load times

Recently I built a tile map generator for a game project. What I am very proud of is that I finally got it to the point where I can have a GIANT 2D map build perfectly on my PC. About 120000pixels by 40000 pixels. I can go larger actually, but I have only 1 draw back. #1 ram, the map currently draws about 320MB of ram and I know the Xbox allows 512MB I think? #2 It takes 20 mins for the map to build then display on the Xbox, on my PC it take less then a few seconds.

I need to bring that 20 minutes of generating from 20 mins to how ever little bit I can, and how can a lower the amount of RAM usage while still being able to generate my map.

Right now everything is stored in Jagged Arrays, each piece generating in a size of 1280x720 (the mother piece). Up to the amount that I need, every block is exactly 40x40 pixels however the blocks get removed from a List or regenerated in a List depending how close the mother piece is to the player. Saving A LOT of CPU, so at all times its no more then looping through 5184 some blocks. Well at least I'm sure of this.

But how can I lower my RAM usage without hurting the size of the map, and how can I lower these INSANE loading times?

EDIT:

Let me explain my self better. Also I'd like to let everyone know now that I'm inexperienced with many of these things.

So here is an example of the arrays I'm using. Here is the overall in a shorter term:

``````    int[][] array = new int[30][];
array[0] = new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
array[1] = new int[] { 1, 3, 3, 3, 3, 1, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
``````

that goes on for around 30 arrays downward. Now for every time it hits a 1, it goes and generates a tile map 1280x720 and it does that exactly the way it does it above.

This is how I loop through those arrays:

``````        for (int i = 0; i < array.Length; i += 1)
{
for (int h = 0; h < array[i].Length; h += 1)
{
}
{
``````

Now how the tiles are drawn and removed is something like this:

``````    public void Draw(SpriteBatch spriteBatch, Vector2 cam)
{
if (cam.X >= this.Position.X - 1280)
{
if (cam.X <= this.Position.X + 2560)
{
if (cam.Y >= this.Position.Y - 720)
{
if (cam.Y <= this.Position.Y + 1440)
{
if (visible)
{
if (once == 0)
{
once = 1;
visible = false;
regen();
}
}
for (int i = Tiles.Count - 1; i >= 0; i--)
{
Tiles[i].Draw(spriteBatch, cam);
}
for (int i = unWalkTiles.Count - 1; i >= 0; i--)
{
unWalkTiles[i].Draw(spriteBatch, cam);
}
}
else
{
once = 0;
for (int i = Tiles.Count - 1; i >= 0; i--)
{
Tiles.RemoveAt(i);
}
for (int i = unWalkTiles.Count - 1; i >= 0; i--)
{
unWalkTiles.RemoveAt(i);
}
}
}
else
{
once = 0;
for (int i = Tiles.Count - 1; i >= 0; i--)
{
Tiles.RemoveAt(i);
}
for (int i = unWalkTiles.Count - 1; i >= 0; i--)
{
unWalkTiles.RemoveAt(i);
}
}
}
else
{
once = 0;
for (int i = Tiles.Count - 1; i >= 0; i--)
{
Tiles.RemoveAt(i);
}
for (int i = unWalkTiles.Count - 1; i >= 0; i--)
{
unWalkTiles.RemoveAt(i);
}
}
}
else
{
once = 0;
for (int i = Tiles.Count - 1; i >= 0; i--)
{
Tiles.RemoveAt(i);
}
for (int i = unWalkTiles.Count - 1; i >= 0; i--)
{
unWalkTiles.RemoveAt(i);
}
}
}
}
``````

-
Slow down. Evaluate. What is taking the time, generating something? Or loading the resources for the level to be played? – karmington Apr 4 '12 at 1:34
There's not nearly enough information to answer this. You have to go into much more detail on how you're storing and generating the data. – Pubby Apr 4 '12 at 1:42
Have you done any profiling? You can't speed something up without knowing what's actually taking so long. – doppelgreener Apr 4 '12 at 1:44
As Jonathan says, rule 1 of optimization: profile. – Laurent Couvidou Apr 4 '12 at 8:34

It takes 20 mins for the map to build then display on the Xbox, on my PC it take less then a few seconds.

Up to the amount that I need, every block is exactly 40x40 pixels however the blocks get removed from a List or regenerated in a List depending how close the mother piece is to the player.

If I had to hazard a guess your map generation method generates a lot of garbage. Try just using the stack and arrays you allocated.

If I remember correctly the Xbox's GC looks over every reference and frees the unused ones for every 1mb of memory changed. In the future try to deploy often to the 360 as there a lot of gotchas like this and its easier to fix them as you go rather than having to rewrite your systems.

-
Also, the XBOX has 1 GC generation VS the PC's 3. – Justin Self Apr 4 '12 at 14:25
Just to chip in my own thoughts here. Repeated calls to RemoveAt can be pretty expensive (see stackoverflow.com/questions/6052003/…) so my guess would be to look at that although without seeing the rest of the source its hard to say. One option might be just to mark the tiles as Deleted rather than actually removing them for the Array/List which I assume ClassicThunder is referring to. – Nicky Waites Apr 4 '12 at 14:56
Actually, the Xbox's Garbage Collector kicks in for every 1mb of garbage allocated. – electroflame May 4 '12 at 17:52
@electroflame Thanks I corrected the amount :) – ClassicThunder May 4 '12 at 21:49
@ClassicThunder No problem. If it was 2mb, my life would be a whole lot easier :) – electroflame May 5 '12 at 19:21