Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Feedback Proper data structure for ECS flowfield?

Discussion in 'Entity Component System' started by tonsillectomy, Feb 21, 2020.

  1. tonsillectomy

    tonsillectomy

    Joined:
    Jun 2, 2015
    Posts:
    18
    Hi there,
    I have been fiddling around with different approaches to implement 2D flow fields with ECS. I ended up choosing the following approach and would love to have some feedback about it, before I begin to take the project further.

    - The flow field is made of gridCells, each represented by an entity with a single float2 component indicating the flow direction. The reason for using entities as girdCells is to enable using tags when iterating through them.
    - The entities have a SharedComponentData, which has a NativeHashMap<int2, Entity> that returns the corresponding entity with given int2 grid position.
    - A separate system iterates through the entities and updates their flowDirections relative to the neighbouring gridCells. The neighbouring cells are retrieved from the NativeHashMap in SharedComponetData.

    And now some questions:
    - Does this approach make any sense?
    - Would BlobAssetReference give any advantage compared to the SharedComponentData?
    - Are there any pitfalls I haven't realized yet (mostly regarding expanding the scale and dimensionality of the system)?
    - Would it be better to just use NativeHashMap<int2, float2> instead of <int2, entity>?
    - The NativeHashMap is allocated as persistent, but it return the: "A Native Collection has not been disposed, resulting in a memory leak." error. How should I work around this?
    - Eventually I'm planning on implementing Navier-Stokes equation with the flow field. Does this approach scale up well for that?

    Thanks!
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,222
    Unless you have lots of algorithms that need to iterate over cells with tags, use a bitmask for this instead.
     
    tonsillectomy likes this.
  3. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,697
    Really curious about the BlobAssetReference vs SharedComponentData approach.
     
    tonsillectomy and TheGabelle like this.
  4. TheGabelle

    TheGabelle

    Joined:
    Aug 23, 2013
    Posts:
    242
    Do you plan on updating the flow field at runtime? If so Blob structures may not be suitable because AFAIK they aren't to be changed. Would be happy to be told I'm in the wrong here.
     
  5. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,697
    I was thinking the graph as a blob reference on each entity with the entity contain a vector component for the flow Dir. is there a cost adding a immutable blob ref per entity ?
     
  6. TheGabelle

    TheGabelle

    Joined:
    Aug 23, 2013
    Posts:
    242
    It would increase the size of each individual entity, reducing the number of entities per chunk. The flowmap system itself could keep a reference, or use a single entity with a component containing the blob asset reference and query for that ahead of the flowmap followers.
     
  7. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,697
    I was under the impression it just a pointer to the blob, is this not the case ? I’m brand new to blobs so really any info here is helpful before I try use them
     
  8. TheGabelle

    TheGabelle

    Joined:
    Aug 23, 2013
    Posts:
    242
    A pointer is 4 bytes (32 bit OS) or 8 bytes (64 bit OS). Keeping a reference on each entity will increase it's memory footprint by 4 or 8 bytes, respectively. Since an Archetype Chunk is 16 KB, the additional reference bytes will reduce the number of Entities that can fit in a chunk.

    To put it simply: a memory block is loaded into a cpu cache each time anything in that memory space is referenced. Archetype Chunks fit within these blocks. Getting data from the cache is much faster than getting data from memory. One way ECS speeds up things comes from reducing the number of memory block fetches. Of course, Jobs make multithreading super easy and the Burst compiler helps with better cpu instructions which also boosts performance.