Search Unity

How to change Archetype Of Entity

Discussion in 'Entity Component System' started by JesOb, Mar 17, 2019.

  1. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    I have some Entity and in one time I want to change it Archetype to specific one.
    I can do that by adding components one by one than removing one by one than check to remove some unknown additional components but this all looks bad and performance heavy because of many entity moves between archetypes.

    What I really want is just be sure to add/remove all components in one go so entity will become of specific archetype. Something like:

    entityManager.MoveEntityToArchetype( entity, myLovelyArchetype );

    How can I do that?
     
    kstothert likes this.
  2. Micz84

    Micz84

    Joined:
    Jul 21, 2012
    Posts:
    451
    What is your use case for such a functionality?
     
  3. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    I have reuse entities for guarantee entity ids locally and across client/server and just add remove components on it.

    So All reusable Entities pre created with empty tag and then moved to Some archetype when created and back when destroyed
     
  4. siggigg

    siggigg

    Joined:
    Apr 11, 2018
    Posts:
    247
    Why not just let the system handle that?
     
  5. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    How can it do this using provided Entity Id?

    it is mostly ok to entirely destroy ad recreate entity if it keeps their id :)

    But how to do that?
     
  6. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    Another part is sync entity across network.

    When I receive new entity state from network today I need to read all necessary components from received data (Archetype), make sure my local entity have same archetype by manually add/remove components on it and slowly move it archetype to destination. and only then set each component on entity from received data.

    with .MoveEntityToArchetype( ) all this boilerplate will gone and entity will move exactly once.
     
  7. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    Currently the closest to your requirement is using the ComponentGroup overload of various EntityManager method. It's not for single entity but that's why it is possible to not move any data. If you can first find some way to separate them (e.g. add component tag) then from that point everything could be fast.
     
  8. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
    OP, can you create simply entities with desired archetype and sync it as suggested? How many entities we talk about.,How. Many components To be removed from initial entity and how many to be added, to match new archetype.

    For me seams, like just having entity pair, with component that has relevant entity reference, with other archetype.
     
  9. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    As I understand ComponentGroup overrides in not about adding many Components onto one entity but about adding one component on to many entities.
    So it is not what i'm looking for :)
     
  10. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    There is method to add many compoents in one go but it work not good too because it throw exception of one of components already on entity
     
  11. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    Creating new entities every time is exactly the thing I with to avoid. Not because overhead but but because boilerplate I need to write to keep many entities in sync across different machines.

    We already have Good entity ids and creating additional layer of collections just to create separate identifiers and then support that thing and make random search to lookup something looks ugly.

    I think I need no more than 1000 entities and I need to delete about 5 components and add about 10.
    This is about performance and about simplicity of such operations, just want to use underlain Entity architecture rather ignore it.

    I need something like create new record in archetype but use existing Id for it and remove old from old archetype.
     
  12. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
    Any particular reason, why you need and add components, instead creating all required components at entity creation? You are loosing this way an opportunity, to utilize effectively burst.
    Seams like over complicating things.
    You can simply use component as tag (s), to filter what you need, if you must.
     
  13. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    Filtering there will not help. there is no things that can be filtered.
    Reasons few posts earlier.

    I short. I dont need to add components I just want to create entity with exact archetype and existing entity ID.
    Is there some method to do so?
     
  14. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
    Ah that makes more sense.

    The thoughts I got, coming to my mind in this right moment, is to create 1000 required (reserved) entities at beginning of the game (as an example) and reuse them. Then you can ensure, you have same set of entities across network clients (same IDs). Just like polling.
     
  15. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    As a side note I don't think Entity is for client server synching purpose? From the source code I see EntityGUID component popping up in various place. I am just guessing it might be intending to serve your use case. (EntityGUID is composed of 2 long)
     
    Antypodish likes this.
  16. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    This is exactly what I did. and there we just make, a loop and can start from first message on topic :)
    I need a way to simple clean entity from many components that was added to in on it lifetime to become clear archetype like it was on creation.
     
  17. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    I think not EntityId nor EntityGUID is not for network sync. it just data that we can use or can ignore.
    My logic is that we already have unique entity ids and create additional layer and make sure that additional layer in sync with primary one on every machine on network is just waste of time to create fix all bugs and support, waste of memory and game performance, waste of code clarity...

    Using prespawned pool of Entities (Manual id manipulation) is great thing.

    on id range 0-19 - Entities of Players
    on id range 20-39 - Entities of PlayerMobs

    this ids lower than 255 so I need to send only one byte over network for it.
    They always in step 20 from each other so Having Entity of Player i can just add 20 and get entity of it Mob and fast chech that player have no mob for time.

    Adding those ids into Entity names is great helper for debugging because it very easy to to find mob of Player is it exists...
    And they all the same on all clients.

    So many Pros and for now just one Con: We have no Api to quick move entity to exact archetype.
     
  18. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
    You could have reliable syncing, storing general information in some form of array (NativeArray, BufferArray, hash, etc), instead of entities.
    With entities, you need deal also with their version at some point.
     
  19. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    This is exactly what I call waste of everything, is not performance by default this is slowness by default and messy code by default.

    About Version you not right it always will be 1 so this is legitimate code
    Code (CSharp):
    1. var entity = new Entity{ Index = netData.Index, Version = 1 };
    just because Entity is stable reference and while I not destroy it, Index and version stay unchanged.
     
  20. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
    Not really. Since you use specifically same data set and as you said, you don't need filtering, accessing NativeArray is likely much faster than entities.
    Adding components outside archetype, is where things can get messy really.
    But since you doing it once, is not that important I suppose?

    What I meant regarding version, as indeed I assumed your version will be one, that you need set that value, to get full entity reference, every time you access it. However, here is small trap you may fall into, if not being careful.

    Imagine you, or someone add part of the ECS code in the future, just before your polling entities are created. And this code creates and destroyed some entities. Then your "spare" entity, will have increased version. Therefore, it won't be 1 anymore.

    You would have to absolutely guarantee, that no one ever add new system, which manipulates entities, before you generate n required entities? Is hard to remember such quirks year later for example :)


    I asked while ago, if entity can be accessed without version, as this would suite me as well. But apparently there is not an option at current state. Unless something has changed.
     
  21. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    You Right. If I need only some unchangeable info NativeArray will be faster and may be better for data manipulation in some cases. But I need exactly entities because there are planty of systems that process it.
    And processing custom NativeArrays from systems is not convenient and bad for future support.

    I just hide this step into one static method used in networking so no one depends on logic. Method take Byte from network end return Correct Entity.

    I have absolute guarantee that no one can create a single entity before I allow.
    This can be done by manually creating world, add EntityManger and spawn first set of entities way before any other systems will be added to world.

    You can access Entity without version actually if you know what you doing.
    Entity manager store array of entities where Index of array is Entity.Index and value of array actually store Version = Entity.Version and additional info. So you can recreate correct entity having only index by asking version from EntityManager. This all just unsafe in normal situation.
     
    Antypodish likes this.
  22. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Honestly it seems like a much better solution to have a mapping between Entity <> NetworkId
     
    e199 likes this.
  23. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    NetworkID is long, Entity too
    so you can just use Entity as NetworkID if networking system allow manual creation of NetworkIds.

    Nevertheless I dont use Network ID and entire high level networking layer of Unity because it bad.
    My network Id always 1 byte for anything in game. And map itself is bad idea as I wrote before.
     
  24. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    I did not mean using unitys higher level networking, I just ment some type of network id. Making sure that the entity index/version always lines up on all computers is akin to trying to put everything in the same memory slot. You can have a custom network id that is 1 byte also
     
  25. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    OK I understand :)

    Im using Entity as network id but only 1 byte.
    You can read details in previous messages :)
     
  26. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Yeah, exactly... but it's causing you issues isn't it? Why not just do a separate mapping?
     
  27. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    It is not an issue actually but ECS API looks incomplete.
    I have mapping before because I thought that manual entity Ids is long run task.
    When every thing was bad and buggy I just remove all these mapping code replace with manual ids code base become 2 times shorter and now looks far more clear, debugging is pleasure because I see identical entities on both sides.

    The only thing is that I need to renew entity by id in a way that dont looks like ECS way.
    So adding ability to move entity to Exact Archetype is good solution for this.