<!DOCTYPE html> <!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]--> <!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]--> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>The Data API — Sponge 6.0.0 documentation</title> <link rel="shortcut icon" href="../../_static/favicon.ico"/> <link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" /> <link rel="stylesheet" href="../../_static/spongedocs.css" type="text/css" /> <link rel="index" title="Index" href="../../genindex.html"/> <link rel="search" title="Search" href="../../search.html"/> <link rel="top" title="Sponge 6.0.0 documentation" href="../../index.html"/> <link rel="up" title="Creating a Plugin" href="../index.html"/> <link rel="next" title="Custom Data" href="custom/index.html"/> <link rel="prev" title="TextTemplates" href="../text/templates.html"/> <!-- Google Analytics --> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-59476017-2', 'auto'); ga('send', 'pageview'); </script> <script src="../../_static/js/modernizr.min.js"></script> </head> <body class="wy-body-for-nav" role="document"> <div class="wy-grid-for-nav"> <nav data-toggle="wy-nav-shift" class="wy-nav-side"> <div class="wy-side-scroll"> <div class="wy-side-nav-search"> <div id="sp-logo-container" class="page-scroll"> <a class="logo" href="../../index.html"> <img src="../../_static/spongie-mark-dark.svg"> <span>Sponge</span> <i class="fa fa-fw fa-chevron-down"></i> </a> <div id="sp-logo-menu"> <ul id="sp-logo-dropdown"> <li><a href="https://www.spongepowered.org"><i class="fa-fw fa fa-home"></i>Homepage</a></li> <li><a href="https://forums.spongepowered.org"><i class="fa-fw fa fa-comments"></i>Forums</a></li> <li><a href="https://github.com/SpongePowered"><i class="fa-fw fa fa-code"></i>Code</a></li> <li class="active"><a href="https://docs.spongepowered.org"><i class="fa-fw fa fa-book"></i>Docs</a></li> <li><a href="https://jd.spongepowered.org"><i class="fa-fw fa fa-graduation-cap"></i>Javadocs</a></li> <li><a href="https://forums.spongepowered.org/c/plugins/plugin-releases"><i class="fa-fw fa fa-plug"></i>Plugins</a></li> <li><a href="https://www.spongepowered.org/downloads"><i class="fa-fw fa fa-download"></i>Downloads</a></li> <li><a href="https://www.spongepowered.org/chat"><i class="fa-fw fa fa-comment"></i>Chat</a></li> </ul> </div> </div> <div role="search"> <form id="rtd-search-form" class="wy-form" action="../../search.html" method="get"> <input type="text" name="q" placeholder="Search docs" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> </div> </div> <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation"> <ul> <li class="toctree-l1"><a class="reference internal" href="../../server/index.html">Creating a Server</a></li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="../../preparing/index.html">Preparing for Development</a></li> </ul> <ul class="current"> <li class="toctree-l1 current"><a class="reference internal" href="../index.html">Creating a Plugin</a><ul class="current"> <li class="toctree-l2"><a class="reference internal" href="../buildsystem.html">Build Systems</a></li> <li class="toctree-l2"><a class="reference internal" href="../workspace/index.html">Setting Up Your Workspace</a></li> <li class="toctree-l2"><a class="reference internal" href="../project/index.html">Setting Up Your Project</a></li> <li class="toctree-l2"><a class="reference internal" href="../plugin-identifier.html">Plugin Identifiers</a></li> <li class="toctree-l2"><a class="reference internal" href="../plugin-class.html">Main Plugin Class</a></li> <li class="toctree-l2"><a class="reference internal" href="../lifecycle.html">Plugin Lifecycle</a></li> <li class="toctree-l2"><a class="reference internal" href="../injection.html">Dependency Injection</a></li> <li class="toctree-l2"><a class="reference internal" href="../practices/index.html">Practices</a></li> <li class="toctree-l2"><a class="reference internal" href="../optional/index.html">Optionals</a></li> <li class="toctree-l2"><a class="reference internal" href="../logging.html">Logging and Debugging</a></li> <li class="toctree-l2"><a class="reference internal" href="../commands/index.html">Commands</a></li> <li class="toctree-l2"><a class="reference internal" href="../event/index.html">Events</a></li> <li class="toctree-l2"><a class="reference internal" href="../assets.html">The Asset API</a></li> <li class="toctree-l2"><a class="reference internal" href="../configuration/index.html">Configuring Plugins</a></li> <li class="toctree-l2"><a class="reference internal" href="../text/index.html">Text</a></li> <li class="toctree-l2 current"><a class="current reference internal" href="#">The Data API</a><ul> <li class="toctree-l3"><a class="reference internal" href="custom/index.html">Custom Data</a></li> <li class="toctree-l3"><a class="reference internal" href="keys.html">Using Keys</a></li> <li class="toctree-l3"><a class="reference internal" href="datamanipulators.html">Data Manipulators</a></li> <li class="toctree-l3"><a class="reference internal" href="transactions.html">Transactions</a></li> <li class="toctree-l3"><a class="reference internal" href="serialization.html">Serializing Data</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="../blocks/index.html">Blocks</a></li> <li class="toctree-l2"><a class="reference internal" href="../entities/index.html">Entities</a></li> <li class="toctree-l2"><a class="reference internal" href="../items/index.html">Items</a></li> <li class="toctree-l2"><a class="reference internal" href="../trade-offers.html">Trade-Offers</a></li> <li class="toctree-l2"><a class="reference internal" href="../effects.html">Effects</a></li> <li class="toctree-l2"><a class="reference internal" href="../scheduler.html">Scheduler</a></li> <li class="toctree-l2"><a class="reference internal" href="../services.html">Services</a></li> <li class="toctree-l2"><a class="reference internal" href="../database.html">Databases</a></li> <li class="toctree-l2"><a class="reference internal" href="../permissions.html">Permissions</a></li> <li class="toctree-l2"><a class="reference internal" href="../bans.html">Bans</a></li> <li class="toctree-l2"><a class="reference internal" href="../bookview.html">Book Views</a></li> <li class="toctree-l2"><a class="reference internal" href="../economy/index.html">Economy</a></li> <li class="toctree-l2"><a class="reference internal" href="../wgen/index.html">World Generation</a></li> <li class="toctree-l2"><a class="reference internal" href="../manager.html">Plugin Manager</a></li> <li class="toctree-l2"><a class="reference internal" href="../game-profile-manager.html">Game Profile Manager</a></li> <li class="toctree-l2"><a class="reference internal" href="../offline-userplayer-data.html">Offline Player Data</a></li> <li class="toctree-l2"><a class="reference internal" href="../debugging.html">Plugin Debugging</a></li> <li class="toctree-l2"><a class="reference internal" href="../tab-lists.html">Tab Lists</a></li> <li class="toctree-l2"><a class="reference internal" href="../plugin-meta.html">Plugin Metadata</a></li> <li class="toctree-l2"><a class="reference internal" href="../ray-tracing.html">Ray Tracing</a></li> <li class="toctree-l2"><a class="reference internal" href="../tutorials.html">Tutorials</a></li> <li class="toctree-l2"><a class="reference internal" href="../internals/index.html">Implementation-dependent Plugins</a></li> </ul> </li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="../../ore/index.html">Ore Documentation</a></li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="../../contributing/index.html">Contributing to Sponge</a></li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="../../about/index.html">About the Sponge Project</a></li> </ul> </div> </div> </nav> <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"> <nav class="wy-nav-top" role="navigation" aria-label="top navigation"> <i data-toggle="wy-nav-top" class="fa fa-bars"></i> <a href="../../index.html">Sponge</a> </nav> <div class="wy-nav-content"> <div class="rst-content"> <div role="navigation" aria-label="breadcrumbs navigation"> <ul class="wy-breadcrumbs"> <li><a href="../../index.html">Docs</a> »</li> <li><a href="../index.html">Creating a Plugin</a> »</li> <li>The Data API</li> <li class="wy-breadcrumbs-aside"> <a href="https://github.com/SpongePowered/SpongeDocs/blob/BestPractises/source/plugin/data/index.rst" class="fa fa-github"> Edit on GitHub</a> </li> </ul> <hr/> </div> <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> <div itemprop="articleBody"> <div class="section" id="the-data-api"> <h1>The Data API<a class="headerlink" href="#the-data-api" title="Permalink to this headline">¶</a></h1> <p>The unified Data API aims to provide a consistent way of accessing and modifying data. ‘Data’, in this context means any data that is consistently synchronized between client and server. It can be changed server-side and then those changes will be synchronized to the connected clients. This includes, among many others, the text on a sign, the looks of a horse or the health of any living entity.</p> <p>Where other approaches define the available data using interfaces and inheritance (like a <code class="docutils literal"><span class="pre">LivingEntity</span></code> interface providing getter and setter functions for current and maximum health), in Sponge every entity, block etc. is completely oblivious to what data it holds. While this may appear less straightforward than direct accessor methods, it is foremost far more extensible. And thanks to the addition of <a class="reference external" href="https://jd.spongepowered.org/6.0.0/org/spongepowered/api/data/key/Key.html">Key</a>s, simply accessing specific values is no less straightforward.</p> <div class="admonition warning"> <p class="first admonition-title">Warning</p> <p class="last">As of writing, a few parts of the Data API are not implemented. If you are trying to access an API and are receiving an empty <code class="docutils literal"><span class="pre">Optional</span></code> when one is not expected, refer to the <a class="reference external" href="https://github.com/SpongePowered/SpongeCommon/issues/8">Implementation Tracker</a>, ask in the <code class="docutils literal"><span class="pre">#spongedev</span></code> IRC channel or on the <a class="reference external" href="https://forums.spongepowered.org">Forums</a> to find out if the data you need to work with is available yet.</p> </div> <div class="section" id="concepts"> <h2>Concepts<a class="headerlink" href="#concepts" title="Permalink to this headline">¶</a></h2> <p>On first glance at the API docs, the data API threatens to overwhelm you with lots of interfaces and packages. But to simply use the data API, you will not have to deal with many of them, as most interfaces found there are just specific data manipulators.</p> <div class="section" id="dataholder"> <h3>DataHolder<a class="headerlink" href="#dataholder" title="Permalink to this headline">¶</a></h3> <p>A data holder is just that - something that holds data. It provides methods to retrieve and offer back data. The interface itself is completely oblivious to the type of data held. Since only the implementations will possess this knowledge, it is possible to ask a <a class="reference external" href="https://jd.spongepowered.org/6.0.0/org/spongepowered/api/data/DataHolder.html">DataHolder</a> to provide data it does not have or to accept data it cannot use. In those cases, the return values of the methods will provide the information that data is not available (via <code class="docutils literal"><span class="pre">Optional.empty()</span></code>) or not accepted (via the <a class="reference internal" href="transactions.html"><span class="doc">DataTransactionResult</span></a>).</p> </div> <div class="section" id="property"> <h3>Property<a class="headerlink" href="#property" title="Permalink to this headline">¶</a></h3> <p>A property too is data, but not synchronized between server and clients. Therefore, it can only be changed by modifications present on both client and server. Since Sponge is not intended to require a client-side counterpart, properties are not modifiable. Examples of properties are the harvesting ablities on tools (represented as <a class="reference external" href="https://jd.spongepowered.org/6.0.0/org/spongepowered/api/data/property/item/HarvestingProperty.html">HarvestingProperty</a> or the damage absorption of an equippable armor item (represented as <a class="reference external" href="https://jd.spongepowered.org/6.0.0/org/spongepowered/api/data/property/item/DamageAbsorptionProperty.html">DamageAbsorptionProperty</a>).</p> </div> <div class="section" id="datamanipulator"> <h3>DataManipulator<a class="headerlink" href="#datamanipulator" title="Permalink to this headline">¶</a></h3> <p>A data manipulator represents points of cohesive data that describes a certain component of its holder. For example <a class="reference external" href="https://jd.spongepowered.org/6.0.0/org/spongepowered/api/data/manipulator/mutable/entity/HealthData.html">HealthData</a>, which contains both current and maximum health. If a data holder has <code class="docutils literal"><span class="pre">HealthData</span></code>, it has health that can somehow be depleted and replenished and can die if that health is depleted. This allows for the re-use of such components over the API and prevents duplication of accessor methods. For example, sheep, stained glass blocks and leather armor all can share the <a class="reference external" href="https://jd.spongepowered.org/6.0.0/org/spongepowered/api/data/manipulator/mutable/DyeableData.html">DyeableData</a> holding the color they are dyed in.</p> </div> <div class="section" id="key"> <h3>Key<a class="headerlink" href="#key" title="Permalink to this headline">¶</a></h3> <p>A <code class="docutils literal"><span class="pre">Key</span></code> is a unique identifier for a single point of data and can be used to directly read or set that point of data without worrying about data manipulators. It was designed to provide a convenient way of accessing data similar to direct getter/setter methods. All keys used within Sponge are listed as constants in the <a class="reference external" href="https://jd.spongepowered.org/6.0.0/org/spongepowered/api/data/key/Keys.html">Keys</a> utility class.</p> </div> <div class="section" id="value"> <h3>Value<a class="headerlink" href="#value" title="Permalink to this headline">¶</a></h3> <p>Within the Data API, a value referred to by a <code class="docutils literal"><span class="pre">Key</span></code> is encoded in a container object. For this documentation, it is referred to as ‘keyed value’ to avoid confusion with the actual value. A keyed value encapsulates the actual data value (if it is present), a default value (to be used if no direct value is present) and the Key by which the value is identified.</p> </div> </div> <div class="section" id="contents"> <h2>Contents<a class="headerlink" href="#contents" title="Permalink to this headline">¶</a></h2> <div class="toctree-wrapper compound"> <ul> <li class="toctree-l1"><a class="reference internal" href="custom/index.html">Custom Data</a><ul> <li class="toctree-l2"><a class="reference internal" href="custom/datamanipulators.html">Custom DataManipulators</a></li> <li class="toctree-l2"><a class="reference internal" href="custom/dataholders.html">Custom DataHolders</a></li> <li class="toctree-l2"><a class="reference internal" href="custom/serialization.html">Serializing Custom Data</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="keys.html">Using Keys</a></li> <li class="toctree-l1"><a class="reference internal" href="datamanipulators.html">Data Manipulators</a></li> <li class="toctree-l1"><a class="reference internal" href="transactions.html">Transactions</a></li> <li class="toctree-l1"><a class="reference internal" href="serialization.html">Serializing Data</a></li> </ul> </div> </div> </div> </div> </div> <footer> <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation"> <a href="custom/index.html" class="btn btn-neutral float-right" title="Custom Data" accesskey="n">Next <span class="fa fa-arrow-circle-right"></span></a> <a href="../text/templates.html" class="btn btn-neutral" title="TextTemplates" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous</a> </div> <hr/> <div role="contentinfo"> <p>© Copyright 2014-2017, Sponge Contributors. </p> </div>Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>. </footer> </div> </div> </section> </div> <div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions"> <span class="rst-current-version" data-toggle="rst-current-version"> <i class="fa fa-book"> <span>SpongeDocs</span></i> v: 6.0.0 <span class="fa fa-caret-down"></span> </span> <div id="versions" class="rst-other-versions"> <dl> <dt>Contribute</dt> <dd><a href="https://github.com/SpongePowered/SpongeDocs/blob/BestPractises/source/plugin/data/index.rst">Source</a></dd> <dd><a href="https://github.com/SpongePowered/SpongeDocs/edit/BestPractises/source/plugin/data/index.rst">Edit</a></dd> </dl> </div> </div> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT:'../../', VERSION:'6.0.0', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../../_static/jquery.js"></script> <script type="text/javascript" src="../../_static/underscore.js"></script> <script type="text/javascript" src="../../_static/doctools.js"></script> <script type="text/javascript" src="../../_static/spongedocs.js"></script> <script type="text/javascript" src="../../_static/js/theme.js"></script> <script type="text/javascript"> jQuery(function () { SphinxRtdTheme.StickyNav.enable(); }); </script> </body> </html>