When I added IMetadatable and the metadata API to Bukkit, I intentionally left out persistence. This was a mistake.
I would like to propose a mechanism for attaching named metadata to entities that persists in the underlying world store. This could be implemented with NBT or some other means.
Would very much love to see this as it would allow the plugin-plugin communication and shared data storage on entities to persist even when one plugin is removed.
The simplest (and probably best) way to do this is a simple String -> String map with a shared key pool. (i.e. if PluginA stores a value in ‘foo’ and PluginB does as well, PluginA and PluginB will end up with the same value) As well, you can store any data in a String, and a String -> String map is easy to persist to NBT.
Part of what made metadata so intensely painful to use in Bukkit was the fact that it was per-plugin, and allowed any Object as a value. A replacement for the per-plugin behavior is for plugins to uniquify their keys by prefixing them with the name of the plugin (e.g. PluginA uses ‘pluginA:foo’ and PluginB uses ‘pluginB:foo’; no more conflicts); as for Object values, Gson and Integer.toString/Integer.parseInt should cover that.
EDIT: As coaster mentions, an NBT abstraction could also work, but then it gets much closer to the metal and becomes a bit harder to persist.
This would be possible with storing custom NBT data. So sponge would most likely develop some kind of abstraction to access such data.
The big question I see with such metadata is where to store it. If you store it with the world, when someone deletes the plugin which was using it, it remains. If you store it with the plugin, when someone deletes the world which it was attached to, it remains. I really needs to be linked to both, somehow…
Leaving old metadata behind doesn’t really seem like that big a deal; linking to the world is much more important imo.
Offering a “metadata pruner/editor” tool would be a way to help with this; open up your world with the Pruner tool, punch in the keys of the metadata you want gone, and it’s all removed.
I agree! Especially if the metadata is stored with the plugin name in the key, like “myplugin::tree.location”.
@deltahat If you haven’t yet, you should check out the thread about the proposed component system. It is definitely in need of a persistence solution.
Do we really need custom metadata API? Couldn’t we just use NBT tags?
Exactly. Wanted to open a topic for that as well
I have to agree. Custom NBT tags is the practical way. All we need is a abstraction layer to them.
That way we don’t break on MC updates.
If desperately wanted gone you could add a button to said tool where you select a JAR file which scans for metadata usage in a plugin and purges/prunes that data automatically.
That sounds more complicated to make than it would be beneficial though.
But it doesn’t need to be the only way. If abstracted it could persist in a number of ways depending on what entity it is attached to, It could be sent as JSON, HOCON, into a database to be shared with other servers.
It would be really cool to be able to attach data to the player object, and have a plugin provide a namespace on that player object that redirects the data to a database, or a redis server or something.
Redirecting the entire playerstate is something I’ve been toying with in my head for a while, It would be great if players could have multiple profiles on a server, allowing admins and moderators to be able to play as players with little or no overlap between their two “lives”, or seperate stats between worlds mimicing bungee servers, or letting bungee servers tie the “lobby” data for a player into one place.