Documentation menu

Namespaces

A private JSON store for each game, keyed by (gameMode, namespace). Invisible to every other game, versioned for safe updates.

Stats and currencies cover numbers. For everything else - kit selections, cosmetics, quest progress, per-player settings - each game gets a namespace: an arbitrary JSON blob that is yours and yours alone.

namespace: skywars
{
  "selectedKit": "archer",
  "unlockedKits": ["soldier", "archer", "tank"],
  "cosmetics": { "cage": "heart", "trail": "flames" },
  "settings": { "autoTeam": true }
}

Store whatever shape you want. It rides back on every profile load:

Kit.java
hive.player()
    .fetchPlayerData(player.uuid(), player.name(), "skywars", GameType.HYTALE)
    .thenAccept(data -> {
      NamespaceData mine = data.getNamespace("skywars");   // only ever your data
      String kit = mine != null ? mine.getData().get("selectedKit").getAsString() : "default";
      giveKit(player, kit);
    });

Yours alone

A namespace is keyed by (gameMode, namespace), and a game can only read its own. Your SkyWars store is invisible to and untouchable by every other game on the network - no shared schema to coordinate, no other team’s bug that can corrupt your data, no naming collisions. It’s a private database per game, with none of the setup.

Read and write directly

The profile load hands you a read-only snapshot. To read or change one namespace on demand - the common case once a player is in-game - reach for the typed playerData store:

SkyWarsData.java
var store = hive.playerData("skywars", SkyWarsData.class);

// Read just this player's data on demand (null until their first write)
store.get(player.uuid(), "skywars")
    .thenAccept(data -> giveKit(player, data == null ? "default" : data.selectedKit()));

// Safe read-modify-write - auto-retries if another server wrote first
store.update(player.uuid(), "skywars", SkyWarsData.defaults(),
    data -> data.unlock("archer"));

update is the one to reach for. It reads the current value, applies your function, and writes it back guarded by the namespace version. If another server wrote in between it re-reads and retries, so two servers touching the same player can’t clobber each other, and you never pass a version number yourself. Use put for an unconditional overwrite and delete to clear a namespace.

Versioned for safe updates

Every namespace carries a version, and that is what makes update safe: a stale write is rejected, not lost in a last-writer-wins race. You get a private store and correctness under concurrency, for free.

Namespace or stat? Structured state that’s just yours → namespace. Anything you want ranked or counted over time → statistics. Don’t build a leaderboard inside a JSON blob.

Next

  • Statistics - per-game counters and leaderboards.
  • Currencies - network-wide balances on the player.