Create a new Class without garbage collection

I’m testing my ability by trying to make a minecraft clone, and so far I have had a lot of trouble with Garbage collection. I have handled most of the issues causing GC but this one function has had me stumped.

void GenerateDefaultBlocks() //fills 8 by 8 by 8 chunk
    {
        for (int z = 0; z < 8; z++)
        {
            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < 8; x++)
                {
                    blocks.Add(new Block(x + xPos, y + yPos, z + zPos, DefaultBlock));
                }
            }
        }
    }

This adds 512 blocks to a chunk with their respective positions and block type.
“blocks” is a list of all the chunk’s blocks.

Below is what the block class looks like. The index and length variables are stored so I can take a specific block’s data out of the triangle, vertex, and uv lists in the Chunk script when the block is destroyed. “BlockSO” means block scriptable-object which is how I am storing block types like grass or stone. umin, umax, vmin, and vmax are the block’s texture’s uv coordinates on the master texture of all the blocks.

[System.Serializable]
public class Block
{
    //position
    public int x;
    public int y;
    public int z;

    //indexes
    public int vertIndex;
    public int uvIndex;
    public int triIndex;
    public int triLength;

    //block type
    public BlockSO block;

    //Texture Co-ords
    public float umin;
    public float umax;
    public float vmin;
    public float vmax;

    public Block(int X, int Y, int Z, BlockSO Block)
    {
        x = X;
        y = Y;
        z = Z;
        block = Block;
        umin = Block.umin;
        umax = Block.umax;
        vmin = Block.vmin;
        vmax = Block.vmax;
    }
}

Here is the Profiler reading of the function. It creates ~36 kilobytes per chunk and this adds up easily.

Is there any workaround or fix for my issue? I have heard that making the Block class into a struct might work, but I need specific references to the blocks quite frequently, so making it a value type would be troublesome.

No, that’s not possible and that’s not how you should do it. Even an empty class requires at least 12 bytes of memory. Together with all your fields one instance requires about 60 bytes. 60*512 is already over 30k. furthermore just the internal array in your list requires additional 2k just to store all the references (not considering potential re-allocation of the internal array).

I don’t quite see the point of this class. The position of a block is determined by it’s location in your chunk array / list. There’s no need to store the position for every block. Also most of your other fields are confusing. The required texture coordinates are not per block but per block face. Also which texture coordinates you need are the same for all blocks of the same type.

Having an actual class instance for every block would be total overkill. MC with a chunk range of 8 (16x16 chunks) would mean at the default world height of 256 you would have 16 million blocks loaded at the same time. Just to store those class instances you would already need over 1 GB of memory. That’s why MC splits all the data into seperate concepts. First there’s the pure voxel data, just as it’s stored in the files. Each block has a block type and a 4 bit meta data value, nothing more. Based on that data you can directly create a mesh based on the block types. MC has one class instance per block type. Though MC has blocks with more complex functionality. For those it uses tile entities / block entities which is an actual class instance for a certain block coordinate which holds all the extra information / functionality.

How you implement those things for yourself is up to you. The implementation that Marcus Persson came up with is pretty ingenious and well thought out. Having seperate class instances is also very inefficient for the CPU cache. Tightly packed data in an array is much better. Another reason why MC uses chunks and processes the world in chunks. Fot the easy of passing information around in a grouped fashion you could use structs. However you shouldn’t store that information in lists or arrays.