[SPIGOT-67] Persistent metadata API Created: 30/Nov/14  Updated: 03/Jul/19  Resolved: 03/Jul/19

Status: Resolved
Project: Spigot
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Minor
Reporter: zreed Assignee: Unassigned
Resolution: Fixed Votes: 19
Labels: nbt, persistent


 Description   

It'd be nice to be able to store data for items etc. and have it be persistent across restarts. Perhaps have a 'plugins' tag either under the 'bukkit' tag or independent of it that is accessible via methods in Bukkit/SpigotAPI. Also have the relevant Minecraft NBT classes exposed for ease of use (they don't change much.) I haven't looked at the NBT code recently but once my CLA request goes through I could look into something like this myself.

That or have something similar to Bukkit metadata but have it be persistent.



 Comments   
Comment by md_5 [ 03/Jul/19 ]

This was added as PersistentDataContainer

Comment by zreed [ 23/May/17 ]

Plugin developers wouldn't need to interact directly with NBT, Spigot would handle conversion automatically.

Comment by BlackBeltPanda [ 23/May/17 ]

I'm not too familiar with NBT but that sounds like a pretty good approach to me.

Comment by zreed [ 23/May/17 ]

It'd be simplest to use NBT (or even custom attributes) as that's already implemented. Using NBT's data types would allow custom data to be read fully without requiring the creating plugin to be loaded. Data would automatically be disposed of by Minecraft when the entity is removed.

There really isn't an easy way to avoid an errant plugin from storing tons of data so it's not worth over engineering this to prevent it. Such an occurrence would be the plugin developer's problem, not Spigot's (assuming it's not a Spigot bug.) Any other plugin could be used to clean up the errant data as well.

As far as keeping track of what plugin owns what, the API should specify that a stored value can't be guaranteed to be unique to any specific plugin unless the data key is prefixed or something. At the API level you would only need a string key and NBT compatible value. 

An external data source wouldn't be a good idea for performance reasons as it would need to be queried for every entity load/unload.

Comment by BlackBeltPanda [ 23/May/17 ]

Would love to see this feature added.

For the above listed issues, my approach would be:
1. Allow the assigning plugin to specify an "expiry" time for metadata.
2. Resolved with #1.
3. Spigot Config option to specify a total size limit for metadata.
4. Resolved with #3.
5. I wouldn't add a prune option but instead allow this to be resolved with #1.
6. JSON format might be the best option here.
7. Not sure I understand this question but if it pertains to the old metadata format, then overloaded methods.
8. This one's tricky since it'd have to make sure the plugin wasn't simply unloaded, i.e. - by Plugman. If possible, a config option for the server owner to specify whether metadata from uninstalled plugins should be removed would probably be best. Not sure what the best way to check for uninstalled plugins would be, though.

Comment by Joshua Küpper [ 21/Jun/16 ]

That's a really cool idea. It also offers the ability to use any kind of storage mechanism, for example Redis. That'd improve performance and make it more dynamical. You could also add "internal parsing guidelines" to your plugin. Something like "if the key ends with _1h or similar input it defines the time the key should be saved"

Comment by Ryan Michela [ 21/Jun/16 ]

Many years ago I wrote the Metadata API, and I always regretted not adding persistence. I'd like to revisit this topic.

Persisting Metadata is a surprisingly difficult problem to solve in the general case. Many questions have no easy answer.

  1. How long should metadata remain persisted?
  2. What if the player never comes back?
  3. What is the size limit on metadata?
  4. How do you keep persisted metadata from filling up the hard drive?
  5. Should persisted metadata be pruned, and if so how and how frequently?
  6. In what format is metadata stored?
  7. How is forwards compatibility between future versions of a plugin guaranteed?
  8. What happens if the plugin that owns the metadata is uninstalled?

Instead of trying to solve the general case poorly, what if there was a simple mechanism for each plugin to handle its own persistence?

Subscribing to a MetadataRequest event would allow a plugin to intervene when metadata is requested to return a previously persisted value. Subscribing to a MetadataSave event would allow a plugin to persist values when they are set.

Using these events, multiple third-party plugins could be developed that answer the above questions different ways.

What do you think?

Comment by Nathan Wolf [ 15/Jan/15 ]

I had a CraftBukkit PR that went through a lot of revisions- I've got code that uses the Configuration API and code that uses the Metadata API. Both allow storage of structured data, and handle configuration serialization - meaning they work in plugins that use the API to serialize items to files and back.

From the feedback I've gotten, devs seem to prefer the idea of the Configuration-based API, though the Bukkit team had preferred Metadata.

I'd like to submit at least one version as a PR, I'd like to see something like this get its way in!

Comment by Ginger Geek [ 20/Dec/14 ]

I think I will PR a setPersistableMeta similar to the implementation in Cubbit. Thoughts?

Comment by Eddie Brown [ 19/Dec/14 ]

There definitely does have to be a difference between this and the temporary meta system, whether it's simply calling this .setAttribute or .setPersistentMeta, etc... Or using an overload as joshua suggested. However I believe that if it is implemented as joshua requested, the old method shouldn't be deprecated.

Comment by Joshua Küpper [ 19/Dec/14 ]

An additional boolean in the method-signature should also work like:

Player.setMetadata(String, MetadataValue) -> Player.setMetadata(String, MetadataValue, boolean)

The old method stays and defaults to false for the boolean, the boolean marks persistence. So old plugins would still be able to use the temporary metadata-API and the old method could be marked as deprecated, because it's only a detour to the real method.

Comment by Eddie Brown [ 14/Dec/14 ]

Persistent meta would be fine, but only if it was given a diff. name to the current system as many plugins would otherwise break.

Comment by Ginger Geek [ 07/Dec/14 ]

This fork of Spigot has this: https://hub.spigotmc.org/stash/projects/MULTICUBE/repos/cubbit/browse

Generated at Mon Dec 15 03:42:06 UTC 2025 using Jira 10.3.13#10030013-sha1:56dd970ae30ebfeda3a697d25be1f6388b68a422.