question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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

See original GitHub issue

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!

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
Dorakucommented, Jan 31, 2022

I should create a new version soon, I just want to do some documentation update before to close a couple more issues (no promise but hopefully tonight or tomorrow). In the meantime you could use the latest CI version from the github registry https://github.com/Doraku/DefaultEcs/packages/26448 if you prefer it instead of directly including the project 😃

1reaction
KaiHellicommented, Jan 27, 2022

Perfect, that would be great. I wrote up a minimal example, so you are able to reproduce the issue.

World world = new World();

Entity entity1 = world.CreateEntity();
Entity entity2 = world.CreateEntity();
Entity entity3 = world.CreateEntity();

entity3.Set("Something else");
entity2.Set("Hi there!");
entity1.SetSameAs<string>(entity2);

Debug.Print(entity1 + ": " + entity1.Get<string>());
Debug.Print(entity2 + ": " + entity2.Get<string>());
Debug.Print(entity3 + ": " + entity3.Get<string>());

Debug.Print("--------");
world.Optimize();

Debug.Print(entity1 + ": " + entity1.Get<string>());
Debug.Print(entity2 + ": " + entity2.Get<string>());
Debug.Print(entity3 + ": " + entity3.Get<string>());

Which produces the output:

Entity 1:1.0: Hi there!
Entity 1:2.0: Hi there!
Entity 1:3.0: Something else
--------
Entity 1:1.0: Something else
Entity 1:2.0: Something else
Entity 1:3.0: Hi there!
Read more comments on GitHub >

github_iconTop Results From Across the Web

Sorting vs if else if in javascript which one to choose?
I have a scenario in which I need to display the data in an increasing order of the index number. ... Should I...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found