Search Unity

Question is it possible to reference a ghost entity across the network?

Discussion in 'NetCode for ECS' started by Opeth001, Dec 19, 2021.

  1. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Hello Everyone,

    im trying to build a Gamplay Ability System using Entities and Netode.
    in some cases the player can cast a spell on a ghost by entity reference, it could be a simple AI or an opposing player, but the big problem here is that the entity references are different for every player.
    so is there a way to identify and access a ghost by some unique id across the network?


    [EDIT]
    i just found out about GhostComponent.GhostId.

    Thanks
     
    Last edited: Dec 19, 2021
  2. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    245
    As far as I know you should be able to put [GhostField] on an Ghost Entity and it will sync.
     
  3. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    thanks @Jawsarn,
    but i am not trying to sync components or fields through server and clients,
    I am trying to synchronize the ghost entities.
    EG: Let's say my ability system has an ability that should have a Player / NPC entity as a target. sending the entity will lead to a bad referral for the server and clients as it only exists in the current world.
     
  4. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    I am using GhostComponent.GhostId as a unique reference in the Server/Clients worlds.
     
  5. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    245
    Aha, so you're sending the information over some other means than component serialization as RPC or Command stream I assume? Such case ghostID seems simplest. Good luck with the system, I'm working on a GAS as well^^
     
    Opeth001 likes this.
  6. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Thats interesting!
    I'm still working on something else at the moment, but I'll definitely implement it using DOTS very soon.
    just out of curiosity, have you already a design for it's implementation ?
    how are you going to implement the ability and its Actions, Effects and Clues ?
     
  7. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    245
    Not really. This is my side project and I started out something similar of the DOTSSample, but did some research and are now trying to get a similar interface of how UE uses it, but with DOTS as backbone. Also very bruteforcy at first to get all components in there and then to optimize it more.


    Abilities & Effects are entity prefabs. If you're familiar with UE terms, I have Attributes and Tags as ScriptableObjects. Attributes are generated into code & systems. I have not arrived at Cues yet, so we'll see about that. I guess it's a bit hard to explain in detail of all the systems involved here ^^
     
    Opeth001 likes this.
  8. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    900
    You can stil use an Entity field for that. It is serialized across the network and resolved in each to the corresponding one in each world.
    Underneath we use the ghost id for that. The only problem is that the reference is a weak one. If the client didn't received the ghost yet (and so the ghost id is not present yet) it will result in a Entity.Null (and never resolved later).

    For robust handling of a target for a spell/ability etc, using the ghost id and resolving it your self is probably fine. There are still some corner cases to handle (like that the entity may never spawn on the server for example, if the target entity is despawned before the client receive it) but at that point I suppose the server will send back an update target value for the ability.
     
    Opeth001 likes this.
  9. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Thank you very much!
    how does the netcode systems resolve those entities by their ghostIds, are they stored in some collection ?

    [edit]
    using the entity as a direct weak reference will meet my needs as in most cases the target entities are Ai / Players spawned at the start of the game.

    but i am really interested to see how do you sync an entity reference between server / clients worlds.
     
    Last edited: Dec 22, 2021
  10. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    I just tried an example and ghost entities ids are not synchronized across servers and clients worlds, but the GhostComponent.ghostid is properly synced.
     
  11. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    @timjohansson can you please confirm that
    I tested it and only GhostComponent.ghostIds are synchronized, but Ghost entity indexes aren’t, which makes sense to me.
    this is very interesting if the netcode package really syncs the ghost entity references, because I a not aware of any API in the Entities package that allows creating entities with a specific ID and how would you do if an entity index is already used on the server but required as predicted by the client.

    also, can you please give any reference/comment on how the netcode package resolves ghostIds ? like are you storing them in some collection NativeHashMap<GhostId, Entity> ?

    Thanks
     
  12. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    900
    Ghost entity indexes cannot be synchronised. client and server have a completely different entities set etc. And it is not important either. What matter is being able to map from one to other.

    We are using the GhostId to map in between server and client entity (and viceversa). On the server and client we have a map (see GhostSendSystem and GhostReceiveSystem) that map ghost-id to entities.

    if u write something like
    Code (csharp):
    1.  
    2. public struct MyComponent : IComponentData
    3. {
    4.    [GhostField] public Entity ghostReference;
    5. }
    6.  
    When the Entity ghostReference is serialised, internally this is translated into the corresponding ghost-id. When deserialized, the ghost-id is resolved and the matching entity (client or server world) is retrieved.

    As you may notice there is a caveat (that we are going to resolve in near future): if the ghostReference Entity has not been received yet by the client, for example, at the moment of the the resolution, this will result in a Entity.Null (this is why we say this is a "weak" reference).
    Of course, when a new snapshot is received and the entity is there, then is resolved to a existing instance.
     
  13. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,129
    @CMarastoni I see. Tat's why client side there get Entity.Null and error spamming. Then the whole game not working anymore.