Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON Conversion Spec #55

Open
Offroaders123 opened this issue Nov 8, 2024 · 2 comments
Open

JSON Conversion Spec #55

Offroaders123 opened this issue Nov 8, 2024 · 2 comments
Assignees
Labels
enhancement New feature or request

Comments

@Offroaders123
Copy link
Owner

I didn't realize the Java Edition has an in-built mechanism that converts JSON <=> NBT, I thought the concept behind that was just a mechanic of users working with NBT data outside of the game itself, like with third-party projects like yours truly.

JSON and NBT - Minecraft Wiki

If this does have a specific intended behavior for converting to and from NBT and JSON primitives, then this is a spec that NBTify itself should also follow. As of yet, I decided to essentially only make safe conversions for working with JSON itself, without any implied value range inferences, say for example whether a value is small enough to fit inside of a TAG_Byte, that shouldn't dictate that it's type is indeed that size, because when the game loads that file, it might be expecting a different number type. This concept was worrisome to me, so I went with what seemed like the least opinionated route, where it would only convert types when they safely could assumed to be such. For example, going from JS booleans to TAG_Byte is okay, because this is what NBT itself does too. However, converting a TAG_List of TAG_Byte values to a TAG_Byte_Array doesn't seem as straightforward, so I don't do that.

If this behavior is expected though, then it is something that NBTify should allow for too. Personally, I think for general JSON out in the world, the current NBTify implementation for conversion works well for that, because it doesn't assume anything to be safe coming in. However, in an expected scenario of data coming in from the game, and you know where it's reading into (like player data for example), then if the game is okay with key-value pairs being of different types, then conversion doesn't seem to be much of an issue.

@Offroaders123 Offroaders123 added the enhancement New feature or request label Nov 8, 2024
@Offroaders123 Offroaders123 self-assigned this Nov 8, 2024
@Offroaders123
Copy link
Owner Author

Discussions from Discord

Offroaders123
Right now I just cast to a broader type when converting to JSON, hence meaning the same data won't be the same data types after going through a file conversion.

// SNBT
{
  Hello: 0b,
  Nice: true,
  Hi: {
    Heya: [B;0b,1b,2b,3b,4b,5b]
  }
}

// ... to JSON
{
  "Hello": 0,
  "Nice": true,
  "Hi": {
    "Heya": [0,1,2,3,4,5]
  }
}

// NBT (represented here as NBT)
{
  Hello: 0.0d,
  Nice: 0b,
  Hi: {
    Heya: [0.0d,1.0d,2.0d,3.0d,4.0d,5.0d]
  }
}

Offroaders123
Part of my concern for what the Wiki describes doing, is that if the game expects a specific key-value to be of a certain type, sometimes it will invalidate the entire file if something isn't correct.

vhebert
Where is that stated?

Offroaders123
Of course you wouldn't want to mass-convert NBT files to JSON (and back), but I also don't want to make it seem like it should be done at all.

Offroaders123
One time I was editing the level.dat in Bedrock, and I set the type of one of the keys to something different by accident, and it didn't load the file.
I think it was NetherScale, but I don't remember for sure.
I have only made a few things to try editing those outright, and that was one of them.

vhebert
By that you mean the world itself didn't load?

Offroaders123
I did manage to open, but it either just made a new level.dat or it used the level.dat_old version instead.
Might need to debug this more, it was a little while back.
It was a surprise though.

@Offroaders123
Copy link
Owner Author

Further discussions from Discord

vhebert
Java edition does sometime similar if certain information cannot be found, though in a lot of cases there's a fallback value the game typically refers to in those cases.
But I have not tinkered around with bedrock enough to test how they handle things.
But obviously you're going to need to preserve the type data in order for things to work when putting data back into minecraft.
Although, it is worth mentioning that you sometimes don't need to keep the typing depending on the context of the snbt.
Java edition commands, for example, will figure out the required type for a key-value pair implictily, as nbt is not defined by a type->value pairs, but by string->value pairs.

vhebert
For example:
/summon minecraft:creeper ~ ~ ~ {Health:1}
Will summon a creeper with half a heart of health. Health is TagFloat in java edition.

Offroaders123
So it does allow converting TAG_Int to TAG_Float implicitly?

vhebert
But I could just as easily do:
/summon minecraft:creeper ~ ~ ~ {Health:1L}
And it will still work the same as the previous command.

Offroaders123
Very interesting okay, I didn't know the premise of that.

vhebert
Commands typically use snbt, as that's what map makers have used for almost a decade to make command block stuff with.

Offroaders123
Now I'm curious if it does this same thing for NBT files, or if it will error when reading them.

vhebert
Yeah, I have not tested that. That would be interesting.
I'm inclinded to think it would not work.

Offroaders123
Yeah me too.
I'm also curious whether this is intended behavior with the concept for SNBT/NBT, or if it's more of a side-effect and or fallback for commands.
Because if it's intended to work that way, then I would do it too.
But if it would only safely do that on Java, and not Bedrock or LCE, then I would stick with the safe-casting one.

vhebert
I don't think LCE even has anything related to snbt afaik.

Offroaders123
But in terms of expected NBT types, say if someone used Dovetail to edit an LCE NBT file, would LCE allow for the changing of a key-value primitive type? That's the part I'm unsure of.

vhebert
For standard nbt data you should preserve the typing of the data you get.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant