Documentation menu

Developers

Java API

Move players, find them, and read the network from your own Hytale plugins.

Your plugins can move players through Link: from a menu, an NPC, a portal, or the end of a match. Everything is on net.beehivesys.link.hytale.LinkPlugin.

Link is not on a Maven repository yet. Download the jar from the releases page, compile against it, and don’t shade it: the Link jar in mods provides the classes at runtime. List Link (group Link, name Link) as a dependency in your plugin’s manifest.json, so Hytale loads it first.

Move a player

Transfers.javaJava
// to one named server
LinkPlugin.send(player, "sw-1");

// into a specific world on that server
LinkPlugin.send(player, "farm-1", "farm-42");

// let matchmaking pick a server in a group
LinkPlugin.play(player, "skywars");
MethodDoes
send(PlayerRef, String serverId)Sends the player to that server.
send(PlayerRef, String serverId, String world)Same, and the player lands in that world. If the world doesn’t exist there, they land in the default world.
play(PlayerRef, String group)Picks a server in the group with matchmaking and sends the player there.

Each returns the LinkServer the player is going to.

Handle failures

When a move can’t happen, the methods throw LinkException. Its message is written for players, so you can show it as is:

PlayButton.javaJava
try {
    LinkServer target = LinkPlugin.play(player, "skywars");
    player.sendMessage(Message.raw("Sending you to " + target.id() + "..."));
} catch (LinkException e) {
    // Already worded for the player: "Every skywars server is full."
    player.sendMessage(Message.raw(e.getMessage()));
}
MessageWhen
There is no server called <id>.No server has that id.
You are already on <id>.The target is this server.
<id> is full.The target reports it is full.
There are no <group> servers.The group is empty.
Every <group> server is full.Every server in the group is full.
Transfers are not available yet, try again in a moment.This server has not reached the registry yet.
Transfers are not set up on this server.Link is not running here, see the log.

Find players

Every server shares who is online with each heartbeat, so you can list the players of the whole network or find one of them.

Friends.javaJava
// where is a friend?
LinkPlayer friend = LinkPlugin.find("Steve");
if (friend == null) {
    player.sendMessage(Message.raw("Steve is not online."));
} else {
    player.sendMessage(Message.raw("Steve is on " + friend.server()));
}

// how many are in a game right now
int inSkyWars = 0;
for (LinkServer server : LinkPlugin.servers("skywars")) {
    inSkyWars += LinkPlugin.players(server.id()).size();
}
CallReturns
LinkPlugin.players()Everyone online in the network, once each.
LinkPlugin.players(serverId)The players on one server.
LinkPlugin.find(nameOrUuid)Where a player is, or null. Names are not case sensitive.

A LinkPlayer has uuid(), name() and server(), the id of the server they are on. Your own server’s players are live. Other servers’ players are as of their last heartbeat, at most 3 seconds old with Redis and 10 with Cloudflare. If a player is mid-hop, they are listed once.

With a shared file, servers don’t share who is online. Then these calls only know the players on your own server.

Read the network

Every server registers with its group from link.json, so you can list the servers of one type, like all lobbies, and send a player to one of them. The list is Link’s local copy of the registry, so the calls are instant and safe to use in a menu.

ServerMenu.javaJava
// every lobby, for a server selector
for (LinkServer lobby : LinkPlugin.servers("lobby")) {
    String load = lobby.reportsLoad() ? lobby.players() + "/" + lobby.maxPlayers() : "";
    menu.add(lobby.id(), load);
}

// when the player picks one
try {
    LinkPlugin.send(player, picked.id());
} catch (LinkException e) {
    player.sendMessage(Message.raw(e.getMessage()));
}
CallReturns
LinkPlugin.servers()Every server in the network, this one included.
LinkPlugin.servers(group)The servers in one group. The name is not case sensitive.

Both return an empty list when Link is not running on this server, so you don’t need to check for that first.

For more, LinkPlugin.link() returns the running network, or null when Link is not configured:

CallReturns
link.server(id)One server, or null.
link.self()This server.
link.isReady()true once transfers work.
link.isRegistryDown()true while the registry does not answer.

A LinkServer has id(), group(), host(), port(), players() and maxPlayers(). With a shared-file registry, the counts are -1: check reportsLoad() first. isFull() is true only when a server reports that it is full.

Something wrong or missing on this page? Open an issue on GitHub.