Where to store large array data on entities

Where would i store runtime generated lists of float3s and float2s that represent vertices/uvs on an entity?

I was thinking to use buffer element data components and name them Vertex and UV but there will be thousands of elements resulting in really large buffers, not sure if thats considered problematic for the ECS architecture or not… are they okay being really large?

I need to be able to edit these lists in runtime so that rules out blob assets entirely.

The only other option i can think of is have a system keep a map of entities to native collections like this as a private field:

NativeHashMap<Entity,(NativeList<float3>,NativeList<float2>)>

I do intend to use jobs to modify the contents of these lists for mesh deformation, so I can’t just put them in a Mesh object since it is managed.

What is the correct design approach here?

Can those arrays be reused by multiple entities, or are they unique to each entity?

  • If they can be reused for all entities in a chunk, you should store them in chunk components.
  • If they can be reused for all entities in the world, you should store them in DynamicBuffers of a SingletonEntity.

Storing arrays in a map of native collections is not different from storing them in DynamicBuffers.

How so? A field on a system is different to a component an entity so it feels like its very different.

As for your question, the data is unique for each entity so they won’t be used by other entities.

What a DynamicBuffer and a NativeList actually store is a pointer to an array. The array data is stored in different memory from the entity (if you set the InternalBufferCapacity of the DynamicBuffer to 0). So no matter where you store those pointers, the CPU still needs to jump to the address of the array to read it.

In this case, I think it’s best to store your data in DynamicBuffers of entities. Note: you should set the InternalBufferCapacity of those DynamicBuffers to 0, so the buffers will be stored outside of your entity chunks.

Okay i will use dynamic buffers, was unsure if dynamic buffers would be fine to use in the case i had thousands of vertices.

Just set the InternalBufferCapacity of those DynamicBuffers to 0, and you will be fine.

Shouldn’t i set it higher than 0 if i plan to store thousands of vertices?

If you supply a specific size for the buffer then it will preallocate all of that space per entity. Having a very large buffer size like this will reduce the effectiveness of the memory locality when iterating through entities, hence the reason they are suggesting you set the size to 0 so that the data is stored outside of the entity chunk entirely. This will reduce the effectiveness of accessing that data in general but with very large sets it’s mostly a wash anyway. I believe Unity itself might also force the data to store outside of the chunk if the size is large enough but don’t quote me on that.

Do you have thousands of vertexes/uvs per entity but a few entities, or just a few vertexes/uvs per entity but have thousands of entities?

If the former, you should set the capacity to 0, because the buffers are stored outside the chunk anyway. If the latter, you should set the capacity to a number that covers most cases to avoid the cpu from reading the buffers through pointers as much as possible.

InternalBufferCapacity refers to the max capacity a chunk can store the buffer inside it, not the capacity of the buffer itself.

[InternalBufferCapacity(0)] means the chunk cannot store this buffer inside it.

[InternalBufferCapacity(4)] means the chunk can store up to 4 elements. If you exceed this number, that buffer will be moved outside of the chunk, but the empty space won’t ever be reclaimed after the move. So you’ll have a fragmented chunk.