Skip to content

ComponentPool ISortable.Sort - Wrong if- / else-if conditions #156

Closed
@KaiHelli

Description

@KaiHelli

Hi Doraku,

I noticed a problem in our game where entities with components assigned with SetSameAs<T>() suddenly took the wrong component after running world.Optimize().

After some debugging, I think I found the cause of this. In the ComponentPool class there is a function ISortable.Sort which contains the following code in lines 334 - 353:

if (_links[_sortedIndex].ReferenceCount > 1 || tempLink.ReferenceCount > 1)
 {
     for (int i = 0; i < _mapping.Length; ++i)
     {
         if (_mapping[i] == minEntityId) // <--- Wrong condition.
         {
             _mapping[i] = _sortedIndex;
         }
         else if (_mapping[i] == tempLink.EntityId) // <--- Wrong condition.
         {
             _mapping[i] = minIndex;
         }
     }
 }
 else
 {
     _mapping[minEntityId] = _sortedIndex;
     _mapping[tempLink.EntityId] = minIndex;
 }

The else branch is correct, so sorting components without additional references is handled correctly. However, if there are multiple references, you are iterating over the entire mapping table. There you want to update the outdated references into the component array. The if and else-if clause for this is wrong. I think the corrected code should read:

if (_links[_sortedIndex].ReferenceCount > 1 || tempLink.ReferenceCount > 1)
 {
     for (int i = 0; i < _mapping.Length; ++i)
     {
         if (_mapping[i] == minIndex) // <--- The mapping table stores the index into the component array and not the entity id.
         {
             _mapping[i] = _sortedIndex;
         }
         else if (_mapping[i] == _sortedIndex) // <--- Same issue here.
         {
             _mapping[i] = minIndex;
         }
     }
 }
 else
 {
     _mapping[minEntityId] = _sortedIndex;
     _mapping[tempLink.EntityId] = minIndex;
 }

I hope you can have a look at it. Thanks a lot for your ECS system, we really enjoy working with it. Keep up the good work!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions