Exclude faction jail containers from object sync (#700) - #893
Merged
Merged
Conversation
miredirex
reviewed
Sep 19, 2026
|
|
||
| TESFullName fullname; | ||
| TESReactionForm reactionForm; | ||
| uint8_t crimeGoldMap[0x30]; // BSTHashMap<const TESNPC*, uint32_t> |
Collaborator
There was a problem hiding this comment.
Where did you get these types and offsets from? crimeGoldMap is a pointer to the map
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
force-pushed
the
fix/jail-inventory-sync
branch
from
September 19, 2026 19:48
26f62d5 to
0b29310
Compare
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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::OnCellChangeregistered 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 andOnAssignObjectsResponsereplaced 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 (
0x39CF1in Diplomatic Immunity and0x3EF03in 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 (TESDataHandlerfaction 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 inShouldSyncObject.How it was checked
SkyrimTogetherClientbuilds andTPTestspass on this branch (based ondev).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.