Parent: #20
Defect
D-C5/D-C6: creature and gameobject loot currently lives in a WorldSession::loot_table copy. Item storage and money persistence both cross async database boundaries before only the handling session updates its copy, so two eligible sessions can grant the same logical item or money pool.
C++ source of truth
src/server/game/Server/Protocol/Opcodes.cpp: loot handlers are PROCESS_THREADUNSAFE.
src/server/game/Server/WorldSession.cpp and World.cpp: thread-unsafe session work is admitted to the serialized world-session update.
src/server/game/Entities/Creature/Creature.h, GameObject/GameObject.h, and Loot/Loot.h: the world object owns one shared Loot plus per-player personal Loot.
src/server/game/Handlers/LootHandler.cpp and Entities/Player/Player.cpp: store validation precedes mutation; failed storage leaves loot available.
The previous D-C5 note that C++ marks the slot before storage is incorrect. Its safety comes from shared ownership plus serialized execution.
Rust targets
crates/wow-loot, wow-entities, and the loot packet re-export boundary
crates/wow-world/src/handlers/loot.rs
crates/wow-network/src/player_registry.rs
tools/wow-test-bot
- D-track status documentation
Acceptance
- Creature/GO loot has one shared authority; session loot tables are views only.
- Item and money claims use cancellation-safe reserve/commit/rollback without holding a world/map lock across await.
- Two sessions racing a normal shared item or money pool produce exactly one logical grant.
- FFA remains once per eligible player; personal loot remains independent per player; AE loot remains independent per owner.
- Inventory/DB failure and cancellation before persistence release the reservation; success cannot be reopened by timeout or stale generation cleanup.
- Master-loot and roll-winner remote delivery use the same claim boundary.
- Group money credits each connected eligible recipient once and persists before runtime/packet success.
- Corpse removal, respawn, and GO deactivation retire old authority without affecting a new generation.
- Focused concurrency tests, live two-bot smoke, single-session capture-diff, format/check/clippy, local preflight, CI, and current-HEAD Codex review are green.
Boundary
LOOT.2 gating, money gain modifiers/criteria, and the complete StoreLootItem side-effect cascade remain tracked by #55. Full world-session serialization and unrelated player-save atomicity remain separate work.
Refs #20.
Parent: #20
Defect
D-C5/D-C6: creature and gameobject loot currently lives in a
WorldSession::loot_tablecopy. Item storage and money persistence both cross async database boundaries before only the handling session updates its copy, so two eligible sessions can grant the same logical item or money pool.C++ source of truth
src/server/game/Server/Protocol/Opcodes.cpp: loot handlers arePROCESS_THREADUNSAFE.src/server/game/Server/WorldSession.cppandWorld.cpp: thread-unsafe session work is admitted to the serialized world-session update.src/server/game/Entities/Creature/Creature.h,GameObject/GameObject.h, andLoot/Loot.h: the world object owns one shared Loot plus per-player personal Loot.src/server/game/Handlers/LootHandler.cppandEntities/Player/Player.cpp: store validation precedes mutation; failed storage leaves loot available.The previous D-C5 note that C++ marks the slot before storage is incorrect. Its safety comes from shared ownership plus serialized execution.
Rust targets
crates/wow-loot,wow-entities, and the loot packet re-export boundarycrates/wow-world/src/handlers/loot.rscrates/wow-network/src/player_registry.rstools/wow-test-botAcceptance
Boundary
LOOT.2 gating, money gain modifiers/criteria, and the complete StoreLootItem side-effect cascade remain tracked by #55. Full world-session serialization and unrelated player-save atomicity remain separate work.
Refs #20.