PerfectPortals

Two plugins in one: colored portal pads with warp system and server transfer, plus a server hub with live selector UI, per-backend queue, and pre-connect fallback. All driven by one JAR.

Version2.4 (Hub Update)
PlatformHytale Server Plugin
Java21
DependenciesNone

Buy on BuiltByBit

Installation

v2.4 hub mode runs on every instance in your network. Install the JAR on the hub AND each backend you want to list. This is a change from v2.3.

  1. Download PerfectPortals-2.4.jar
  2. Place it in UserData/Mods/ on every server (hub + backends)
  3. Start each server once so proxy.json auto-generates at UserData/Saves/MODDING/mods/KatsuyaTV_PerfectPortals/proxy.json
  4. Edit the hub's proxy.json to list every backend (see Hub Config below)
  5. Open statusHttpPort (default 5540) between the hub and each backend in your firewall
  6. Restart or run /pportals reload

Portal Types

6 colors x 2 styles = 12 unique portals. Each has its own texture, particles, and icon.

Light Variants (colored glow)

PortalColorLight
Portal_RedRedRed glow (2 block radius)
Portal_GreenGreenGreen glow
Portal_PurplePurplePurple glow
Portal_OrangeOrangeOrange glow
Portal_PinkPinkPink glow
Portal_YellowYellowYellow glow

Dark Variants (no light)

Same textures and particles, no light emission: Portal_Red_Dark, Portal_Green_Dark, Portal_Purple_Dark, Portal_Orange_Dark, Portal_Pink_Dark, Portal_Yellow_Dark

Warp System

Link any two portals together for instant bidirectional teleportation.

  1. Place two portals anywhere in the world
  2. Open /pportals — the admin UI shows all placed portals
  3. Click portal A in the list, then portal B
  4. Click "Link A - B"
  5. Walk up to either portal and press [F] to teleport

Links are bidirectional. Breaking a linked portal auto-cleans the link.

Server Selector UI (new in v2.4)

Command: /pportals servers (permission perfectportals.servers).

Opens a browsable list of your configured backends. Each row shows:

When a backend is full (count >= maxPlayers), the player is queued on the origin server. Chat shows their position every 5 sec. When a slot frees up, they are auto-transferred.

When a backend is offline and fallbackHub is set, the player is redirected to the fallback instead of failing.

Hub Config (v2.4)

Edit UserData/Saves/MODDING/mods/KatsuyaTV_PerfectPortals/proxy.json:

{
  "enabled": true,
  "fallbackHub": "lobby",
  "statusHttpPort": 5540,
  "statusToken": "your-shared-secret",
  "pollIntervalMs": 5000,
  "httpTimeoutMs": 2000,
  "backends": {
    "lobby": {
      "host": "hub.yourdomain.com",
      "port": 5520,
      "statusPort": 5540,
      "displayName": "Main Hub",
      "maxPlayers": 0,
      "hidden": false
    },
    "survival": {
      "host": "survival.yourdomain.com",
      "port": 5520,
      "statusPort": 5540,
      "displayName": "Survival",
      "maxPlayers": 30,
      "hidden": false
    }
  }
}

Root fields

Per-backend fields

Architecture

+----------+    HTTP /status     +-----------+
|   Hub    |-------------------->|  Backend  |
|  (5520)  |<--------------------|  (5520)   |
+----+-----+  {online, players}  +-----------+
     |
     | referToServer(backendHost, 5520)   (direct, no proxy)
     v
   Client

Server Transfer (portal)

A portal pad can be configured to transfer players to another Hytale server (outside the selector UI).

  1. Open /pportals, select a portal
  2. Go to Server tab
  3. Set Label to a backend name in proxy.json (e.g. survival)
  4. Set Countdown if you want a delay
  5. Walk into / interact with the portal to get transferred (with queue + fallback if applicable)

If the label does not match a backend in proxy.json, the fields Host/Port in the portal config are used directly (raw referToServer without queue or fallback).

Commands

CommandPermissionDescription
/pportals serversperfectportals.serversOpen the server selector UI
/pportals or /pportals menuperfectportals.adminOpen the admin portal UI
/pportals listperfectportals.adminList all portals in chat
/pportals reloadperfectportals.adminReload portals + proxy.json
/pportals help-Show help

Limitations

FAQ

Do backend servers need PerfectPortals?

Yes, in v2.4. Each backend runs PerfectPortals to expose its /status HTTP endpoint so the hub can query its state. This changed from v2.3 (which had a TCP proxy that never actually worked with Hytale's QUIC/UDP traffic).

Why not a TCP proxy like v2.3?

Hytale uses QUIC over UDP for all gameplay traffic. A TCP proxy cannot forward QUIC. The v2.3 "built-in reverse proxy" was non-functional in practice. v2.4 uses direct referToServer with an HTTP sidecar for status data, which is a clean, working architecture.

What does the status endpoint return?

GET /status?token=YOUR_TOKEN returns {"online":true,"players":N,"version":"2.4"}. Request without a token or with the wrong one returns 403.

Can I use portals for same-server teleportation AND server transfer?

Yes. Portals without a server label act as local warps. Portals with a server label matching a backend in proxy.json route through the hub (with queue/fallback). Portals with a server label that doesn't match trigger a raw transfer.

The UI shows a backend as OFFLINE but the backend is running.

The /status HTTP call is failing. Check: (1) statusHttpPort is reachable from the hub, (2) statusToken matches on both ends, (3) no firewall is blocking.

JOIN gives "connection aborted" / "failed to connect".

The host in the backend config must be reachable from the client's machine, not just the hub. Use a public hostname or IP, never 127.0.0.1 / localhost.

How to upgrade from v2.3?

Replace the JAR on every server, edit each proxy.json to the new schema (the old listenPort/target fields are gone), open the statusHttpPort in your firewall, restart.