Is it bad practice to have components reference an entity?

I have been trying to learn ECS lately, and like many others am having issues wrapping my head around certain concepts. I was interested in trying to make a card game with ECS, and found this tutorial series which does exactly that : https://www.gamevanilla.school/courses/create-your-own-single-player-ccg-with-unity/lectures

I followed through their series, then quickly started expanding on their example project and getting comfortable writing components and systems. Great.
However, as I build on top of it, I’m having a lot of trouble getting certain concepts to scale. For instance, I have a sword card that has its own slots that can be played on, basically adding damage to the sword when you add other cards to it. Then, when I play the sword on a monster, I want the sword to “reset” to what its damage was previously. None of that is too tricky, except that there are a bunch of different modifiers that other cards can give to a card - extra damage, damage multiplier, different types of damage, etc. So I want to be able to basically make a copy of the sword entity, and “reset” it when the sword is played. The issue is that the slots that the sword owns are referencing the base entity, so I would have to have a system specifically for copying all those components, and there will end up being a ton of if(EntityManager.HasComponent), which feels bad.

Is it bad practice to have components that reference entities? It feels anti-ecs (or rather, it feels like i’m thinking in OOP every time I have a reference in a component) but I haven’t been able to figure out a way to avoid it.

It’s not bad practice. It is a necessity. Think of a transform system. How would an entity know its parent if it didn’t have a parent component that referenced its parent? ComponentDataFromEntity exists exactly for this purpose and EntityCommandBuffers will even patch references to be real for to-be-created entities.

Interesting, that was my thought from experience, but I was wondering if I had the right idea.
So what about cases where I want to essentially re-create an old version of an entity? How do I maintain any references to it? Or if I can’t do that, what’s a good way to “reset” an entity?

Also, what is ComponentDataFromEntity actually for? The documentation says “A NativeContainer that provides access to all instances of components of type T”. I thought an entity could only have one component of a given type?

Also, I feel like the more I reference entities in my components (especially when I create event-like components), there starts to be a lot of implicit dependencies and I end up with a lot of HasComponent checks. Should I be worried about this?

ComponentDataFromEntity is how you access components on entities when you’re inside a job. You can’t use the EntityManager inside a job, so you call GetComponentDataFromEntity inside the system and pass the CDFE into the job:

JobHandle OnUpdate(JobHandle inputDeps)
{
    var someComponentFromEntity = GetComponentDataFromEntity<SomeComponent>();
    inputDeps = Entities.ForEach((in EntityHolder holder)=>
    {
        var someComponent = someComponentFromEntity[holder.targetEntity];
    }).Schedule(inputDeps);

    return inputDeps;
}

My gut feeling is if you’re using HasComponent you’re doing something wrong, but it’s impossible to know without context. Generally your systems should know what components exist or don’t on the things they’re processing, because they query for them. You can tag or untag your entities as needed, and If you need to perform some logic based on the existence (or lack of) a component, your system should be querying for that case and doing whatever it needs to do.

Referenced child entity and vice versa, should not care in most cases, what state they are.
You should be able reading, or writing to them in safe manner, without needing to check what parent/ child component has.

That state in most cases should be dealt by designated systems and their jobs.

So for example parent sets transform position to child. It is assumed child has such component. System to move entities, simply look for transform component.

Player reads lives of referenced unit entity and calculate score.
You got separate system job, to look entities with lives and separate system job, to look entities like players or score. They don’t care about mutual correlation, other than checking, if referenced entity is valid.

Only thing I can think of, for checking components of reference entity, would be componentTag. But even then, I would probably use bool/int/enum, to check state, rather than hasComponent.