Jump to content

Scripting question


niston

Recommended Posts

I do not use to extend on other scripts, so I don't know for sure. Do some tests, I'm also interested on this matter, but I don't have any projects to tinker with right now, so it would be nice if you share your findings.

Link to comment
Share on other sites

Alright, I tried extending WorkshopObjectScript instead of ObjectReference. The behaviour was the same as with the casted reference: It doesn't work reliably.

 

What I didn't try so far is removing the original workshopobjectscript that's attached to the furniture.

 

But I texted with kinggath about the issue. This is what he had to say:

 

 


The only way to guarantee correct assignment detection is to persist the actors in an alias, which becomes a memory hog.

This is why Bethesda's scripts re-assign everyone when you arrive at a settlement, as they know the assignments are unlikely to hold up. It's also why settlers don't always stay assigned to plots from SS.

The best solution I've come up with, is to only calculate these things while the cell is loaded, and then record the data as a script variable, [...]

 

So I think caching is really the only option here as I don't want to bloat user's save files or hog their RAM. Also, for the sake of "separation of concerns", I'll change my code back to extend ObjectReference.

 

Bummer.

 

 

One unrelated but notable thing: As I'm testing, I'm loading the same save all over again. Out of the 70 or so times I loaded that save now, I've just encountered the "can't assign any settlers to anything anymore" bug for the second time. It becomes apparent immediately, because the first thing I do when testing is plonking down a mine and then assign a settler to it.

 

So, I don't think anything specific triggers that one mean ass bug (it cost me my first run on nuka world, the last good save was just before I went there). The cause is, imho, more likely a f***-up in the engine or, maybe, in some script. A race condition perhaps, that only manifests under relatively rare circumstances. And it happens immediately on load.

Edited by niston
Link to comment
Share on other sites

Well, the only solution that comes to mind is preloading the cell before calling CanProduceForWorkshop(), I don't even know if it will work but it's worth a try:

If(IsInInterior())
	PreloadTargetArea()
Else
	PreloadExteriorCell()
EndIf
Bool CanProduce = CanProduceForWorkshop()
Edited by DieFeM
Link to comment
Share on other sites

That's interesting to know that we can preload cells!

 

I however found a perfectly satisfactory solution for the problem of remote assignment/unassignment by tracking suitable events on workshopparentscript. Those will fire reliably even when player uses SMS to operate on an unloaded settlement.

 

Here's what came out of it:

 

https://www.nexusmods.com/fallout4/mods/37531

 

More is on the way.

Edited by niston
Link to comment
Share on other sites

So you've find out a reliable way to find out this information from the quest script (WorkshopParentScript) which persists (as kinggath said), instead of retrieving it form the object reference script (WorkshopObjectScript) which is not available once unloaded. What I learn from it: Something to keep in mind while working with persistent data; is better using quest/alias scripts instead of ObejctReference scripts when you need to access this data at any moment (even if it is unloaded).

Edited by DieFeM
Link to comment
Share on other sites

So, I don't think anything specific triggers that one mean ass bug (it cost me my first run on nuka world, the last good save was just before I went there). The cause is, imho, more likely a f***-up in the engine or, maybe, in some script. A race condition perhaps, that only manifests under relatively rare circumstances. And it happens immediately on load.

 

Yes. I have a radiant quest system that sometimes just shuts down loading an exit save, but never with a full save.

 

Its < 10% of game loads, but enough to be an irritating quality issue.

 

Many many hours debug tracing *everything* and ... it must be just a random quest engine glitch.

Link to comment
Share on other sites

So you've find out a reliable way to find out this information from the quest script (WorkshopParentScript) which persists (as kinggath said), instead of retrieving it form the object reference script (WorkshopObjectScript) which is not available once unloaded.

 

Well, not 100% exactly. The Information is not available in the workshopparentscript, alas. But, the functions that SMS calls on workshopparentscript to assign and unassign settlers, they both fire a corresponding event as they complete. And that will happen regardless if the workshop object is loaded or not.

 

So I listen for those events to update a script local cache (simple boolean variable). Technically, the assignment information is thus persisted inside the NPC mining script and updated according to certain rules:

 

- If I get an "assigned" event, the cache is set to true.

- If I get an "unassigned" event, the cache is set to false.

- If I get a "cell detached" event, I update the cache with the return value of IsActorAssigned()

 

The cached information is only used when Is3dLoaded() returns false.

When the object is loaded, a direct call to CanProduceForWorkshop() will be made instead.

 

 

I am at this point not 100% positive that actor death would trigger an "unassigned" event. If it doesn't and if that should become a problem (altho I don't think it would), there's an event to be listened at for the death of an actor, too.

 

The root of all evil pertaining to assignment, according to Kinggath, lies in the fact that assignments simply don't persist. As the game unloads the cell, it generally also unloads the actors aaaand... the assignment is gone (as far as Papyrus is concerned). The game will just reload the actor and reassign them, once the cell gets reloaded. Hence also why a reference alias would remedy the problem, because the actor in the alias will always persist.

 

That's a boolean vs. a complex structure that represents an actor instance. Which is also why the "reference-alias-technique" could potentially end in enormous bloat, especially if we have hundreds of assigned actors. As I'm not really interested in the assigned actor, but only in the assignment status (yes/no) of the unloaded workshop object, I feel quite happy with my solution now.

Edited by niston
Link to comment
Share on other sites

 

Many many hours debug tracing *everything* and ... it must be just a random quest engine glitch.

 

 

Exactly this. The responsible software component is called "Story Manager", if I'm not mistaken. I bet you two nuka colas, the fault would not occur on a machine with just a single CPU and no hyperthreading. Those probably also signified the era during which the relevant code has been written and tested.

 

Maybe a mod could be created to test for and warn about presence of the bug, upon game load and/or periodically. By trying to assign some reference alias'd settler somewhere (hidden cell maybe?) to something, and checking IsActorAssigned() for results. Popping up a warning in a message box when the assignment fails.

Edited by niston
Link to comment
Share on other sites

Different question: If adding items to a container from a leveled items list like .AddItem(lvliList, n), will the game roll n times and add each, or roll once and add n times ?

 

And totally unrelated: How to get the PC to comment, like "yess" or "excellent"?

Edited by niston
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...