Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Arrays - Using them to store game level

Tags:

c#

I'm making a 2D tile based game. I use a 2D jagged array to store an integer, and the renderer then draws a certain image depending on what that integer is. I have this part of my code working, however I've come to a point where I'm not sure how to proceed next.

As the player goes on through the game, I need to be able to store information about every cell in the 2D array, such as the light level, or the number of times the user has clicked that cell, or the rotation value of the image in that cell, or the alpha level for that image, etc etc.

The only way I can think of doing this is to create a 2D array like I have done previously, for each piece of information I'm using. So for example:

AlphaLevel[][]
NumberOfTimesClicked[][]

And then if I needed (for example) to check the number of times the user has clicked the cell 5,5 I can do NumberOfTimesClicked[5][5] or if I needed to set the rotation I could do SetRotation[5][5] = 90.

The thing I'm not sure about is how efficient this is, having an array for each piece of information doesn't seem that memory efficient.

Is the idea I have a good solution, or is there a better way I haven't thought about?

Any advice would be great! Thanks

like image 855
user9993 Avatar asked Aug 19 '13 17:08

user9993


2 Answers

Make a Tile object that has the information, like AlphaLevel and NumberOfTimesClicked, and make a jagged array of those. Then, you only need one jagged array to hold all of your information, and it's organized more nicely, since you can easily find all the properties a Tile has.

If you're interested in memory optimization, NPSF3000 is correct in saying structs will be marginally better. Make sure you're familiar with how value and reference types differ before using them.

Storing data in a smaller format is always going to be bigger than not storing data at all. In addition to working to compress your current data as much as possible, look at ways of storing old data you won't need to disk, or discarding data you can generate procedurally later.

One last note: are you sure you need to compress it? When I worked on 2D tile systems in the past, I found that I was actually storing some extra data so I could improve speed, because I wasn't actually using that much memory. Run some numbers to make sure you're actually using enough memory for optimizations to be worth it.

like image 190
Mike Precup Avatar answered Oct 02 '22 14:10

Mike Precup


The thing I'm not sure about is how efficient this is, having an array for each piece of information doesn't seem that memory efficient.

Short Answer: You could use Structs as an alternative - it'd get rid of the additional arrays by simply 'storing everything together'.


Long Answer:

An array's representation is something like the following: Header:Data where the header is a 4 byte Int32.

Currently your storage might look something like this:

IIII:B:B:B  //Byte array (e.g. alpha level)
IIII:SS:SS:SS  //Short array (e.g. num times clicked)
IIII:B:B:B  //Byte array

Where I, B and S represent a byte of an Int, Byte and Short respectively. With Struct's you can store it all together - like so:

IIII:BSSB:BSSB:BSSB

If you use classes instead it looks very different, as a class is stored in an array as a reference to the location of the data:

IIII:RRRR:RRRR:RRRR
BSSB  //These can be stored anywhere in memory
BSSB  //These can be stored anywhere in memory
BSSB  //These can be stored anywhere in memory

So while a struct can save some memory, it's not a lot. Using classes instead will actually cost you memory! However the memory it uses does not have to be contiguous which can help when storing lots of large groups of data (e.g. totalling 1GB+) esp. on 32 bit machines... however that's a discussion for another day.

Of course this purely talks about memory size efficiency, if your workload does computation on a field by field basis, then individual arrays are going to be far more cache friendly - and therefor efficient. Conversely, if you tend to do computation on a tile by tile basis then the reverse is true. Classes are inefficient for raw storage, but if they fit your coding paradigm may make development much easier. Furthermore classes are good when many objects need a reference to the same data - which can even save memory by reducing duplicates!

Hope this helps, as you can see a good understanding of the fundamentals helps a bit. The most important thing however is to value your time, and if/when performance becomes an issue test and benchmark for yourself!

Disclaimer: Written early in morning, may be wrong/have omissions etc.

like image 40
NPSF3000 Avatar answered Oct 02 '22 14:10

NPSF3000