-
Type: Bug
-
Version: ModelEngine
R4.2.0, Leaf1.21.4-525 -
Evidence: 3 entity UUIDs in 12 instance worlds each produced 18,777 of 22,907 repair lines on one server
-
Location:
ModelUpdaters.registerModeledEntity,ModelUpdaters.uuidLookup
Checked against
ModelEngine-R4.2.0.jar. The link between the collision and these missing models is my reading of the code, not something I reproduced.
Logs
[00:00:05] [Server thread/WARN]: [MythicUtils] [ModelGuard] soldierfallen bed6779e-8ec7-42fb-b2ce-0affea520436 @ ca72d386-5d0c-4000-8000-000000000001_Labyrinthe 2,-38,200: model(s) [fallensoldier] still missing after 2 replay(s), giving up on this entity
[00:01:05] [Server thread/INFO]: [MythicUtils] [ModelGuard] soldierfallen bed6779e-8ec7-42fb-b2ce-0affea520436 @ ca72d386-5d0c-4000-8000-000000000004_Labyrinthe 2,-38,200: model(s) [fallensoldier] missing -> replayed model{} [...]
Context
Dungeon instances are copies of one world. If an entity is saved in the source world, every copy contains an entity with the same UUID, which Minecraft allows per world.
We will remove these entities from our source world. ModelEngine should still handle this case safely, because world copying is a common way to build instances.
Problem
The model registry is global and keyed by UUID. registerModeledEntity calls uuidLookup.put with the entity's UUID, and getModeledEntity(UUID) reads from the same map.
A second copy replaces the first in that map. The method returns the previous model, but nothing in this class stops or reports the replacement. idLookup still holds both by entity ID.
Lookups by UUID can return the wrong entity's model. A call for the first world's entity can get the model bound to another world, and removing one copy can leave the other without a registered model.
Our repair cannot fix this. Replaying model{} on these entities failed repeatedly: 5,060 repairs ended with still missing after 2 replay(s) on this server.
Solution
-
Log a warning when
registerModeledEntityreplaces a live model bound to a different entity. -
Check that the stored model belongs to the same entity before replacing it.
-
Consider keying the registry by entity ID or by world and UUID.