Skip to content

Shared container storage and server-tracked dropped items - #926

Closed
gherman7755 wants to merge 2 commits into
tiltedphoques:devfrom
gherman7755:feat/shared-containers-and-dropped-items
Closed

gherman7755 wants to merge 2 commits into
tiltedphoques:devfrom
gherman7755:feat/shared-containers-and-dropped-items

Conversation

@gherman7755

Copy link
Copy Markdown

Problem

Two long-standing issues when playing together:

  1. Items stored in containers disappear. Container contents only lived on the server while someone was in the cell. Once everyone left, the entities were destroyed, and the next player to enter registered their own local copy as the truth. Items a guest stored were wiped as soon as the host (or anyone without them) entered first, and player home chests could not be shared at all.
  2. Dropped items are not visible to other players. Drop sync existed behind bEnableItemDrops but was off by default because each client created an unrelated copy, so a dropped item could be picked up once per player.

Changes

Containers (first commit)

  • Container entities are kept for the whole server session; only doors are still dropped when a cell empties.
  • Player home (NoResetZone) chests merge each player's local contents into the server state the first time that player sees them (Inventory::MergeMissing), and players already in the cell receive the added entries. bSyncPlayerHomes now defaults to true.
  • Server container inventories never store negative entries (AddOrRemoveEntryClamped).
  • Client object entities are deduplicated by form id and cleared on disconnect, so container inventory changes are no longer sent with a stale server id.

Dropped items (second commit)

  • New DroppedItemService on client and server, plus DropItemRequest/DropItemResponse, NotifyDroppedItems, NotifyDroppedItemRemoved, PickupDroppedItemRequest/PickupDroppedItemResponse.
  • The dropping client waits until the item comes to rest and reports its cell and position. The server assigns an id, sends it to players in range, and to players entering that area later.
  • Other clients place their copy at that position and map it to the server id (reusing a leftover local copy nearby, e.g. after reconnecting).
  • Pickups are arbitrated by the server: the first request wins, every other copy is removed, and a player who lost the race has the item removed again.
  • uMaxDroppedItems (default 1000) caps how many dropped items the server tracks. bEnableItemDrops now defaults to true.
  • The old Drop relay through NotifyInventoryChanges is no longer used; the item simply leaves the dropper's inventory there.
  • HookDropObject now passes an explicit location in front of local actors when the game provides none. Without it, single items dropped by the player sometimes landed near the world origin instead of in front of them.

Testing

  • TPTests pass, including new round-trip tests for the messages and tests for the merge/clamp helpers.
  • Tested in game with two players on Skyrim AE:
    • a guest stores items, leaves, and the host enters: items are still there;
    • shared chest in a player home: both players' items are kept;
    • single items and stacks dropped indoors and outdoors show up at the same spot for both players;
    • both players grabbing the same item: only one keeps it.

Notes / open points

  • Server state is in-memory only. After a server restart, the first player to enter a non-home cell still defines its container contents.
  • Containers outside player homes no longer respawn their loot while the server is running.
  • Existing STServer.ini files keep their old values for bEnableItemDrops / bSyncPlayerHomes.

Container inventories used to be dropped from the server as soon as the last
player left a cell. The next player to enter then registered their own local
copy as the truth, so items another player had stored were wiped, most
noticeably when the host entered after a guest had used a chest.

- Keep container entities alive for the whole server session, only doors are
  still dropped when a cell empties.
- Player home (NoResetZone) chests merge each player's local contents into the
  server state the first time that player sees them, and players already in
  the cell receive the added items. bSyncPlayerHomes now defaults to true.
- Never store negative entries in container inventories on the server.
- Client: dedupe object entities by form id and clear them on disconnect, so
  inventory changes are no longer sent with a stale server id and dropped.
Item drops were an opt-in experiment (bEnableItemDrops, off by default)
because every client created its own unrelated copy of a dropped item, so it
could be picked up once per player and duplicated.

Dropped items are now tracked by a new DroppedItemService on both sides:
- The dropping client waits for the item to come to rest and reports its
  cell and position; the server gives it an id and sends it to players in
  range, and to anyone entering that area later.
- Other clients place their copy at the same position and map it to the id.
- Pickups go through the server: the first request wins, everyone else's copy
  is removed, and a player who lost the race has the item taken back.
- uMaxDroppedItems caps how many dropped items the server remembers.
- bEnableItemDrops now defaults to true.

Also give the game an explicit drop location for local actors. Without one,
single items dropped by the player sometimes ended up near the world origin
instead of in front of them.

Adds encoding tests for the new messages and the container merge helpers.
@miredirex

Copy link
Copy Markdown
Collaborator

Hi. I'm already working on item drops #913

Please write PR descriptions by hand instead of using ai, and discuss submitting such big changes with the team first in our discord

@miredirex

Copy link
Copy Markdown
Collaborator

Sorry, closing for the following reasons:

  • overhauled item drops is already work-in-progress and is going to land in the upcoming ST update
  • "first-time contributor" working on a big feature without prior discussion
  • heavy AI use with no AI disclosure, plus an ai-written PR description

You're still welcome to contribute (and use AI too, we don't mind), just pick a small-scope task. We will soon have AGENTS.md that should help

@miredirex miredirex closed this Oct 14, 2026
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.

2 participants