OptiPortal

Hytale server optimization plugin that eliminates chunk loading lag on portal travel. Pre-loads destination chunks before teleports occur using a self-learning portal link registry and three-tier cache system (HOT/WARM/COLD).

File Details

OptiPortal-1.0.9.jar

  • R
  • Mar 20, 2026
  • 18.43 MB
  • 42
  • Early Access

File Name

OptiPortal-1.0.9.jar

Supported Versions

  • Early Access

[1.0.9] - 2026-03-20

Added

  • Vertical activation bound consistency: Proximity detection previously used a fixed vertical distance that didn't match the configurable setting, causing portals to behave inconsistently. Now it respects the configured vertical distance and per-zone overrides, ensuring portals trigger reliably from any height.
  • Asymmetric zone radius: Zone width and depth settings were saved but never actually used — all zones were forced into circles. Now zones can be rectangular, perfect for corridors and bridges, with automatic fallback to circular zones when not specified.
  • Portal link confidence threshold: Portal connections were saved after just one use, which could accidentally learn wrong links. Now connections require multiple confirmations (default: 3 uses) before being saved, and unconfirmed links automatically expire after a week of inactivity. Configurable via portalLinks.confidenceThreshold and portalLinks.pendingDecayDays.
  • TTL enforcement: Time-based expiration settings were stored but never actually removed old entries. A new cleanup process now automatically deletes expired entries like death locations and temporary zones every 24 hours (configurable), while protecting active zones from being deleted. Configurable via ttl.cleanupIntervalHours.
  • Native death hook: Death location tracking was completely inactive because it was waiting for an external plugin. Now it works natively with Hytale, so respawn screen preloading functions immediately without requiring any additional plugins.

Changed

  • /preload radius command now supports /preload radius <id> <X> [Z] syntax with backward-compatible Z omission (defaults to X when omitted).

Configuration

New config.json fields (all optional, defaults apply if absent):

  • portalLinks.confidenceThreshold — number of observations required to confirm a portal link (default: 3)
  • portalLinks.pendingDecayDays — days of idle time before pending links are purged (default: 7)
  • ttl.cleanupIntervalHours — interval in hours for TTL cleanup runs (default: 24)

[1.0.8] - 2026-03-20

  • Keepalive now active: The async keepalive manager was constructed but never started, meaning no HOT/WARM heartbeat pings fired since 1.0.4. Chunks owned via the dedup path (no direct pin) were relying on this for retention.
  • Gravestone integration restored: Due to initialization order, the gravestones plugin integration was always passed as null to the teleport interceptor, silently disabling death-location cache release even when the gravestones plugin was installed.
  • Warp file watcher portal cache callback restored on reload: After /preload reload, the warp file watcher was reconstructed without its portal cache invalidation callback, meaning warp changes no longer refreshed the proximity detection cache until server restart.
  • In-memory chunk fast-path: Chunks already resident in the engine's store are pinned and registered directly without a redundant async load call. Chunks mid-save are deferred until the save completes. Applies to both the base and enhanced preload pipelines.
  • Enhanced preload backoff guard: The enhanced chunk preloader now correctly skips chunks on failure backoff, matching existing behaviour in the base preloader. Previously broken positions were retried on every preload pass.
  • Preload backpressure: Chunk loading is suspended when JVM heap exceeds 80% (giving a 5% margin before the engine's own desperate-eviction threshold), and also when a world's live chunk count exceeds the configured pressure ceiling.
  • Ownership auditor fix: The periodic audit now correctly cross-references ownership records against the engine's chunk index, resolving an encoding mismatch that prevented it from ever detecting real evictions.
  • Async metrics accuracy: Chunk load success and error events were recorded twice per chunk in both the enhanced preload pipeline and keepalive pings (once by WorldThreadBridge with real latency, once by the caller with false 0ms duration). Duplicate calls removed.
  • RAM estimate storage efficiency: Zone RAM estimates were updated by calling storage.loadAll() once per chunk loaded — 121 calls for a radius-5 zone. Replaced with a targeted loadById() lookup.
  • BUG FIX — Warp sync no longer deletes portal zones and player data: The warp file watcher was deleting ALL storage entries not present in the warp file on every sync cycle (default every 30 seconds). This silently erased auto-registered portal destination zones, portal device zones, death location records, and respawn location records. The deletion loop now only removes entries of type PORTAL (warp entries).
  • BUG FIX — Portal link registry thread safety: The portal link registry used a plain HashMap accessed from multiple executor threads, allowing lost updates and ConcurrentModificationException under concurrent teleports. Replaced with ConcurrentHashMap and added synchronization to the compound read-modify-write methods.
  • BUG FIX — JSON storage backend thread safety: The JSON backend's in-memory entries map (LinkedHashMap) was read and mutated from multiple threads without synchronization, risking ConcurrentModificationException and lost writes. All five public read/write methods are now synchronized.
  • BUG FIX — Async keepalive enhancement never active: The enhanced keepalive implementation (load-balanced, batched via WorldThreadBridge) was silently bypassed because the base class method it intended to override was private. All keepalive pings were falling through to the base implementation. Method visibility corrected.
  • BUG FIX — Async teleport poll override never scheduled: The async teleport record polling override was never invoked by the scheduler for the same reason — private method in the base class. Base polling continued to function, but the enhanced batched path was dead code.
  • BUG FIX — Player disconnect leaked position tracking entries: On disconnect, the player's last-known-position and last-seen-teleport-nanos entries were not removed, leaving them to accumulate indefinitely. Both maps are now cleared on player removal.