Game Development Stack Exchange is a question and answer site for professional and independent game developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

So I've built myself a system of classes for what I think is an efficient way to describe an entity that would live in my game.

Is this an effective approach or am I creating entities that are too large in size? I want the game to be able to run well even with an inane amount of tiles.

I read the post (Map with 20 million tiles makes game run out of memory, how do I avoid it?) about having one million tiles and memory problems and I'm worried that my tile system I've created using the entity system will not be able to handle such large sized maps as there is so much information to be processed.

To give you an idea about what each component of a Hex Entity holds, the sprite comp maintains the following variables: the texture, position, rotation, height and width; while the hex comp of the hex entity maintains: the position, the coordinates on the board, the orientation, and what hex's are adjacent to it. Should i simplify the date types

share|improve this question

It is hard to say what exactly will suit your situation. Your setup is very memory inefficient, if you want millions of hexes as much data as possible should be implicit, that means you should store hexes in an array where each array entry maps to a specific position.

But do you need millions of hexes? If you have only got a few thousand hexes your current system may be fine.

share|improve this answer

Here's an example of a large number of block entities per frame: (spool to position 1:07)

The way I had 100,000+ blocks per frame, single threaded was to limit the data that defined those blocks, ie:

public struct Block
    public BlockType Type;
    public byte Sun;
    public byte R, G, B;

    public Block(BlockType blockType)
        Sun = 0;
        R = 0; G = 0; B = 0;

The block then, is quite compact, but not defined for extremely low memory here. To do that, I needed to look even further, for example:

public struct LowMemBlock
        private byte store ;

        public BlockType Type
            get { return (BlockType)(store >> (byte)4); }
            set {store = (byte)(((byte)value << (byte)4) | (store & 0x0F)); }


This isnt the full lowmemblock, but just a snippet. It highlights the point of efficiently using the high and low nibbles, to further reduce the size of the block in memory.

One other interesting point to consider, is Garbage Collection. If you are able to sacrifice a potential stutter at specific frames, make use of the gc in .NET to clear up deallocated memory.

Two more techniques that I found to work well are:

1. Sparse matrices:


A sparse matrix is a data structure that works like a two-dimensional array but uses far less memory. It is ideally suited for situations where you need to represent a grid, but most cells in the grid will be empty.

For example, consider a spreadsheet with 1,000,000 rows and 1,000,000 columns. To represent the data for such a spreadsheet using a two-dimensional array, the array would need to store 1,000,000,000,000 elements! When you consider that most spreadsheets use only a tiny fraction of the available cells, this represents a huge waste of memory. A two-dimensional array uses memory for all cells, whether they are used or not.

The sparse matrix is ideal: It allows you to specify a position, and store the data at that position. The positions in the sparse matrix that have no data, are not initially allocated. So, in reality, the matrix is a defined array, but only that doesnt use memory for any cell that has no data. It is much more memory efficient that a usual array. But, I found that it can be slow to traverse when dynamically reallocating, as I was doing with procedural voxel terrain. It might work perfect for you in your game though.

2. Weak references:


Usually, when an object goes out of scope, or is set to null, it is no longer accessible to us, even if the garbage collector will only delete the object much later. A weak reference object will keep a reference to an object that went out of scope or was set to null, until it is actually deleted by the garbage collector. But until that happens, we can get the object back!

So, we are able to make reuse of the memory allocated on that object, and still allow the gc later on to delete it. In a way, we are informing the gc that it is safe to clean up the memory footprint of that object.

And for clarity, a link to explain them a bit better, with a code example:

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.