Help with storing voxel data for destruction game

I’m wondering what the most performant method is for storing voxel data. I’ve tried storing the data in a multidimensional array where each dimension is the XYZ position of the voxel, example: data[x][y][z], however even empty arrays generate multiple gigabytes of RAM usage when millions of voxels are present. I had no idea an empty array would use that much memory and am quite stumped on how to store all this data.

2 Likes

Simple just don’t store the empty voxel data… Or… Maybe I didn’t understand what your saying? Please clarify!

1 Like

I’m not storing empty voxels, only voxel that are there. For example if I made a 800x800x800 cube that is 512 million voxels. Not only does this take forever to loop through in a table, but without even putting a part down to render the voxels, just the empty arrays I create max out my memory

1 Like

Hmm well maybe you can arrange the voxels? Using greedy meshing?

1 Like

I thought about using greedy meshing, but I’m unsure how to implement destruction physics. If we go back to the 800x800x800 cube, greedy messing would make it a singular part. If I were to then want to break a small portion of that cube how would I get the positions of the voxels that are hit?

I suppose you also get the size of the voxels?

In the case of greedy meshing the only values I would have for the massive cube are the position and size of that cube

Yes exactly. Save for bigger cubes not for smaller.

So using greedy meshing I would get this massive singular cube:

However say I wanted to take a chunk out of it:

How would I achieve this?

This video shows how to greedy mesh.

What I am asking is how to UN-greedy mesh. Even at the end of the video he says he doesn’t know how to effectively remove blocks from the mesh which is what I am trying to figure out

ohhh… uhhhhh… that is tricky… maybe just use rays? or regions? see the block color etc? and repeat for 512 million voxels lol?

Unfortunately looping through 500 million times every time I need a block removed isn’t going to be
viable :joy:

This game achieves pretty much what I’m going for with no lag. I’m super curious to how they managed it

yea I know XD.
IF you already have them greedy meshed why not just save part and their sizes like this:

local part = -- our part

local propertytab = {
[part.Name] = {Size = {part.Size.X,y,z...},Position {part.Position.X,y,z...},... etc}
}

After playing this game for a few minutes I believe they split walls and such into smaller segments and then just run the greedy mesh algorithm over again when a projectile hits one of the wall segments.

They make sure to not have any part be too big other wise the algorithm would take too long to complete

A: You have lua parallel
B: You can create a system of queries where you control how many blocks are greedy meshed every tick
C: From the tutorial it seems like you can do this in a faster way despite that your system is different.

Because you can add now merged meshes into a node (it’s important, because when you are going to get to removing them from the pool of objects, arrays would be unsustainable in performance (You will have to move thousands if not tens of thousands of elements in an array), nodes are simple solution to this, though will be bit slower in iterating).

Parallel Luau | Documentation - Roblox Creator Hub This will be super useful thanks

What do you mean by merging meshes into a node?

I said adding merged meshes data into a node class object

Like here:

local LastNode = addNode(nil)

function addNode(LastNode,Value)
     local Node = {
      Next = nil;
      Last = nil;
      Value = Value;
     }
     if (not LastNode)
        LastNode = Node
        return Node
     end
     LastNode.Next = Node
     LastNode = Node
     LastNode.Previous = Node //table.insert like behaviour
     return LastNode
end

local Mesh = GreedyMeshingFunc(...)// { Node: NodeClassObject Mesh: Mesh   }
local Node = addNode();

Mesh.Node = Node

Isn’t this just making a custom array?

I would say it’s “Custom array”. But not really. Look up so called “linked lists”.

Your address mentioned in the tutorial on linked lists in this case would be the reference of a table (object) itself.