Thank you for the reply! I see and appreciate your approach. However, I’m not sure it’s a good solution in this case. Here’s why:
This is my bad. I used the word “unbounded”, which was dumb. It’s not true. The number of archetypes in my project is bounded. ‘n’ is always a known quantity. I should have said something like, “As a generalized approach to development, this way would need to stay viable across multiple projects, each with a different and potentially large number of archetypes.”
As for maximizing chunk usage - that’s a topic that’s unrelated to the use of Dynamic Buffers…Let me give an example:
Let’s say, in a worst case scenario, I had a different archetype for each type of enemy in my project: “Enemy0” - “Enemy49”. Depending on how many instance of each enemy type I have loaded at once, I might end up with one or two entities in a mostly-empty chunk. If the current game environment had just one enemy of each type, I could end up with 50, mostly empty chunks. But that’s governed by the game design. If each of those enemies actually has a different archetype, then each one would have to live in a different chunk. And here, we’re talking about archetypes without any Dynamic Buffers.
Now throw a differently sized Dynamic Buffer on each archetype (again, the worst case scenario). Nothing changes. Each of the 50 entities would still have to occupy it’s own, mostly-empty chunk. That situation is governed by the game design’s enemy needs, not whether or not they have differently sized Dynamic Buffers.
Continuing with this example: If I committed to the approach you described, I would need to make 50 different IBufferElementData types, each with a different Default Capacity. Each of these IBufferElementDatas would be identical, except for their Type name and Default Capacity attribute.
-
If I wanted to change the data layout of all of those variant Types, I would now need to do it in all 50. If I for whatever reason needed to add a 51st capacity, the workload grows.
-
All of these IBufferElementData variants store the same contextual data. So how would I go about writing a single JobComponentSystem to process all of these different variants at the same time? I don’t think I could use any of the build in convenience Job types, since I believe they currently max out at 6 Component types. I believe I would have to use IJobChunk, and then filter through all of the different IBufferElementData types inside the Job, until I found the right one for each entity. Or maybe I could write 50 different Job types, and filter for the right IBufferElementData on the main thread. Or perhaps I could do some trickery with a common interface. But now, suddenly, I need to add 3 new enemy types. I’ll potentially have to revisit every one of my systems that does this. And that’s just the game’s enemies!
Vs. If you could set the initial capacity of a Dynamic Buffer differently for each archetype:
- You could just use a single IBufferElementData type.
- You would only need to filter for that one type in a JobComponentSystem.
- The amount of ram taken up by DynamicBuffer wouldn’t be oversized for any of your archetypes. It would be as optimized as possible.
Unity seems to handle this fine. You can force two DBs of the same type to have different capacities (and therefore different archetypes) by resizing them differently. So I’m wondering if the only limit here is the absence of a method to set the capacity.