Hytale Stable-5 Migration
All Glymera plugins updated for Hytale Server 0.5.x (Stable 5)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
All Glymera plugins have been updated for compatibility with Hytale Server 0.5.x (Stable 5). The previous versions targeted Hytale Server 0.4.x (Stable 4).
This document covers what changed in the Hytale Server API between Stable 4 and Stable 5, and which adjustments were required across plugins so that things keep working.
◆ Why a new major version
Stable 5 introduced a number of source-incompatible API changes. A plugin compiled against Stable 4 will either fail to load, fail silently on first use, or — in a few cases — crash the world thread. Because the surface of change is large, every plugin received a new major version number, even when the only functional behaviour change was a manifest flag.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
◆ What changed in Hytale Stable 5
▸ Vector math
- Internal Hytale vector types were replaced by JOML.
- com.hypixel.hytale.math.vector.Vector3d/3i/3f → org.joml.Vector3d/3i/3f
- Rotation helpers now use the Rotation3fc interface where the older API took a concrete Rotation3f.
▸ Particle / Sound API
- SpawnParticleSystem constructors gained additional arguments.
- PlaySoundEvent3D / ambient sound registration semantics tightened — long-running or looped sounds attached to a block must now use the block-state AmbientSoundEventId path; firing them with PlaySoundEvent3D from a tick handler no longer behaves correctly.
▸ Asset pack registration
- AssetModule.registerPack(...) now requires a PackSource parameter (use PackSource.MODS for plugin-installed packs).
- The IncludesAssetPack manifest flag is now strictly enforced. If a plugin both declares IncludesAssetPack: true and registers a runtime pack from its setup code, Hytale detects this as a duplicate registration and aborts boot with "Duplicate asset pack ... Remove the duplicate." For affected plugins IncludesAssetPack is now set to false; the actual asset pack is installed by the plugin at startup as before.
▸ HUD / UI system
- The HudManager API has moved to a keyed model — HUD entries now require a stable key and explicit lifecycle hooks.
- InteractiveCustomUIPage event bindings are wiped if the page is rebuilt while the client is processing a click. Plugins refreshing a HUD per tick had to throttle the rebuild rate (commonly to 1 Hz) so button presses are not lost.
▸ Player handles
- The Player component and the PlayerRef reference have been split. Plugins previously juggling one or the other now need to consider both.
- ServerPlayerListPlayer requires a worldUuid field — entries without it are silently dropped from the tab list.
▸ Entity utilities
- EntityUtils.toHolder(...) was removed. Lookups need to go through the entity store directly or via Ref<EntityStore>.
▸ Damage system
- Resistance fields on EntityEffect (damageResistanceValuesRaw, damageResistanceValues) now expect ResistanceModifier[], not StaticModifier[]. Plugins that previously injected resistances via reflection now use the ResistanceModifier(ResistanceCalculationType, float) constructor.
- The corresponding JSON CalculationType value "Multiplicative" is no longer accepted for damage resistance — it must be "Percent". Migrating large packs needed a bulk rewrite of Potion/Effect JSONs.
- Lethal-damage detection: EntityStatValue#getMin() is no longer a usable death-threshold. Lethal checks now compare the post-damage health against 0.0f directly. Plugins relying on the old behaviour would silently fail to fire and the player just died.
▸ ECS / system tick safety
- It is no longer legal to call mutating store methods (addComponent, removeEntity, …) directly from inside a system's tick handler. Doing so now throws IllegalStateException: Store is currently processing! Such calls must be deferred: either via the system's CommandBuffer, or by scheduling onto the next world tick with world.execute(...).
▸ Items, weapons and recipes
- Custom swords must declare Tags.Type: "Weapon" (not "Tool"), and they need their own complete InteractionVars block — these are no longer inherited from the parent template under Stable 5. A custom weapon without its own InteractionVars will spawn but cannot deal damage.
- Recipe bench IDs and recipe categories are now validated against the asset registry. Mistyped values cause Hytale to silently drop the recipe with no error message.
▸ Cosmetics
- CosmeticsToHide now only accepts a restricted, enumerated set of values. Custom values are rejected at asset-load time.
▸ Server authentication
After every Stable update the server's OAuth credentials must be refreshed:
If the server is still on cached OAUTH_STORE credentials after a Stable update, every incoming player connection is rejected with serverAuthUnavailable and the client only sees "QUIC handshake failed".
- auth logout
- auth login device
- Open the printed verification URL, complete the device authorisation
- auth select <profile>
▸ Manifest / ServerVersion
- Stable 5 enforces a recognisable ServerVersion declaration in each plugin's manifest.json. A malformed value prevents the server from booting. Glymera plugins declare "ServerVersion": "*" to remain agnostic across patch versions.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
◆ Plugin-data path
The plugin-data directory used by all Glymera plugins is now:
mods/de.glymera_<PluginName>/
(Previously it wasplugins/<PluginName>/.) Existing configuration files are not migrated automatically — if you want to keep custom configuration from an older install, move the relevant files from the old plugins/ location into the new one before first launch.
GlymeraFloatingIslands - Changelog
v5.0.0 (2026-04-17)
Bug Fixes
- Restart bug fixed: After a server restart, newly-to-be-generated chunks stopped being rendered as islands. Chunks already saved on disk stayed fine, but walking into unexplored territory produced flat normal terrain. Root cause: worldConfig.getWorldGenProvider().getGenerator() is a factory that returns a brand new ChunkGenerator instance on every call. The v4 approach of fetching and patching once modified short-lived objects that Hytale immediately discarded.
- Teleport crash fixed: Teleporting into a freshly-created island world could occasionally fail with RejectedExecutionException and disconnect the player. Root cause: applyIslandBiome was being invoked twice, and the second setGenerator() call shut down the ThreadPool of the previous generator while it was still generating chunks.
Changes
- Idempotent on-demand generator patching: New method ensurePatched(world, def) replaces the old "patch once" flow. Called from four entry points and decides for itself whether patching is required. Reads the generator currently in use, skips in O(1) via identity hash if already patched, otherwise patches in place via reflection without killing any ThreadPool.
- Integration in chunk post-processor: The ChunkPreLoadProcessEvent handler calls ensurePatched before its block-clear pass. If Hytale swaps in a fresh generator between the AddWorldEvent patch and actual chunk generation, this new generator is intercepted and patched before a single chunk is generated incorrectly.
- Diagnostic logging: All log lines prefixed [FI-v5] for easy filtering. Exceptions now logged with full stack trace.
No Functional Changes
All commands, config format, preset list, and island shape are identical to v4.
Compatibility
- Existing v4 worlds work without any further action
- Plugin can be swapped in-place by replacing the JAR and restarting — no world regeneration required
v4.0.0 (2026-04-16)
Bug Fixes
- Player-edit loss fixed: In v3 the chunk post-processor cleared blocks outside the island Y-range on every chunk load — including chunks loaded from disk. Player-built structures outside the Y-range disappeared on chunk reload. Fix: clear logic now only runs on freshly generated chunks.
v3.0.0 (2026-04-16)
- Switched to custom IHeightThresholdInterpreter with direct 3D Simplex noise evaluation
- No more carving or post-fill logic — Hytale generates islands natively through the biome pipeline
- Covers (grass/flowers/trees), environments (NPCs/animals) and prefabs (structures) preserved natively
- Spawn-platform guarantee: 5x5x3 solid blocks at world origin
- Cave deactivation: stalactites no longer dangle in empty air
- /fi biomes command for preset overview
- Native prefab Y-range bounding
v2.0.0 (2026-04-15)
- Removed custom zone system, switched to per-biome reflection
- Asymmetric vertical taper (no rock debris dangling at bottom)
- Fast path: column-level skip when all Y-samples below cutoff
- Per-world offset seed so different worlds with identical parameters look different
v1.0.0 (2026-04-15)
- Initial release: floating-island worlds via /fi create <name> <biome>
- 6 biome presets: native, grasslands, desert, snow, volcanic, crystal
- 3D-Simplex-noise based island shape (configurable size, density, height range)
- Persistent worlds via JSON config
- /fi create|tp|back|list|delete|biomes|reload commands
- No asset pack, JAR under 30 KB
