The logic for pulling an entity out of its old entity block has a bug that I believe was the root cause of the multiple Sword entity bug found in Day066.
Towards the end of that session, the solution implemented by Casey was to guard against attempts to re-add entities that already have a reference index or some such thing.
The following statement in ChangeEntityLocationRaw will fail to remove an entity from its old entity block when the Hash location of the entity is the last entry of FirstBlock.
| Block->LowEntityIndex[Index] =
FirstBlock->LowEntityIndex[--FirstBlock->EntityCount];
|
The remainder of ChangeEntityLocationRaw then goes on to successfully add the entity to its new block, resulting in the entity existing in more than one block.
Subsequent calls to BeginSim will encounter the same entity across different blocks and pull in each occurrence into SimRegion had Casey not implemented the guard against re-adding solution.
This situation can compound or "balloon" out to result the same entity being Hashed across many blocks.
I'm not following Casey's implementation verbatim, and in-fact not even in C/C++ so I don't have a C/C++ solution, but the following is what worked for me.
| if (Index === Block.LowEntityIndex.length - 1 && Block === FirstBlock) {
FirstBlock.LowEntityIndex.pop();
} else {
Block.LowEntityIndex[Index] = FirstBlock.LowEntityIndex.pop();
}
|