PerfectPortals v2.4
2026-05-26
Hytale Update 5 compatibility update.
Changes:
- Updated for Hytale Update 5 (Pre-Release 5).
- Recompiled against the latest server API (JOML vectors, new permission and HUD APIs).
- Fixed the red "Target Version" warning shown in the mod manager.
- No feature changes. Your existing configs, data and saved files are kept as is.
How to update:
- Stop your server.
- Replace the old PerfectPortals jar with this one.
- Start your server. Nothing else to do.
v2.4 - Hub System
- New server selector UI: /pportals servers (permission: perfectportals.servers)
- Real-time backend status via HTTP sidecar (online, player count)
- Pre-connect fallback to a configured hub when a backend is offline
- Per-backend queue with live position updates in chat
- Hot config reload: /pportals reload
Breaking changes:
- Replaces the TCP reverse proxy from v2.3 (incompatible with Hytale's QUIC/UDP traffic).
- proxy.json format changed. See HUB_v2.4.md bundled in the JAR for the new config schema and deployment guide.
Fixes:
- No more "you're on an old plugin" warning spam (target version updated).
Patch Notes v2.3 - Spawn Direction & Fixes
- Added configurable spawn direction per portal (N/E/S/W). Players now teleport in front of the destination portal facing the correct direction instead of spawning on top of it
- Spawn direction buttons in the Info tab of the admin UI
- Fixed Ancient Gateway (Portal_Device) not working when PerfectPortals is active. Vanilla gateways now work normally unless specifically linked in PerfectPortals
- Updated version label in admin UI
Patch Notes
v2.2 - Cross-World Teleport Fix
- Fixed portals not changing world when teleporting between different maps. Players were being teleported to the correct coordinates but staying in the same world instead of transferring to the linked portal's world.
- Fix applies to both F-key interaction and collision-based activation.
PerfectPortals v2.1 - Patch Notes
New Features
Auto-Link by Color
Collision-Based Teleportation
- Portals now automatically link when you place two portals of the same color as the same player
- Place a Green portal, then place another Green portal anywhere (even in a different world) -- they link instantly
- If multiple unlinked portals of the same color exist, a message guides you to use /pportals admin
- Can be toggled on/off in Settings
Custom Portal Names
- New activation mode: walk onto a portal to teleport instead of pressing F
- Three modes available: USE KEY (F), COLLISION, or BOTH
- Built-in cooldown prevents ping-pong teleportation (configurable in Settings)
- Configurable via the new Settings panel in the admin UI
Redesigned Admin UI
- Portals can now be renamed with a custom display name
- Names appear in the portal list, chat messages, and admin UI
- Rename from the portal detail header in the admin panel
- Full dark flat theme (900x550) with sidebar + tabbed content area
- Sidebar: searchable portal list with pagination
- Three tabs per portal: Info, Link, Server
- Info tab: portal details (ID, type, position, world, owner, name, status)
- Link tab: see current link + one-click "Link to..." picker (no more confusing A/B selection)
- Server tab: inline server config form (host, port, countdown, label)
- Settings panel: activation mode, cooldown, auto-link toggle
Improvements
Better In-Game Messages
- Portal placement now shows contextual messages (auto-linked, instructions, or multiple matches warning)
- "This portal is not linked" now includes instructions: "Use /pportals admin to link it"
- Portal names displayed in /pportals list
Technical
- New config.json for global settings (activation mode, cooldown, auto-link)
- Collision system uses Universe.getPlayers() + Transform API for reliable position detection
- Shared cooldown between F key and collision prevents ping-pong in BOTH mode
- Backward compatible with existing portals.json (name field is optional)
PerfectPortals v2.0 - Patch Notes
## What's New: Built-in Reverse Proxy
PerfectPortals v2.0 introduces an integrated TCP reverse proxy, allowing you to run multiple Hytale servers behind a single public IP. Players never see your internal server IPs — they connect to one address and portals seamlessly route them between servers.
### New Features
### Bug Fixes & Improvements
- Built-in TCP Reverse Proxy — No external tools needed. The proxy runs directly inside the plugin.
- Multi-port architecture — Each backend server gets its own public port. Fully reliable, zero protocol parsing.
- Internal IP support — Backend servers can use Docker IPs (172.x.x.x), local network (10.x.x.x, 192.168.x.x) or localhost.
- Automatic fallback — If the proxy is disabled, the plugin works exactly like v1.1 (direct
referToServer).- Zero config for existing users — Proxy is disabled by default. Existing setups work without changes.
---
- Improved transfer countdown display
- Better error handling for unreachable servers
- Cleaner console logging
## Proxy Setup Guide
### Architecture Overview
Players only know your public IP. Backend servers are hidden.Code:Players connect here (public) | v [PerfectPortals Proxy] Port 5520 ──> Lobby (localhost:5521) Port 5530 ──> SMP (172.18.0.3:5520) Port 5540 ──> PvP (172.18.0.4:5520)
---
### Step 1: Install the Plugin
1. PlacePerfectPortals-2.0.jarin your lobby server'sUserData/Mods/folder
2. RemovePerfectPortals-1.1.jarif present
3. Start the server once to generate config files
4. Stop the server
---
### Step 2: Change Your Lobby Server Port
Your lobby Hytale server needs to listen on a different port than the proxy.
In your Hytale server configuration, change the listen port from5520to5521(or any unused port).
The proxy will listen on5520(the public port) and forward to your lobby on5521.
---
### Step 3: Configure the Proxy
Open:UserData/Saves/MODDING/mods/KatsuyaTV_PerfectPortals/proxy.json
Default content (generated on first launch):
Edit it for your setup:JSON:{ "enabled": false, "publicHost": "localhost", "backends": { "lobby": { "listenPort": 5520, "target": "localhost:5521" } } }
Fields explained:JSON:{ "enabled": true, "publicHost": "play.yourserver.com", "backends": { "lobby": { "listenPort": 5520, "target": "localhost:5521" }, "smp": { "listenPort": 5530, "target": "172.18.0.3:5520" }, "pvp": { "listenPort": 5540, "target": "172.18.0.4:5520" } } }
| Field | Description |
|-------|-------------|
|enabled| Set totrueto activate the proxy |
|publicHost| Your public hostname or IP (what players use to connect) |
|backends| Map of backend servers |
|listenPort| The public port the proxy listens on for this backend |
|target| The internal address of the actual Hytale server |
You can add as many backends as you want.
---
### Step 4: Configure Portals In-Game
1. Place portal blocks in your lobby
2. Open the admin UI:/pportals
3. Select a portal, click Server Config
4. Fill in the fields:
| Field | What to enter |
|-------|---------------|
| Host | Your public hostname (e.g.play.yourserver.com) |
| Port | The proxy listen port for the target backend (e.g.5530for SMP) |
| Countdown | Seconds before transfer (0 for instant) |
| Label | IMPORTANT: Must match the backend name in proxy.json (e.g.smp) |
The Label field is what links the portal to the correct proxy backend. It must be an exact match (case-sensitive).
---
### Step 5: Open Firewall Ports
Make sure all proxy listen ports are open in your firewall:
Your backend internal ports do NOT need to be exposed publicly.
5520(lobby)5530(smp)5540(pvp)- etc.
---
### Step 6: Start and Test
1. Start all your backend Hytale servers
2. Start the lobby server (with PerfectPortals v2.0)
3. You should see in the console:
4. Connect toCode:[PerfectProxy] lobby | Listening :5520 -> localhost:5521 [PerfectProxy] smp | Listening :5530 -> 172.18.0.3:5520 [PerfectProxy] pvp | Listening :5540 -> 172.18.0.4:5520 [PerfectProxy] Started with 3 backend(s). [PerfectPortals] v2.0 loaded. 5 portal(s) registered.play.yourserver.com:5520
5. Walk into a portal configured for SMP
6. You should be transferred to the SMP server via port 5530
---
### Docker Example
If you run Hytale servers in Docker:
proxy.json on the lobby:YAML:# docker-compose.yml services: lobby: image: hytale-server ports: - "5520:5520" # Proxy lobby port (public) - "5530:5530" # Proxy SMP port (public) - "5540:5540" # Proxy PvP port (public) networks: - hytale smp: image: hytale-server expose: - "5520" # Internal only, not exposed publicly networks: - hytale pvp: image: hytale-server expose: - "5520" networks: - hytale networks: hytale: driver: bridge
---JSON:{ "enabled": true, "publicHost": "play.yourserver.com", "backends": { "lobby": { "listenPort": 5520, "target": "localhost:5521" }, "smp": { "listenPort": 5530, "target": "smp:5520" }, "pvp": { "listenPort": 5540, "target": "pvp:5520" } } }
### Troubleshooting
"Failed to start proxy: Address already in use"
Another process is using the port. Make sure your lobby server listens on a different port (e.g. 5521) and no other service uses the proxy ports.
Portal says "Transferring..." but nothing happens
"Proxy backend 'xxx' not found, falling back to direct transfer"
- Check that the backend server is running
- Check that the proxy listen port is open in the firewall
- Check console for
[PerfectProxy] Failed to connect to backenderrors
The portal's Label doesn't match any backend name in proxy.json. Make sure the Label is exactly the same (case-sensitive).
Proxy works but players can still connect directly to backend IPs
Configure your firewall to block external access to backend ports. Only the proxy ports should be public.
---
### Non-Proxy Mode (v1.1 behavior)
If you don't need the proxy, leaveproxy.jsonwith"enabled": false. The plugin will use directreferToServercalls as before. Nothing changes from v1.1.
PerfectPortals v1.1 — Patch Notes
New Feature: Cross-Server Transfer
Portals can now transfer players to a different Hytale server. Perfect for hub networks — set up portal pads that send players from your hub to survival, factions, PvP, or any other server.
How it works:
Admin UI improvements:
- Open the admin UI with /pportals
- Select a portal (A) and click Server Config
- Enter the target server's host/IP, port (default 5520), an optional countdown (seconds before transfer, 0 = instant), and an optional display label
- Save — the portal is now in server mode
- When a player presses [F] on the portal, they see a title countdown and get transferred to the target server
- New SERVER section in the sidebar with "Server Config" and "Clear Server" buttons
- Portal list now shows label for server-mode portals instead of a link arrow
Technical details:
- Uses Hytale's native referToServer() API — no proxy needed
- Server mode and portal linking are mutually exclusive (setting one clears the other)
- Countdown uses EventTitleUtil for on-screen display + ScheduledExecutor for delayed transfer
- Double-trigger prevention: pressing [F] again during countdown cancels the previous transfer
- Fully backward compatible — existing portals.json files load without migration
