
ChestShare
Per-player loot in every world-generated chest, 100% server-side. Can even restore chests that were looted before you installed it.
- Загрузки
- 52
- Подписчики
- 0
- Обновлён
- 10 июля 2026 г.
- Лицензия
- MIT
Опубликован 3 июля 2026 г.
ChestShare
Summary
Per-player loot in every world-generated chest — 100% server-side. Can even restore chests that were looted before you installed it.
Description
Every player gets the dungeon chest. Not just the first one.
On a survival server, the first player to find a structure empties it. Everyone after them explores a looted world. ChestShare gives each player their own instance of every world-generated container — same seed, same loot, nobody left out.
And it's 100% server-side: drop one jar in mods/, done. No client install, works with vanilla clients, launcher-locked modpack players, and cracked-open modpacks alike.
What it does
- Per-player loot instances — chests, trapped chests, barrels, shulkers, dispensers, chest minecarts, and modded containers built on vanilla mechanics. Two players opening the same dungeon chest see the exact same items, each in their own copy.
- Deposit friendly — players can take and stash items in their instance; everything persists with the world.
- Mod-generated structures included — containers are captured at chunk generation, whether they use a loot table or were pre-filled with custom modded items (full NBT).
- No exploits — hoppers and pipes can't touch shared containers; breaking one drops only the breaker's own instance; player-placed chests keep vanilla behavior, always.
- Double chests, done right — combined 54-slot screen, each half tracked separately.
Installed the mod too late? We did too.
ChestShare was born on a live Cobblemon (COBBLEVERSE) server where players had already explored and emptied chests across the whole map. Vanilla deletes a chest's loot table the moment it's opened — that information is gone from the world forever.
But world generation is deterministic. So ChestShare ships a recovery workflow:
- Copy your server setup (same mods, same seed), delete the world copy.
- Pre-generate the explored area on that mirror (Chunky works great) — ChestShare captures every container as it generates.
/chestshare export recoveryon the mirror./chestshare import recoveryon your real server: every chest still standing — including the ones already looted — becomes a shared container with its original loot.
The import runs spread across server ticks (no freeze, no watchdog kill) and skips non-empty containers by default so it never eats player storage. On our server: 332 containers exported from the mirror, 241 restored in one command, zero downtime beyond a restart.
Commands (op level 2)
| Command | Effect |
|---|---|
/chestshare convert <pos> <loot_table> |
Convert one container (e.g. a chest looted pre-mod) into a shared container |
/chestshare reset <pos> |
Wipe player instances — loot regenerates for everyone |
/chestshare export <file> |
Export all captured containers to a file |
/chestshare import <file> [force] |
Apply an export to this world (recovery) |
Good to know
- Fabric, Minecraft 1.21.1, Java 21. Requires Fabric API. Server-side only (also works in singleplayer/LAN).
- Chunks generated before install: unopened containers still convert automatically on first open (their loot table is intact); already-looted ones need the recovery workflow above.
- Fully custom container implementations (not based on vanilla loot mechanics) aren't covered.
- Cosmetic: no chest lid animation on shared containers (server-side trade-off).
Ченджлог
0.2.3Релиз1.21.1 · 10 июля 2026 г.
Fixed
- Import chunks are held non-ticking (border level 33), not ticking (level 32) - The async import pinned each in-flight chunk at the block-ticking level, so over a large import (tens of thousands of chunks) ticking chunks accumulated faster than they unloaded: server tick cost inflated until a watchdog crash in the vanilla spawn loop (
SpawnHelperviatickChunks), and entities in those far-away ticking chunks ticked with no player nearby (mass NPC/trainer despawn). Chunks are now held at the border level (33), which gives full block-entity access — enough to read and convert containers — with none of the ticking:shouldTickBlocks(33)andshouldTickEntities(33)are both false. No more tick-cost accumulation or watchdog at scale, and no more far-away entity ticking during imports. - Import pauses chunk admission under memory pressure (heap gate) and orders the chunk queue spatially - Import-loaded chunks stay resident in memory until vanilla's throttled unloading drains them (vanilla only unloads a quota per tick). On a large import, generation outran unloading, so resident chunks grew without bound until the heap was exhausted — an
OutOfMemoryErrorat scale (bench: OOM after ~7 min at parallelism 8 on a 6 GiB heap; production showed the same slope, 17 GiB after 2h45 even at parallelism 1). The import captures a per-world baseline of the loaded-chunk count at start (ServerChunkManager.getLoadedChunkCount(), the current holder-map size) and stops enqueuing new chunks for a world whenever its loaded count sits more than 384 chunks above that baseline. But that counter is blind to the proto-chunk neighborhood the generation pipeline holds: each target chunk (border level 33) forces generation of a neighborhood of lower-status proto-chunks (up to ~17×17 per target) that never appear in the full-chunk holder map — a second bench (78,915 positions, parallelism 8, 6 GiB heap, c2me) OOM'd with 9,416 chunks still pending and zero hits on the count gate. Two additions close that gap: (1) a heap gate that also pauses admission whenever free heap drops below 20 % of max heap — measuring the actual constraint (the heap) rather than a blind proxy; and (2) spatial ordering of the chunk queue per dimension by locality (region-major then position,(chunkX >> 5, chunkZ >> 5, chunkX, chunkZ); plain row-major within a region, no Hilbert curve needed) so consecutive targets share generation neighborhoods — scattered admissions each pay a full ~17×17 proto-chunk neighborhood, whereas sorted admissions reuse neighbors, cutting both peak memory and total generation work. The pause log line now names which gate fired (heap vs chunks); everything else keeps running (in-flight ticket refresh, polling, processing, timeouts) — this throttles admission only. An INFO line is logged at most once per 30 s while admission is paused.
Changed
- Already-registered positions are pre-skipped without loading their chunk - At import start, every position already present in the shared-container state is counted as "already shared" up front and its chunk is never queued. Re-running an import after an interrupted run now only loads the chunks of the remaining tail instead of every chunk in the export — near-instant resumes. The "Import started" line reports the pre-skipped count.
0.2.1Релиз1.21.1 · 3 июля 2026 г.
Changed
- Async import -
/chestshare import <file> [force]now processes positions via vanilla's asynchronous chunk loading. Positions are grouped by chunk and requested with worldgen tickets, so terrain generation runs on the worldgen worker threads instead of the server thread. The import no longer causes TPS drops — even across large stretches of ungenerated terrain — and runs fully in the background. Command syntax, single-active-job guard, and the final summary format are unchanged.
Fixed
- c2me compatibility (import watchdog crash) - On modpacks bundling c2me, the async import could block the server thread and trigger the watchdog. c2me wraps
ServerChunkManager.getChunkinto a blocking path that awaits chunk generation on the main thread; the import's per-tick poll called that method, so each in-flight chunk was awaited synchronously — causing massive tick lag and a watchdog crash. The import now polls chunk holders directly (getChunkHolder+ChunkHolder.getWorldChunk(), both non-blocking vanilla internals that c2me does not wrap) and never callsgetChunk. As defense in depth, each tick self-limits its import work to 5 ms, capping the worst-case contribution to tick time even if an unexpected call path were to block.
0.1.0Релиз1.21.1 · 3 июля 2026 г.
First release. Server-side only — nothing to install on clients, works with vanilla players.
Added
- Per-player instanced loot containers - Every world-generated container (chests, trapped chests, barrels, shulkers, dispensers, chest/hopper minecarts, and modded containers built on vanilla mechanics) gives each player their own copy of the loot. Same seed for everyone: two players opening the same dungeon chest see the exact same items, each in their own instance.
- Capture at chunk generation - Containers are registered the moment their chunk generates, whether they carry a loot table or were pre-filled with items by a mod (full NBT serialization, custom modded items included).
- Deposit support - Players can take and store items in their own instance; everything is persisted with the world.
- Automation blocked - Hoppers and pipes can neither extract from nor insert into shared containers.
- Natural breaking - Breaking a shared container drops the breaker's own instance and removes the container for everyone. Player-placed chests are never touched and keep vanilla behavior — including when placed where a shared container was destroyed (duplication-safe).
- Double chest support - Combined 54-slot screen, each half instanced and persisted separately.
- Admin commands (op level 2) -
/chestshare convert <pos> <loot_table>restores a single already-looted chest;/chestshare reset <pos>regenerates loot for all players. - Mass recovery for existing servers -
/chestshare export <file>and/chestshare import <file> [force]: regenerate a mirror copy of your world from the same seed, export every captured container, and import on the live server to restore chests that were looted before the mod was installed. The import runs progressively across server ticks (no freeze, watchdog-safe) and skips non-empty containers by default to protect player storage.
Notes
- Validated end-to-end on a live COBBLEVERSE (Cobblemon, Minecraft 1.21.1) server: 332 containers exported from a regenerated mirror, 241 restored on the origin server, non-empty containers preserved, no server stall.
Комментарии
Загружаем…