Can someone help me to find a better approach for task?

Hi! There is one task which I have already resolved, but my approach has some architecture and performance issues.
This topic will not have almost any code because it requires time for understanding. I don’t want to waste your time and tried to explain it without unnecessary details.

So the task is next:

  1. there is a grid which contains some amount of cells (quad mesh renderer)
  2. On the grid exists some another objects (bots, food, poison (all of them also quad mesh renderers with another colours and scale))
  3. Every turn all bots want to perform some action (move, eat, transform poison in a food), the food and the poison can be spawned
  4. In a moment 1 cell can contain only 1 object

My way to solve this was:

  1. All entities in this solution has PositionComponent which contained grid position (x,y)
  2. Cells also has CellContent component which has enum of possible contents
  3. OnCreate BehaviourSystem cache all cells in a NativeHashMap<int, int> to access CellComponent on cells in behaviour code (int - transformed cellPosition to avoid valueType key int2(), key is Entity)
  4. Every turn I process bots logic in a BehaviourSystem in the next way : calculate intentions for each bot in parallel and write them to List, then tried to apply them (making big amount of structural changes) in main thread. Intentions which can’t be applied goes for recalculation. This repeated until all intentions were applied.
  5. Spawn food and poison by PoisonSystem and FoodSystem

What problems I have faced at the moment (and resolved them in a some way but not sure about my solutions):

  1. How to make relations between cell and world’s objects? In my solution it was horrible. Some objects (cells, food, poison) has IRelatedEntityBufferComponent. When food was spawned into cell - cell adds this entity to buffer, and food also add cell’s entity in it’s buffer. That needed in case food will be removed - it needs to change CellComponent’s value, so should be the way to access exact this cell

  2. This is an Intention struct example

struct Intention
{
    public Entity TargetCell;
    public Entity CurrentCell;
    public Entity Bot;
    public IntentionType Intention;
    public CellContent TargetCellContent;
}

When applying an Intention I make lots of GetComponent and SetComponent to all of this Entities.
I tried to use command buffer, but it is quite senseless, because after applying possible intentions all changes should be calculated immediately in case of recalculation.
I understand that the best way - change data directly, but can’t understand how can i do that.

  1. In case of transformation poison into food I need to remove poison entity from cell (remove entity + some changes in cell) then spawn new entity into this cell (instantiate entity + set data to it + changes in cell).

  2. The way I spawned food and poison seems weird.
    I made prefabs for food, cell, etc… Then I spawned them and convert to Entity. After this I saved this entity and use it for spawning “clones” and set to clones custom data.

In my opinion Food system was responsive for spawning food. But when I applying a “Transform food intention” there is few problems. If I’ll try to apply intentions in parallel code using EntityCommanBuffer.Concurrent - there is no possibility to getReference to FoodSystem from this code (can’t use reference types in ForEach lambda). We can try to overcome this using FoodSystem’s static method, but it is impossible in my implementation. Why? My “reference entity” is a static not readonly field (i can’t make it readonly because addressables has only asynchronous loading of resource and even in case i started load it in construcor - i can’t set readonly fields in callback)

So in my opinion I have only 2 ways: use synchronous code or make code duplication

If you don’t mind - I’ll stop at this point.
There is too much abstract information wrote from not native english speaker, it is already hard to understand.
Hope for some kind of discussion and advices, your solutions and knowledge sharing.

I expect to find solution which can avoid lots of GetComponent/SetComponent and write most data in direct way… But this require different approach.

Can’t make any comments about your data structure or your Get/SetComponent without knowing the specifics of the problems you are having, but for the rood prefab entity, just copy the entity into a local variable before the Entities.ForEach and then use the local variable inside the Entities.ForEach.