Jump to content

What are some reasons why deserialize nbt might not work correctly?


Turtledove

Recommended Posts

I'm attempting to write and read members of my player capability class, and for things like my stamina, accuracy, fuel variables, when I exit the game and return, it 100% works and saves just fine. However, I also have a 3x3 grid of user bound indices that I've represented as a one dimensional array of integers, which I then created 9 integer data parameters of, registering and setting it like the others.

 

When I go to print these values within my serializenbt method, the correct values are printed, i.e. 2,4,1,0,...

 

However, when I print them after the readNBT call within the deserialize method after exiting the game and reloading, it just prints the default values for them, 0,0,0,0,... Note that this is immediately after calling readnbt in the same deserializeNBT method.

 

Both these methods are called on the logical server, and the client/server side for these variables are synced, so I don't believe it could be a server/client side issue. There's nothing weird with how I'm calling the two methods, since it works for all my other variables. The only time I set these variables to 0 is in the default/nondefault constructor as well.

 

Anyone know what it could be? Does it just not work well with arrays?

Edited by Turtledove
Link to comment
Share on other sites

Could you post the relevant code? It sounds like there might be some confusion in the naming somewhere (i.e. you're saving it as "3_x_3_array" and loading it as "3x3_array"). Either that, or it's calling your constructor somewhere you don't expect it to. But without the code, those are just guesses.

Link to comment
Share on other sites

13 minutes ago, Blazer Nitrox said:

Could you post the relevant code? It sounds like there might be some confusion in the naming somewhere (i.e. you're saving it as "3_x_3_array" and loading it as "3x3_array"). Either that, or it's calling your constructor somewhere you don't expect it to. But without the code, those are just guesses.

It's got nothing to do with how I'm writing/reading nbt data within the data provider class, I'm 100% certain of that, plus it implements ICapabilitySerializable and doesn't rely on strings as tags.

 

I guess I'm confused about what exactly happens when readnbt is called when used on a player capability. I.e, how does it determine which member variables to populate? It does so just fine for other member variables of my player capability class, but does not for my array variable.

Link to comment
Share on other sites

You have to post the code for us to see the problem. I don't think there is anything different with int arrays (at least the lat time I used them), and it is more likely to be caused by your code.

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

Link to comment
Share on other sites

19 minutes ago, Turtledove said:

It's got nothing to do with how I'm writing/reading nbt data within the data provider class, I'm 100% certain of that, plus it implements ICapabilitySerializable and doesn't rely on strings as tags.

OH, I CapabilitySerializable! I'll be honest, I haven't messed with it, as I could never seem to find any resources for how to use it. I honestly just have an interface defining methods for reading to/writing from NBT, and then use those in my ICapabilityStorage implementation. I'm pretty sure what I'm doing violates diesieben07's coding guidelines, but it's how I first learned to do it back in... was it 1.10?

Anyway, I'm going to defer to DavidM's judgement here, as he's clearly more experienced than I.

  • Like 1
Link to comment
Share on other sites

4 minutes ago, DavidM said:

You have to post the code for us to see the problem. I don't think there is anything different with int arrays (at least the lat time I used them), and it is more likely to be caused by your code.

Alright my player capability class is pretty big, but here's all the relevant parts. The parts removed for clearer reading just affect stuff like bow accuracy, player combat, etc.

 

Anyhow, the 3x3 container (implemented here as a 1-d array) has initial values when the player first joins the world, and they can manipulate values within it from my custom player inventory. All of this works perfectly fine, I send a packet from client to server when the GUI is closed, plus for testing purposes I manually sync both client and server every 1200 ticks. But yeah the problem is that it does not save, when printArtes() is called, it prints what it was initially set to in the constructor:  https://pastebin.com/y8R0Up3L

Link to comment
Share on other sites

Please post the whole mod as a GitHub repo, makes it much easier for us to help you if we can run it and test for ourselves

This is my Forum Signature, I am currently attempting to transform it into a small guide for fixing easier issues using spoiler blocks to keep things tidy.

 

As the most common issue I feel I should put this outside the main bulk:

The only official source for Forge is https://files.minecraftforge.net, and the only site I trust for getting mods is CurseForge.

If you use any site other than these, please take a look at the StopModReposts project and install their browser extension, I would also advise running a virus scan.

 

For players asking for assistance with Forge please expand the spoiler below and read the appropriate section(s) in its/their entirety.

Spoiler

Logs (Most issues require logs to diagnose):

Spoiler

Please post logs using one of the following sites (Thank you Lumber Wizard for the list):

https://gist.github.com/100MB Requires member (Free)

https://pastebin.com/: 512KB as guest, 10MB as Pro ($$$)

https://hastebin.com/: 400KB

Do NOT use sites like Mediafire, Dropbox, OneDrive, Google Drive, or a site that has a countdown before offering downloads.

 

What to provide:

...for Crashes and Runtime issues:

Minecraft 1.14.4 and newer:

Post debug.log

Older versions:

Please update...

 

...for Installer Issues:

Post your installer log, found in the same place you ran the installer

This log will be called either installer.log or named the same as the installer but with .log on the end

Note for Windows users:

Windows hides file extensions by default so the installer may appear without the .jar extension then when the .log is added the log will appear with the .jar extension

 

Where to get it:

Mojang Launcher: When using the Mojang launcher debug.log is found in .minecraft\logs.

 

Curse/Overwolf: If you are using the Curse Launcher, their configurations break Forge's log settings, fortunately there is an easier workaround than I originally thought, this works even with Curse's installation of the Minecraft launcher as long as it is not launched THROUGH Twitch:

Spoiler
  1. Make sure you have the correct version of Forge installed (some packs are heavily dependent on one specific build of Forge)
  2. Make a launcher profile targeting this version of Forge.
  3. Set the launcher profile's GameDir property to the pack's instance folder (not the instances folder, the folder that has the pack's name on it).
  4. Now launch the pack through that profile and follow the "Mojang Launcher" instructions above.

Video:

Spoiler

 

 

 

or alternately, 

 

Fallback ("No logs are generated"):

If you don't see logs generated in the usual place, provide the launcher_log.txt from .minecraft

 

Server Not Starting:

Spoiler

If your server does not start or a command window appears and immediately goes away, run the jar manually and provide the output.

 

Reporting Illegal/Inappropriate Adfocus Ads:

Spoiler

Get a screenshot of the URL bar or copy/paste the whole URL into a thread on the General Discussion board with a description of the Ad.

Lex will need the Ad ID contained in that URL to report it to Adfocus' support team.

 

Posting your mod as a GitHub Repo:

Spoiler

When you have an issue with your mod the most helpful thing you can do when asking for help is to provide your code to those helping you. The most convenient way to do this is via GitHub or another source control hub.

When setting up a GitHub Repo it might seem easy to just upload everything, however this method has the potential for mistakes that could lead to trouble later on, it is recommended to use a Git client or to get comfortable with the Git command line. The following instructions will use the Git Command Line and as such they assume you already have it installed and that you have created a repository.

 

  1. Open a command prompt (CMD, Powershell, Terminal, etc).
  2. Navigate to the folder you extracted Forge’s MDK to (the one that had all the licenses in).
  3. Run the following commands:
    1. git init
    2. git remote add origin [Your Repository's URL]
      • In the case of GitHub it should look like: https://GitHub.com/[Your Username]/[Repo Name].git
    3. git fetch
    4. git checkout --track origin/master
    5. git stage *
    6. git commit -m "[Your commit message]"
    7. git push
  4. Navigate to GitHub and you should now see most of the files.
    • note that it is intentional that some are not synced with GitHub and this is done with the (hidden) .gitignore file that Forge’s MDK has provided (hence the strictness on which folder git init is run from)
  5. Now you can share your GitHub link with those who you are asking for help.

[Workaround line, please ignore]

 

Link to comment
Share on other sites

47 minutes ago, Blazer Nitrox said:

Anyway, I'm going to defer to DavidM's judgement here, as he's clearly more experienced than I.

I haven't been modding much after 1.15, so I guess I'm quite a noob now. :P

 

@Turtledove I'm not sure what some of the data meant, but it seems that you are storing the data that is meant to be the same in two places: the int array and the data manager (corresponding to the 9 integer data parameter). You should keep them in one place instead (I would suggest the data manager instead of the array).

bindedArtes[0] = ArteHandler.ARTES.QUICK_SLASH.ordinal();
bindedArtes[1] = ArteHandler.ARTES.QUICK_SLASH.ordinal();
bindedArtes[2] = ArteHandler.ARTES.QUICK_SLASH.ordinal();
bindedArtes[3] = ArteHandler.ARTES.SCATTERING_SLASH.ordinal();
bindedArtes[4] = ArteHandler.ARTES.SCATTERING_SLASH.ordinal();
bindedArtes[5] = ArteHandler.ARTES.SCATTERING_SLASH.ordinal();
bindedArtes[6] = ArteHandler.ARTES.DEMON_FANG.ordinal();
bindedArtes[7] = ArteHandler.ARTES.DEMON_FANG.ordinal();
bindedArtes[8] = ArteHandler.ARTES.DEMON_FANG.ordinal();

//...

privateData.register(R0C0,0);
privateData.register(R1C0,0);
privateData.register(R2C0,0);

privateData.register(R0C1,0);
privateData.register(R1C1,0);
privateData.register(R2C1,0);

privateData.register(R0C2,0);
privateData.register(R1C2,0);
privateData.register(R2C2,0);

As you can see there are parts like this, in which the values in the two places are de-synced with each other. My best guess is that during the reading/writing, this happened.

 

You also seem to be using the capability as a non-direct handler for certain events, which I would not suggest. Capability is only meant to be a method of storing data, and routines that use the data should be in their corresponding places instead of the capability class. This will make debugging easier.

Edited by DavidM

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

Link to comment
Share on other sites

4 minutes ago, DavidM said:

I haven't been modding much after 1.15, so I guess I'm quite a noob now. :P

 

@Turtledove I'm not sure what some of the data meant, but it seems that you are storing the data that is meant to be the same in two places: the int array and the data manager (corresponding to the 9 integer data parameter). You should keep them in one place instead (I would suggest the data manager instead of the array).


bindedArtes[0] = ArteHandler.ARTES.QUICK_SLASH.ordinal();
bindedArtes[1] = ArteHandler.ARTES.QUICK_SLASH.ordinal();
bindedArtes[2] = ArteHandler.ARTES.QUICK_SLASH.ordinal();
bindedArtes[3] = ArteHandler.ARTES.SCATTERING_SLASH.ordinal();
bindedArtes[4] = ArteHandler.ARTES.SCATTERING_SLASH.ordinal();
bindedArtes[5] = ArteHandler.ARTES.SCATTERING_SLASH.ordinal();
bindedArtes[6] = ArteHandler.ARTES.DEMON_FANG.ordinal();
bindedArtes[7] = ArteHandler.ARTES.DEMON_FANG.ordinal();
bindedArtes[8] = ArteHandler.ARTES.DEMON_FANG.ordinal();

//...

privateData.register(R0C0,0);
privateData.register(R1C0,0);
privateData.register(R2C0,0);

privateData.register(R0C1,0);
privateData.register(R1C1,0);
privateData.register(R2C1,0);

privateData.register(R0C2,0);
privateData.register(R1C2,0);
privateData.register(R2C2,0);

As you can see there are parts like this, in which the values in the two places are de-synced with each other. My best guess is that during the reading/writing, this happened.

Ah you're right, if I print the data parameters every tick server-side, none of them are initialized until I send my packet from the client after editing the grid in the inventory. I'll get back to you on that and see what happens if I fix it.

 

Unfortunately having both is kind of necessary, it makes some of the referencing I need to do 100x times cleaner, for example it's used to determine which attack the player should do on a certain number of clicks:

 

image.png.c756d43043f05c068070b5f1af7bece3.png

 

 

Link to comment
Share on other sites

On 5/26/2020 at 8:31 PM, DavidM said:

I haven't been modding much after 1.15, so I guess I'm quite a noob now. :P

 

@Turtledove I'm not sure what some of the data meant, but it seems that you are storing the data that is meant to be the same in two places: the int array and the data manager (corresponding to the 9 integer data parameter). You should keep them in one place instead (I would suggest the data manager instead of the array).


bindedArtes[0] = ArteHandler.ARTES.QUICK_SLASH.ordinal();
bindedArtes[1] = ArteHandler.ARTES.QUICK_SLASH.ordinal();
bindedArtes[2] = ArteHandler.ARTES.QUICK_SLASH.ordinal();
bindedArtes[3] = ArteHandler.ARTES.SCATTERING_SLASH.ordinal();
bindedArtes[4] = ArteHandler.ARTES.SCATTERING_SLASH.ordinal();
bindedArtes[5] = ArteHandler.ARTES.SCATTERING_SLASH.ordinal();
bindedArtes[6] = ArteHandler.ARTES.DEMON_FANG.ordinal();
bindedArtes[7] = ArteHandler.ARTES.DEMON_FANG.ordinal();
bindedArtes[8] = ArteHandler.ARTES.DEMON_FANG.ordinal();

//...

privateData.register(R0C0,0);
privateData.register(R1C0,0);
privateData.register(R2C0,0);

privateData.register(R0C1,0);
privateData.register(R1C1,0);
privateData.register(R2C1,0);

privateData.register(R0C2,0);
privateData.register(R1C2,0);
privateData.register(R2C2,0);

As you can see there are parts like this, in which the values in the two places are de-synced with each other. My best guess is that during the reading/writing, this happened.

 

You also seem to be using the capability as a non-direct handler for certain events, which I would not suggest. Capability is only meant to be a method of storing data, and routines that use the data should be in their corresponding places instead of the capability class. This will make debugging easier.

 

Yup, fixing that got it to work. I really need to manage capability data initialization and read/writes better. Is there any tips for managing multiple systems on a player capability? My capability class controls mana, accuracy, defense, passive skills, etc. If this were one of my Unreal or OpenGL projects I wouldn't have to centralize all this data onto a single class.

Link to comment
Share on other sites

3 hours ago, Turtledove said:

 

Yup, fixing that got it to work. I really need to manage capability data initialization and read/writes better. Is there any tips for managing multiple systems on a player capability? My capability class controls mana, accuracy, defense, passive skills, etc. If this were one of my Unreal or OpenGL projects I wouldn't have to centralize all this data onto a single class.

I personally define the read/write NBT myself in ICapabilitySerializable, as I find it more flexible (have more control over how stuff is stored, as well as being able to store types such as int array). This would force you to manage string keys though.

However it is really up to you. I would suggest adhering to the single responsibility principle and make sure that your capability class is meant for data storage only; this will make it easier to debug as well as more readable.

  • Like 1

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

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.

Announcements



×
×
  • Create New...

Important Information

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