Jump to content

[Solved][1.12] EntityDataManager error -- duplicate id value when calling register


jabelar

Recommended Posts

So I'm porting all my mods to 1.12. In the past, due to limitations of the DataWatcher I had come up with my own custom packets and for every entity had an NBTTagCompound with custom data that I would sync between server and client. The system worked well.

 

Now that there is a EntityDataWatcher I noticed there is a DataSerializer for NBTTagCompounds. So I figured great! now I can just use that instead of custom packets. I know I can also break my tag compound back up into individual elements and serialize those into the EntityDataWatcher but figured since I already had a tag compound I'd see what happens.

 

Well, I get a very strange error when I try to use a spawn egg to spawn my EntityElephant (which extends EntityHerdAnimal). The error is:

. Caused by: java.lang.IllegalArgumentException: Duplicate id value for 13!
    at net.minecraft.network.datasync.EntityDataManager.register(EntityDataManager.java:105) ~[EntityDataManager.class:?]
    at com.blogspot.jabelarminecraft.wildanimals.entities.herdanimals.EntityHerdAnimal.initSyncDataCompound(EntityHerdAnimal.java:86) ~[EntityHerdAnimal.class:?]

 

The whole console output including the error is here: error gist

 

Now the DataWatcher doesn't seem to be documented, so I'm looking at vanilla entities and did the following:

  1. In my custom entity class I created a DataParameter field for my tag compound like so:     protected static final DataParameter<NBTTagCompound> SYNC_COMPOUND = EntityDataManager.<NBTTagCompound>createKey(EntityHerdAnimal.class, DataSerializers.COMPOUND_TAG);
  2. In my custom entity constructor I register the parameter with it's initial value (a tag compound which I have already set fields in) like so: dataManager.register(SYNC_COMPOUND, syncDataCompound);
  3. Anywhere I change a value in the tag compound I also set the data manager like so: dataManager.set(SYNC_COMPOUND, syncDataCompound);
  4. Anywhere I need a value I get the tag compound from the data manager and then the value from the compound, like so: dataManager.get(SYNC_COMPOUND).getFloat("scaleFactor")

 

The whole class is here (feel free to try the download and try the mod as well): The code on GitHub

 

So basically I think the error is very weird. It is obviously related to the register method in my constructor. One thing I noticed is that if I change the class to a parent class (like Entity) the error will change the id it complains about. So it seems to be a problem with the class I'm passing.

 

Now the EntityHerdAnimal class itself is never instantiated (rather I extend it to EntityElephant) but that is consistent with other EntityDataManager entries -- such as for Entity. I'm wondering if it is an issue with the way I'm registering the EntityElephant itself? However, all the other entities in the game (EntityTiger, EntityEagle, etc.) all work although they use my old packet system -- EntityElephant was my first attempt at converting to EntityDataManager.

 

Sorry for the long post, but really I just need someone to see if they see anything wrong in my EntityHerdAnimal class regarding the way I'm using the data manager. Thanks.

Edited by jabelar

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

So looking at theEntityDataManager#register method that throws the error, it very simply gets an integer "id" from the DataParameter that is passed in. That DataParameter is considered the "key" for the entries map. I created the DataParameter using the EntityDataManager#createKey method, so it is very confusing that it is saying that it already exists.

 

I'm actually a bit suspicious though of the createKey code. It uses a "next ID map" that looks wierd to me. First of all it checks to see if the class you're trying to register (which should be <T extends Entity> type) is already in the NEXT_ID_MAP. In my case it should not be, so it uses a while loop to weird crawl through the NEXT_ID_MAP. It checks the superclass of the <T extends Entity> class that was passed in and if that is not in the NEXT_ID_MAP then it checks the next superclass and keeps going until it hits the Entity class itself. At that point it finds the largest ID for that class and adds 1 to that.

 

I think that might be a bug though, since there will be other things in the map that have different parent hierarchies.

 

Imagine you have two different classes that both have Entity as the direct parent, and imagine that 4 parameters are already registered for Entity as ID 0 to 3. Then both of these will want to get an ID of 4. Maybe I'm looking at it wrong, but that's what it seems like the code does. On the other hand, the vanilla entities seem to work okay so I guess I'm just misinterpreting the code path.

 

But my main point is: the ID that is throwing the error is the one created by the DataManager's own createKey method so I don't understand how it could create one that would be a duplicate.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Okay, I figured it out. I was essentially registering twice because my inherited class EntityElephant was also calling the initSyncCompound() method in the constructor in addition to the EntityHerdElephant parent class.

 

All is good in the world now and I can finally get to sleep...

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.