EntityCommandBuffer and assigning deferred entities to DynamicBuffers

Recently I transferred my project from Entities 0.51 to 1.0.
I’m trying to create a cellular automata kind of game like Powder Toy. The game’s world is separated in Chunks of pixels like this (I apologize for the horrible magenta colour, it’s for debugging reasons):
8485349--1128509--upload_2022-10-3_17-19-32.png

So, there is a WorldGenerationSystem that I am using to generate the world’s terrain by filling Chunks’ DynamicBuffers with pixels (which are entities). Right now I’m trying to use an IJobEntity struct for this system which I haven’t been using previously – it worked just fine like that until 1.0, then I got 8 FPS even thought there was nothing being processed at all.

At this stage of development, the system’s logic runs only once in the OnStartRunning method for testing purposes.
Here’s the simplified version of the code:

        protected override void OnStartRunning()
        {
            base.OnStartRunning();

            EntityCommandBuffer commandBuffer = GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>().CreateCommandBuffer(World.Unmanaged);
            new GenerateRegionJob()
            {
                pixelBuffers = GetBufferLookup<PixelBufferElement>(),
                commandBuffer = commandBuffer
            }.Schedule(regionQuery, Dependency).Complete();
            endSimulationEntityCommandBufferSystem.AddJobHandleForProducer(Dependency);
        }

I followed the Turbo Makes Games tutorial on this.

GenerateRegionJob’s purpose is to create pixels using the passed commandBuffer.
I guess that would be working fine, if I haven’t been assigning the newly created pixels to the pixelBuffers of the Chunks I create the pixels for, like in this GenerateRegionJob piece of code:

            private void CreatePixel(Entity chunk, int index)
            {
                Entity newPixel = commandBuffer.CreateEntity(pixelArchetype);
                commandBuffer.SetComponent(newPixel, /*some creation data*/);

                pixelBuffers[chunk][index] = newPixel;
            }

So, the problem is, when I try to access the entities I created inside of the job by indexing DynamicBuffers, Unity tells me that they’re still deferred. I assume that’s because those buffers store a copy of the deferred pixel entities (with negative entity indexes) and that doesn’t change when the playback is called.

Storing tose pixels in DynamicBuffers (or any ordered containers) is obviously vital for my game and I cannot treat them individually.

Could anyone please provide me with any suggestions on finding a workaround for that?


Deferred entities should be processed through ECB only. In this case you just assign them directly, as result ECB Playback Fixup know nothing about that and can’t patch deferred entity to real one.

So, my assumption was correct then. And there’s no way to assign the entities created via ECB to some other entity’s field or store some kind of reference to them for later use?
It kinda looks like it kills my whole project’s “one-to-many” hierarchy.

Nope, that’s incorrect. As I said - if deferred entity assigned through same ECB they will be patched. Example from EntityCommandBufferTests after playback all deferred entities will be real one.
8485382--1128518--upload_2022-10-3_13-55-6.png

8485382--1128518--upload_2022-10-3_13-55-6.png

1 Like

Alright, I played around with ECB a little. It looks simple to work with setting data of singular components, but when it comes to interaction with DynamicBuffers it seems extremely inconvenient. I also can’t find any clear documentation about it.
For example, does SetBuffer method clear out the entirety of the previously existing buffer? If so, then instead of rewriting a couple of elements, I have to rebuild the whole thing in order for it to work with ECB.
May be a method like void SetBufferElement<T>(Entity entity, int index, T element) where T : IBufferElementData for EntityCommandBuffer would be a good feature suggestion or is my use case too specific? There’s an AppendToBuffer method already, why can’t we have a Set- one?

Crashed the editor couple of times, going to put this project away for a while until I come up with a solution.
Thanks for all the help.

I suggest you to look at the Entities package code, it has plenty of useful information apart from docs, one of them - Tests which cover many different stuff :slight_smile:

1 Like