Uploaded image for project: 'Minecraft API'
  1. Minecraft API
  2. MCAPI-55

Direct NBT Data Access

    XMLWordPrintable

    Details

    • Type: New Feature
    • Status: Open
    • Priority: Normal
    • Resolution: Unresolved
    • Labels:

      Description

      Proposed Addition:
      Direct access to the persistent NBT data store of:

      • Blocks in the world
      • ItemStacks
      • (?)Entities

      Description:

      A plugin developer would be able to obtain a Block either from an event or from World+XYZ coordinates in the normal method, then use Block.getNBTData() to obtain an object representing the root element of its persistent NBT storage. If none currently existed, one would be created. Various getters and setters would exist in each node, similar Bukkit's current YamlConfiguration interface.

      The same method would exist in ItemStacks and Entities, and would return the same class of object. NBT data could be removed from a tool and placed on a block, and vise versa.

      All plugins will see the same NBT data, which is the entirety of the data contained in that object. NBT data will not be identified as belonging to one plugin or another. Both "custom" and "vanilla" data can be read or set, regardless of whether it alters Minecraft's behavior or whether it is purely cosmetic or useless.

      Justification

      The non-persistent metadata of Bukkit was heavy due to its reliance on HashMaps, and didn't actually fill a very real need we plugin developers have for tagging a block or ItemStack with persistent data. So far we've each been cobbling together different storage systems with various levels of reliability. Some are using flatfiles, others are using local sqlite or h2 databases, others are using "remote" mysql stores.

      All of these approaches run into trouble when we arrive at the problem of matching up the relevant World+XYZ location information with the equivalent custom-data. This is something I like to call linearization of location data. Since Java doesn't have a two dimensional Collection interface, and because of our sparse population of data, most of us (including Notch and Jeb_) wind up abusing HashMaps for the purpose. HashMaps, of course, have only one longint for addressing, and collisions in Location.hashCode() and other linearization functions, while unlikely at any given instance, are a serious concern of mine for Minecraft's overall stability. (This particular instance can be solved by using a non-colliding function where the maximum extents are known such as the current +/-30,000,000)

      I digress... we need to be able to stuff location- and entity- specific data directly onto the relevant objects because more than anything else, it reduces the computational complexity of the result: Every time you have to match up a block with its custom data, that's an O(n log n) operation that could have been avoided by just setting NBT data in the first place. Likewise, instead of saving the map, then saving the custom data, you could just save the map with the custom data inside it. One search, one save, one load, is always going to be better than two. You get persistence for free instead of forcing every plugin developer to reinvent a wheel Minecraft already contains.

      Use-Case

      Vastly simplifies the server-side operation of plugin blocks, and helps make inter-process communication about relevant objects possible.

      Let's say I wanted to re-write an RP2/IC2/BC energy framework. I could store an integer "EU" in the NBT data of my custom generator block, and each tick distribute that EU to neighboring wires. Other plugins could create machines, and simply look in adjacent blocks each tick for EU to consume.

      ...Or I could attach a "prefix" string to a mob, such as "daywalker" zombie. Depending on what other features are available, I could render the zombie differently, add a title above its head, interrupt it if it tries to burn, and other plugins can recognize it instantly for what it is just by checking its NBT.

      ...Or I could store an enchantment I didn't want on this tool, into a bookcase so I could retrieve it later. Other plugins, such as custom tools, would also be able to detect the enchantments within the block.

      ...Or I could make a "bank block", a multi-container that exposes its inventory in "tabs", and switch between tabs by swapping which NBT inventory list is in the name/spot that Minecraft recognizes. Naive plugins that operate on containers would always see the exposed tab, and plugins using the Bank Block API could access the extra tabs just by reading in the NBT data, even if the Bank Block plugin itself was unloaded. Later, other kinds of multi-container storage such as advanced crafting tables and fabrication devices could be developed, and be inter-operable with plugins that affect multi-containers.

      I can't possibly think of all the use cases that simple plugin storage and access of NBT data would provide. It'd just be a huge help.

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              falkreon Isaac Ellingson
            • Votes:
              20 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated: