Store custom data in block/chunk

Hello all,

I’ve created my own custom data classes and have successfully been able to store custom data to an item stack.

I now also want to store custom data to a block.
I know blocks themselves can’t store custom data themselves (unless they are tile entities), so as far as I am aware the best way to do this is to store data to the chunk instead and just include info about the block’s coordinates in your data somehow.

However I don’t know how to do this.

At first I noticed that Chunk seems to have methods similar to the ones I used to store data in ItemStack - namely getOrCreate, offer, and get(Key). The chunk’s methods looked exactly the same as for itemstack except they take in a Vector3i named “coordinates” as a parameter as well. I assumed this means that Sponge themselves implemented a system where you can store data in a chunk that also includes coordinates.
Note: Are the coordinates absolute block coordinates or relative coordinates within the chunk? I tried both and had the same issue I’m about to describe.

However, when I use the getOrCreateMethod, I got an AbstractMethodError.

Method
net/minecraft/world/chunk/Chunk.getOrCreate(IIILjava/lang/Class;)Ljava/util/Optional; is abstract
net.minecraft.world.chunk.Chunk.getOrCreate(Chunk.java)
org.spongepowered.api.world.extent.LocationCompositeValueStore.getOrCreate(LocationCompositeValueStore.java:128)
com.mydomain.customblocksanditems.CustomBlocksAndItems.onInteract(CustomBlocksAndItems.java:154)

Can anyone explain why I’m getting this error and how I should be storing custom data inside a chunk?

Edit: I get the same error when using the Chunk.get(coordinates, key) method.

Assuming your using custom data from api 7 (not sure if the rule applies in api 8).

Custom data can only be applied to 3 different DataHolders (cannot remember the three). I dont believe chunks nor locations are part of those three. I believe it states the three on the doca, but a quick look from me couldn’t find it

The docs say " It’s also possible to create your own data objects, allowing you to serialize objects directly to players, entities and more!"

Doesn’t mention a fixed list or anything.

Are you 100% sure it’s not possible to do this? If not then Sponge really needs to add it. With spigot you can do it with PersistentDataContainers.

Edit: Yes I’m using api 7

Ah they may have added more since I last looked. Ignore me

Is there any way I can tell if it is possible or not? And if it has since been added do you know what else might be causing my error?

So the error your getting is essentially a MethodNotImplementedException, its just its different due to how sponge is built (using Mixins and still).

So the way your doing it isnt possible. You could look at the github and see at what point its causing the error, but Chunk wouldnt be possible.

I know Location can do some custom data stuff (not sure if applying data can be done on it), or try world?

I’ll give world a try. And maybe location as well, thanks.

1 Like

Oh i would also try api 7.4.1. I normally assume people develop and run on the latest, but then you find out they are running 7.1 due to a specific forge version. If you are using 7.1 then it will only be able to be applied to the 3 types mentioned before because when 7.2 just came out is the last time i properly read the custom data docs

I looked at the doc history in the github. There was an unrelated change to the serialization page when 7.2 was released but other than that the pages haven’t been changed for years.

I’m on 7.3.0 currently.

Ok, I tried with world, and if I attempt to do it at a location where there is a tileentity, it works and stores data in the tileentity. If I try to do it at a location where there is just a normal block, World#getOrCreate just returns an empty optional.

Trying location now.

Edit: Exact same result with location. If there is a tileentity at that location then it works, otherwise it doesn’t.

So… either there IS a way to store data in a chunk but I haven’t found it yet, or Sponge needs to add that!

Edit 2: So now my question probably is, what’s the best alternative? I want to store data relating to a block, ideally in a way that stores it in Minecraft’s format so I don’t need a database. If this were spigot, I’d use Chunk’s PersistentDataContainer.

Is there any way to store data in a chunk at all? Maybe not through the data API but through some other means? Directly with NBT?

So you can read any Minecraft file written in NBT (Minecrafts saving format) as well as save using the NBT data format.

Found in DataFormats.NBT

However I have never attempted to read and write chunk data as everything ive needed has been in the API. But if I was going about it, I would read the chunk file, study it and then attempt to pass in custom data)

That’s awesome that it’s possible, but I don’t quite see how the code you linked helps, I can’t quite figure out what it is (I’m super new to Sponge). Could you tell me roughly how I’d access NBT of a chunk?

So thats a NBT reader and writer. So if you run


File chunkFile;
DataContainer container = DataFormats.NBT.readFrom(new FileReader(file);

You will then have access to the chunks data container (im hoping you read DataContainers in the docs). From there you can read how the structure is stored and then write in your data safely. Then write it back using

DataFormat.NBT.writeTo(new FileWriter(file), container);

P.s remember to close your readers and writers (standard states you should flush too, but closing does that automatically since Java 7)