the Sim Settlements forums!

Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

LinkedRefs Warning, RE: Scrapping

kinggath

Well-Known Member
Staff member
Administrator
Moderator
Verified Builder
Messages
3,878
I love LinkedRefs, they are an incredibly powerful feature that lets you tie items together without causing them to be kept in memory perpetually (though they can still cause persistence - I will likely write up another exhaustive guide about LinkedRefs in the future, as well as one on persistence).

One thing I literally just learned tonight, is that when an item is scrapped in Workshop mode by the player, and those items are also linked via WorkshopStackedItemParentKeyword, ALL LinkedRefs to it are pseudo-severed. I say pseudo, because they only appear to be severed in one direction.

Let's say you link two items together:

Code:
kSomeRef.SetLinkedRef(kSomeOtherRef, MyKeyword)

And those items were also linked via WorkshopStackedItemParentKeyword (that keyword is a special one that allows those items to move together in workshop mode - think about when you pick up a rug and the things on top move with it) and then the player scraps kSomeOtherRef.

If you were to check kSomeOtherRef for GetLinkedRefChildren(MyKeyword), you'd expect it to return kSomeRef, instead it will return nothing. If you were to then check kSomeRef.GetLinkedRef(MyKeyword), you will correctly get back kSomeOtherRef. So it appears to only half break the links.

This is likely a bug in the way linked refs are cut by scrapping, but it's interesting to know - and even important to know if you are expecting to use linkrefs as a way to do some cleanup work after an object is scrapped.


In fact, this is likely the reason Sim Settlements can sometimes leave items behind, and a good reason for me to go do some more bug hunting!
 
Last edited:

1000101

Lurking in the bushes
Verified Builder
Messages
104
I think your assumption is wrong based on the order of events you describe and your expected results.

Regardless of whether an object is "physically linked" (linked ref) to another one, unless the other object held the deleted reference in a script variable or property before "deletion", no enumeration function of any of the scripted object class should return a deleted object (whether it was deleted by the player scrapping it or the script "Delete()" function).

If enumerators were to return deleted objects which are pending garbage collection, every script using those enumerators would need to verify at the call site whether the results are valid. The reason we have the "IsDeleted" and similar functions/properties is to insure that any references already held can be validated at any given point.

TL;DR, GetLinkedRefChildren not returning a deleted object is correct behaviour; GetLinkedRefs of a "deleted" persistent object (regardless of how it's deleted) are still valid because until "held count" triggering persistence reaches 0, the object it's only flagged for removal and the garbage collector cannot deallocate that object.
 
Last edited:

kinggath

Well-Known Member
Staff member
Administrator
Moderator
Verified Builder
Messages
3,878
Scrapped objects aren't deleted, they are only disabled and marked for future deletion, you can actually undo the scrapping by enabling them, and they won't be cleaned up.

All besides the point of this post though, which was to say that you should not rely on linked refs as a way to do cleanup work post-scrapping.
 

1000101

Lurking in the bushes
Verified Builder
Messages
104
I'm not sure I follow.

Are we talking about actual proper scrapping/deletion that is done at the engine level where the dynamic formID is freed, all memory and references are freed and any further access would yield an invalid pointer exception, or....

Are we talking about the fake scrapping (disable and move down N points on the Z axis)?

I thought your original post and thus my reply was based on the former. If it's the later, then "scrapping" and "deleting" are the wrong terms to use because it is neither. There is a major distinction here which can lead to confusion as it already has.

All besides the point of this post though, which was to say that you should not rely on linked refs as a way to do cleanup work post-scrapping.
I'll do you one better and say that one shouldn't use linked refs beyond their intended purpose of providing a physical link between objects.
 

kinggath

Well-Known Member
Staff member
Administrator
Moderator
Verified Builder
Messages
3,878
Scrapping via the Workshop.

If you catch the OnWorkshopObjectDestroyed event, you can still interact with the reference. You can even re-enable it.
 

1000101

Lurking in the bushes
Verified Builder
Messages
104
Ah yes, at that stage though the object is still not fully destroyed by the engine because it still has events pending, to wit - OnWorkshopObjectDestroyed. Once the events are complete and all references holding it (be it a script variable, registered event, etc), it should be fully released.

Back to the original topic, one should test an object IsDeleted when responding to events/user interaction.
 

kinggath

Well-Known Member
Staff member
Administrator
Moderator
Verified Builder
Messages
3,878
After further investigation, I discovered my initial post only appears to be true if the items in question are also linked on WorkshopStackedItemParentKeyword. That keyword makes the items move along with the parent, and then if the parent becomes scrapped, it appears to break all links - not just the link on WorkshopStackedItemParentKeyword.

I'm curious if using the rug trick (which works with dynamically attaching things via that keyword), and then scrapping the rug, causes all linked refs to break. If so, it could probably leave some very interesting bugs behind.

I'm editing the original post to add the new findings in case anyone finds this in the future and doesn't read through all replies.
 

EricFranklin

New Member
Messages
25
I'm curious if using the rug trick (which works with dynamically attaching things via that keyword), and then scrapping the rug, causes all linked refs to break. If so, it could probably leave some very interesting bugs behind.
Having read through all replies, I'm also curious.
Has further testing been done on this yet?
Since the rug trick and pillar trick are a MAJOR building mechanics used on PS4s.
Where save testing is at it's worst, basically zero.
They crash all the time, because... Who knows?
I'll setup some (PC) test saves and if I find something funny I don't understand in Resaver I'll post.
 
Top