File Details
GlymeraMegaChest-5.0.0.jar
- R
- May 23, 2026
- 84.33 KB
- 131
- Early Access
File Name
GlymeraMegaChest-5.0.0.jar
Supported Versions
- Early Access
GlymeraMegaChest - Changelog
v5.0.0 (2026-05-23)
Single-issue release fixing a Windows-specific Network Chest persistence bug reported by BottenRastrd on 2026-05-23.
Network Chests are now persisted on Windows hosts
BottenRastrd reported that under v4 on his (Windows) installation:
"I place a network chest (or multiple chests) and they work as intended. If I save the game, return to the main menu, and reload the game the chest cannot be opened. Additionally, if you break the chest (which shouldn't be possible if it has items inside), it disappears and doesn't go into your inventory. There are no JSON files being written at all in the 'network' folder. I also tried using the regular mega chest and everything seems to be working as intended."
Three symptoms, one root cause.
Root cause. Network pools were keyed by id "net:" + ownerUuid and that id was used directly as the on-disk filename (plugins/GlymeraMegaChest/network/net:<owner-uuid>.json). The colon is legal on Linux/ext4 — so every internal test passed against the Linux dev server — but on NTFS the colon is reserved for alternate data streams. FileOutputStream of net:<uuid>.json.tmp raises IOException on Windows, which saveChest catches and silently returns from. Nothing ever made it to disk. Because the in-memory chests map still held the pool until restart, the chest looked fine until the player quit; on the next load, no JSON to read → no entry in posToChest → MegaChestUseBlockSystem returned without opening the plugin UI, and MegaChestBreakBlockSystem + MegaChestDamageBlockSystem no longer matched the block, so vanilla Hytale break handling kicked in with "DropList": "Empty" — block and contents vanished without a trace. Standard Mega Chests were unaffected because their id is a plain UUID.randomUUID().toString() with no colon.
Fix. Pool id prefix changed from "net:" to "net_" (single character, single source-of-truth constant NETWORK_ID_PREFIX). The underscore is legal on every filesystem the plugin can plausibly run on. saveChest, deleteChestFile, and loadChests all derive the filename from c.id so no other code-paths needed changes.
Migration. Linux servers that ran v3 or v4 already have net:<uuid>.json files on disk. loadChests now detects the legacy prefix at startup, rewrites c.id in memory, and atomically renames the file to net_<uuid>.json (via Files.move). The rename is one-shot and idempotent; once renamed, subsequent loads see only the new prefix and no work is done. If the rename fails (e.g. permission denied), the in-memory id is still corrected and the next saveChest writes a fresh file under the new name. Customers on Windows had no v4 network files at all (the bug we are fixing), so there is nothing to migrate there.
Verified on the Linux dev server: the two pre-existing net:<uuid>.json files were renamed cleanly to net_<uuid>.json on first start, all in-world Network Chests remain openable, and the bug-trigger sequence (place → quit → reload) is exercisable by anyone wanting to repro on Windows.
Compatibility
- v4 data on Linux migrates automatically on first start. No manual file rename required.
- v4 data on Windows is empty by definition — nothing to migrate.
- No save-format change beyond the id-prefix swap. The chest contents (
items,positions, etc.) are byte-identical. - All in-world placed chests and the per-owner network pool are entirely preserved.
v4.0.0 (2026-05-16)
This release rolls up everything addressed from the v3.0.0 CurseForge bug-report thread (BottenRastrd 2026-05-12, Walomart 2026-05-06): a crash-safe persistence rewrite, a header-bar UI fix, an impossible-to-craft recipe corrected, and a deliberate "no" to workbench-pulls-from-chest integration. All four were verified in-game against the live Dev server before release.
1. Persistence: chests no longer lose contents after a hard kill
BottenRastrd reported that previously-placed Network Chests became unopenable after quitting to the main menu and returning, with the net files in the network/ folder showing 0 bytes in VS Code. Standard Mega Chests showed the same symptom under restart pressure.
Root cause. v3 saved each chest with:
try (FileWriter w = new FileWriter(f)) { gson.toJson(c, w); }
FileWriter truncates the target file to zero bytes the moment it is opened, before gson writes anything. If anything went wrong between that truncate and the final stream close — JVM kill (SIGKILL), ConcurrentModificationException on c.items while gson was streaming, an I/O error, OOM during serialization — the target JSON file was left empty on disk. The next load saw a 0-byte file and silently discarded the chest (catch (Exception e) { /* skip bad file */ }). Network Chests were more exposed than standard ones because a single per-owner pool means every item movement touches the same JSON file, multiplying the contention window.
Fix. saveChest was rewritten as an atomic four-step:
- Serialise the chest to a
Stringundersynchronized (c). AConcurrentModificationExceptionmid-serialisation now aborts the save and leaves the previous good copy on disk untouched, rather than corrupting it. - Write the bytes to a sibling
<id>.json.tmp. FileOutputStream.getFD().sync()to flush OS buffers to the disk.Files.move(tmp, target, ATOMIC_MOVE, REPLACE_EXISTING)— POSIX-atomic rename. The target points either at the previous good copy or at the new complete copy at every instant, never at a half-written file. Safe even if the JVM is killed between steps 3 and 4 (the.tmpis left behind for the recovery path below).
loadChests now self-recovers: if a target <id>.json is missing or unparsable, the loader looks for a sibling <id>.json.tmp and, if it parses cleanly, promotes it to the target (atomic rename again). This safety net catches the rare case where SIGKILL lands between fsync and rename, and also recovers leftover .tmp siblings from older crashes.
saveConfig was deliberately left on the old pattern. Config is written rarely (plugin startup + reload command); only the per-chest hot path was actually exposed.
Verified with a deliberate SIGKILL test against a populated v4 server: chests/network folders had no 0-byte files, no leftover .tmp siblings, and every item placed before the kill was still in-game after restart.
2. UI: trailing >-button stays inside the container
Walomart reported the UI buttons being "out of GUI". A screenshot confirmed that the pagination >-button on MegaChestPage extended roughly halfway past the right edge of the visible container.
Root cause. MegaChestPage.ui #HeaderBar uses LayoutMode: Left with a FlexWeight: 1 search container in the middle and three fixed-width nav elements after it (<, page label, >). Hytale's flex algorithm sizes the FlexWeight element from the remaining space without reserving a right-edge buffer for the trailing fixed widths, so the last element gets pushed past the container's inner edge.
Fix. #HeaderBar padding extended from (Bottom: 4) to (Bottom: 4, Right: 16). The 16-pixel right pad stops the Left-layout flow early enough that the trailing > stays inside the container.
MegaChestDepositPage.ui does not need the same treatment — it has three fixed-width buttons and no FlexWeight middle, so nothing was being pushed past the edge.
3. Network Chest recipe is finally satisfiable
BottenRastrd: "How am I supposed to get this? I make two small ones, place them next to each other to make a Large one, break the large one, and have two small chests again."
He was right. The v3 recipe required Furniture_Temple_Light_Chest_Large as an input, but that item does not exist as an inventory item. Its JSON lives under Server/Item/Items/Furniture/Temple_Light/Unique/ — a Hytale convention for connected-block states. It has no Recipe field, breaking it returns two small chests rather than itself, and "Variant": true marks it as a state variant of the small block under ConnectedBlockRuleSet. No player could ever satisfy the v3 recipe.
Fix. Recipe ingredient changed from Furniture_Temple_Light_Chest_Large × 1 to Furniture_Temple_Light_Chest_Small × 2. Bench requirement (Alchemybench / Alchemy_Potions) and the 3× Ingredient_Life_Essence_Concentrated co-input are unchanged. Costs roughly the same raw materials as the dead-end v3 recipe (2× small chests = 6× Marble + 2× Shale, plus the 3× concentrated Life Essence). Matches the player's intuitive "two small = one large" expectation and keeps the visual/thematic tie to the Temple Light family.
The recipe definition lives in assets/Server/Item/Items/Furniture/Glymera/GlymeraMegaChestNetwork_Block.json. No Java change beyond the version-bump header.
4. Workbenches reading from MegaChest is intentionally not added
BottenRastrd asked: "The workbenches don't 'see' what is in the network chest. Is this intentional?"
Yes, by design — and after looking into what it would take to change that, we are explicitly keeping it that way.
Native Hytale crafting benches pick up nearby item containers via CraftingManager.getContainersAroundBench, which queries a spatial index of blocks that declare BlockEntity.Components.ItemContainerBlock in their JSON. We could add that component to the MegaChest blocks and have the benches see something — but that "something" would be a parallel 36-slot native container sitting next to the plugin's own 1080-slot JSON-backed storage. Players would put iron into our UI, the workbench would not see it; players would put gold into the native container via some external means, our UI would not see it. The two storages would not be synchronisable without a fragile sync layer.