Subobject Replication - Inventory System - Invalid items when originator is destroyed

I’m having trouble with replicated subobjects for an inventory system, and these results are very concerning. Hopefully someone can shed some light here:

  • Two actors (A and B) with “ItemContainer” actor components
  • ItemContainers are just replicated TArray of pointers to replicated UObjects.
  • Adding / removing items to these arrays renames (to change the outer) and appropriately assigns subobject list replication.
  • Renames are also sent to the client (to change the outer on the client)
  • Moving an item from A → B works fine, the subobject is networked.
  • After some delay I destroy actor A.
  • Checking slightly later in B, the array still contains a pointer to the object, but the pointer to the subobject is now invalid. It becomes invalid instantly after A was destroyed by the server.

So I guess that means only the original networked pointer is meaningful on the client? Am I doing something wrong here? This seems to make working with replicated subobjects completely useless if we’re expecting them to act independently of their original replicating owner. Seems like a pretty obvious way to implement an inventory system would be to use subobject replication in this way.

im not sure if thats normal behaviour, i think it is but one way around this would be to have an itemmanager where every item in the game is created and stored and then your actors just reference their item on that manager

that wouldn’t work, and I think I’ve figured out why:

It appears that RemoveReplicatedSubObject actually invalidates networked object, so if you’re passing around UObjects for use, you should use TearOffReplicatedSubObjectOnRemotePeers instead. Even if you keep valid networked pointers to objects, they will become invalid upon calling RemoveReplicatedSubObject!

that is not a bug, it is what the ownership of a subobject means. a replicated subobject takes its network identity from the actor that registered it, so when actor A dies the client copy of the object dies with it and the pointer left in B is dangling. your last reply found the right escape hatch, TearOffReplicatedSubObjectOnRemotePeers instead of RemoveReplicatedSubObject, but you are still tying the items lifetime to A.

the pattern that scales is giving shared items a home that outlives the actors, a manager actor or the game state that owns every item, and letting the containers hold references to those items instead of owning them. then destroying A does not touch the item at all.

blueprint object replication from fab is a UObject replication plugin that keeps a stable id per object and gives you tear off and unregister at runtime, so a container can look the item up again by id after its host actor drops out of relevancy. ue5.0 to 5.8.

btw i used blueprint object replication from fab https://www.fab.com/listings/e26dcf07-7c78-4e67-8e56-272cf6df8021 it worked for me