Files
Pumpkin/pumpkin-nbt/Cargo.toml
TheDarkSword e480f32265 fix(pumpkin): stop entities from duplicating on chunk reload (#2342)
* fix(pumpkin): stop entities from duplicating on chunk reload

Entities lived in two places at once: the live World::entities list and the
serialized NBT in the entity chunk's data. On load the saved NBT was turned
into live entities but never cleared, and on unload each live entity was
appended back onto that still-populated list - so the persisted entity count
doubled every load/unload (reconnect) cycle. Freshly spawned entities hit the
same trap: add_entity_silent pushed their NBT into the chunk immediately, so
they were both live and serialized, doubling on the first unload too.

Make the live entity the single source of truth, matching vanilla:
- on load, take (clear) the chunk's serialized entities as they become live,
  and restore their persisted UUID so they keep their identity;
- a second watcher of an already-loaded chunk is sent spawn packets built from
  the live entities, not the stale NBT;
- entities are serialized fresh, from their current live state, only when their
  chunk unloads (save_entity);
- add_entity_silent no longer serializes on spawn.

Because the live entity is serialized fresh on unload, any change made to it
while loaded (health, effects, ...) is persisted automatically, without having
to be written back to the chunk data by hand.

* Move UUID int-array NBT helpers into pumpkin-nbt

Review feedback: the UUID read helper doesn't belong in world/mod.rs.
NbtCompound now has put_uuid/get_uuid for the vanilla 4-int-array
layout, used by both Entity::write_nbt and the entity chunk loader.
Serialized bytes are unchanged.
2026-07-11 18:59:37 +02:00

30 lines
542 B
TOML

[package]
name = "pumpkin-nbt"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
[dependencies]
pumpkin-codecs.workspace = true
serde.workspace = true
thiserror.workspace = true
bytes.workspace = true
uuid.workspace = true
cesu8.workspace = true
flate2.workspace = true
tracing.workspace = true
[dev-dependencies]
tempfile.workspace = true
criterion.workspace = true
serde = { version = "1.0", features = ["derive"] }
[[bench]]
name = "nbt"
harness = false
[lints]
workspace = true