Skip to content

fix: ensure chunk is loaded before placing death chest block - #101

Closed
wangzhizhou wants to merge 2 commits into
DevCyntrix:mainfrom
OrzMC:fix/chunk-load-before-chest-place
Closed

fix: ensure chunk is loaded before placing death chest block#101
wangzhizhou wants to merge 2 commits into
DevCyntrix:mainfrom
OrzMC:fix/chunk-load-before-chest-place

Conversation

@wangzhizhou

Copy link
Copy Markdown

Problem

When a player disconnects immediately after dying (e.g. server lag, accidental quit, or death while logging out), the death chest is never created and all items are lost forever.

Root cause

BlockCreationChestListener.onCreate() schedules the actual setType(CHEST) call on the next tick via runTask() (intentionally, to avoid the chest being destroyed by a delayed explosion when sleeping in the nether).

Meanwhile, SpawnChestListener.onDeath() clears event.getDrops() synchronously in the same death event.

If the player disconnects between these two moments:

  1. Drops are already cleared (items gone from the world)
  2. On the next tick, the chunk containing the death location is unloaded (no players nearby), so location.getBlock().setType(CHEST) writes to an unloaded chunk and is silently discarded
  3. Result: no chest, no drops → items permanently lost

Fix

In BlockCreationChestListener.onCreate(), before placing the chest block:

  • Check if the chunk is loaded; if not, force-load it via world.getChunkAt(chunkX, chunkZ)
  • If it still isn't loaded (async load), retry every tick for up to 40 ticks (2 seconds)
  • Only then place the block

This preserves the original next-tick delay (nether explosion protection) while guaranteeing the block lands on a loaded chunk.

Verification

On a Paper 26.2 test server, the repro is: give items → /minecraft:kill → disconnect within 2s → check chest at death location.

Scenario Before fix After fix
Death + immediate disconnect ❌ No chest, items lost ✅ Chest created, items intact
Death while staying online ✅ Chest created ✅ Chest created (no regression)

8/8 repeated disconnect-on-death runs passed with the fix (100% chest creation, 0 item loss), vs 100% failure before.

Also added a debug log line with the chest location to confirm placement.

Death chest block was placed on a possibly unloaded chunk when the player
disconnected right after dying, silently discarding the block change and
causing items (already cleared from the world) to be lost forever.

Now we force-load the chunk (with retry up to 40 ticks) before setType(CHEST).
@wangzhizhou

Copy link
Copy Markdown
Author

Found a Bug And Fixed it, please review this PR, maybe this plugin can be publish on hangar or modrinth platform, and make more people can see it.

During server startup, expired chests are loaded and their expiration
tasks run before (or racing with) the model being added to the loaded
cache, causing loadedChests.remove() to return null and throwing
IllegalArgumentException 'Invalid model'.

Now we return silently instead - destroying a chest is idempotent.
@wangzhizhou

Copy link
Copy Markdown
Author

Additional fix (commit 3572396): destroyChest idempotency

Second issue found during full regression: on server startup, expired chests get loaded and their expiration tasks run racing with the model being added to the loaded cache. loadedChests.remove() then returns null and destroyChest throws IllegalArgumentException: Invalid model (one WARN per restart).

Fix: return silently when the model is no longer in the cache — destroying a chest is idempotent. Verified: 2 consecutive restarts with 11 expired chests → 0 exceptions (was 1/1 before).

@wangzhizhou

Copy link
Copy Markdown
Author

Superseded by #102 (#102) which contains the complete fix set (chunk load before chest placement + idempotent destroyChest) from the fork's main branch. Closing this duplicate to keep the review focused on a single PR.

@wangzhizhou wangzhizhou closed this Aug 5, 2026
@wangzhizhou
wangzhizhou deleted the fix/chunk-load-before-chest-place branch August 5, 2026 05:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant