Open yyy257 opened 4 months ago
Good spot! I think the best solution here would be to only store struct entity*
pointers in the dict, instead of the whole object.
I also think that's a good idea, so I implemented it in a commit. It might not be the best implementation, but it seems to work - I hope it will be useful. This could even save memory, as dictionaries may use a temp array relative to the dictionary's size while resizing.
To reproduce the bug, I dug a lot of blocks without picking them up until the player data became corrupted. I could also reliably trigger it with the code in my fork that drops all items upon death.
Client-side entitites are tracked with an M*LIB dictionary, and inserting a new entity can shuffle other entities around in memory, including the local player:
Therefore, insertion of a new entity can randomly make
gstate.local_player
point to garbage data, usually getting the player stuck at X=0, Y=0 and Z=0, sometimes ending in a segmentation fault.To fix it, I added a variable separate from the entity dictionary which tracks the local player ID, allowing updating
gstate.local_player
after spawning a new entity. As long as the game is singleplayer, the local player ID is always 0, but the variable may be useful when multiplayer is added.