Entities is throwing an index out of range exception, potential bug? (RESOLVED)

Debain 9, MonoDevelop 6.2 Stable, MonoGame 3.6, latest clone of Monogame.Extended.

Forewarning: I am only an intermediate programmer. Just enough to make me dangerous but nowhere near an expert.

I run EntityComponentSystem inside of a game screen class. The game runs fine the first time around. If you quit the game screen and return to the main menu, then try to play again, this exception is thrown when EntityComponentSystem is calling Scan(params Assembly[] assemblies), which calls CreateSystems(List systemTypeInfos, int componentCount) and in turn EntityManager.FillComponentBits(andMask, aspectAttribute.Components). The exception is thrown inside of BitVector (which is the andMask). FillComponentBits is trying to assign a value to the bool indexer BitVector[int index] property but the index is out of range and throws an exception.

EDIT: I set a break point and inspected the variables and the first time the index value of BitVector[int index] was 26. The second time when the exception is thrown it’s 53. EDIT2: It’s pretty clear that the index value is being doubled.

Am I supposed to be resetting or destroying the EntityComponentSystem some how when a game is quit, even if it’s just returning to the main menu? I assume this problem is happening because EntityComponentSystem is trying to do something it’s already done. I’m sure you can imagine this creates a problem for a game intended to be fully featured and finished. This is just my guess though, I suppose I could be wrong. I tried to work around it but I was unsuccessful.

If you need more info on how I am managing the game states/screens, let me know.

Here’s the stack trace: https://pastebin.com/2PCL4Uv0

Thanks in advance!

Are you calling EntityComponentSystem.Scan multiple times?

Not every frame. It’s being called once in the constructor of the game screen when the gameplay is started the first time. Quitting the game to the main menu and selecting play adds a new game screen where EntityComponentSystem gets instantiated again in the game screen constructor. Apparently something isn’t getting deleted off the stack or heap and the same data is being added to the second time around. I’ll be trying to hunt it down.

Well, I think that is the problem. Scan adds to the collections.

Any further help by someone who has encountered this before would be much appreciated.

I am slowly making progress:

BitVector holds the component count in _array.

EntityManager._componentTypes holds a list of the component types.

This is essentially the same amount of items as BitVector._array.

_componentTypes is a dictionary where the values are EntityComponentTypes which have an int Index property. This property is supposed to correlate with the number of items in _componentTypes.

During the first run, there are 27 items in _componentTypes and the Index properties of it’s EntityComponentTypes range from 0-26.

On the second run, _componentTypes.Count still only has 27 items.

The Index properties of EntityComponentTypes were added to which make the values 27-53.

When these values are passed into the BitVector for a calculation it throws System.IndexOutOfRangeException (the foreach loops starts by passing 53.)

Because BitVector._array was set to have indexes of 0-26 (27 items).

Now I just have to figure out why this is happening and how to fix it…hopefully a quick fix is just a matter of clearing some collections before registering components.

The problem happens in this method (a little stack trace for explanation.)
EntityManager.CreateComponentTypesFrom(List componentTypeInfos),
EntityComponentSystem.Scan(params Assembly[] assemblies)

The private static field EntityComponentType._nextIndex is never set back to 0 probably because the EntityComponentSystem in general was never meant to call Scan twice in the same program.

Currently thinking about the best way to solve this.

Problem is solved by simply changing EntityComponentType._nextIndex to a public property NextIndex and setting it to 0 in EntityManager.CreateComponentTypesFrom(List componentTypeInfos). Not sure if that’s a bad idea or not, but it works.