Skip to content

Exclude faction jail containers from object sync (#700) - #893

Merged
miredirex merged 2 commits into
tiltedphoques:devfrom
sfedev:fix/jail-inventory-sync
Sep 19, 2026
Merged

miredirex merged 2 commits into
tiltedphoques:devfrom
sfedev:fix/jail-inventory-sync

Conversation

@sfedev

@sfedev sfedev commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Fixes #700

What was wrong

When a player is sent to jail, the game moves their whole inventory into the jail's prisoner belongings container (stolen goods go to the evidence chest) and hands it back when the sentence is served. Both are regular world containers, so ObjectService::OnCellChange registered them on the server with the first player's stash as their inventory. When a second party member entered the same jail cell, the server answered with that inventory and OnAssignObjectsResponse replaced the second player's local chest contents with the leader's items. On release, the game gave the second player the leader's belongings and their own were gone.

Example: leader and member both get arrested in Whiterun and serve their time. Before this change, the member walks out with the leader's inventory (except worn items). After it, each player gets their own items back.

Two quest chests (0x39CF1 in Diplomatic Immunity and 0x3EF03 in No One Escapes Cidhna Mine) were already excluded by hard-coded form ID for the same reason. As noted in the issue, that does not scale: every hold has its own jail chests, and mods add more.

What changes

Every faction that can arrest the player stores, in its crime data, the container that receives the player's inventory (PLCN) and the one that receives stolen goods (STOL). On cell change the client now walks the loaded factions (TESDataHandler faction array) and excludes those containers from object sync, so each client keeps its own copy and the game returns each player's own items. The check compares pointers only and never dereferences the crime data, so a layout mismatch cannot crash the client; it would just fall back to the previous behaviour for that faction.

The two hard-coded quest chests stay excluded because they are quest-owned containers, not faction jail containers.

  • Code/client/Games/Skyrim/Forms/TESFaction.h: crime data layout.
  • Code/client/Games/TES.h: faction form array in the data handler, with offset asserts.
  • Code/client/Services/Generic/ObjectService.cpp: collect the containers and exclude them in ShouldSyncObject.

How it was checked

  • SkyrimTogetherClient builds and TPTests pass on this branch (based on dev).
  • In-game verification with two arrested party members is still pending. Expected result: each player gets their own inventory back, and the client log shows Excluding sync for <chest id> for the prisoner belongings and evidence chests when entering the jail cell, while other containers in the cell keep syncing.

Limited to object sync exclusion; no changes to actor inventories, ownership transfer, protocol or quest logic.


TESFullName fullname;
TESReactionForm reactionForm;
uint8_t crimeGoldMap[0x30]; // BSTHashMap<const TESNPC*, uint32_t>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where did you get these types and offsets from? crimeGoldMap is a pointer to the map

sfedev and others added 2 commits September 19, 2026 22:47
When a player is sent to jail, the game moves their whole inventory into the
faction's prisoner belongings container and stolen goods into its evidence
chest. Both were synced like any other container, so the first player to enter
the jail cell registered their stash on the server and the next player's local
chest was overwritten with it; on release they walked out with someone else's
inventory.

Read the player inventory and stolen goods containers from every loaded
faction's crime data and exclude them from object sync, so each client keeps
its own copy. This replaces the need for per-chest hard-coded exclusions and
also covers jails added by mods. The two quest chests already excluded by form
ID stay as they are, since they are quest-owned rather than faction containers.

Verified: client builds, TPTests pass. In-game check with two arrested party
members pending.
@miredirex
miredirex force-pushed the fix/jail-inventory-sync branch from 26f62d5 to 0b29310 Compare September 19, 2026 19:48
@miredirex
miredirex merged commit 5966924 into tiltedphoques:dev Sep 19, 2026
3 checks passed
@miredirex miredirex mentioned this pull request Sep 20, 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.

Inventory glitch when thrown in jail

2 participants