Jump to content

Question on Events and threads (Papyrus scripting)


PJMail

Recommended Posts

  • Replies 55
  • Created
  • Last Reply

Top Posters In This Topic

I tested IsChild() and IsDead() - both should not involve any real processing - but both were Not Latent + Delayed.

By that I mean FPS locked and Blocking - Same as Is3Dloaded().

Probably just lazy programming to have them Delayed... It's not like an Actor can change to a child between frames...

Edited by PJMail
Link to comment
Share on other sites

@SKK - trust you to do a "thorough" job of testing, that's one s**t load of boxes!!! Any scripting 'gems' from that you can pass on?

 

Scripts attached to non persistent objects still run (while loops & such) even when they are unloaded.

 

Non persistent objects with running scripts (while loops & such) are not removed from the game when unloaded even flusihing pcb/cellreset.

 

Scripts that are idle but have a property to Object itself make it persistent.

 

Scripts that are idle but refer to self as Self.Function do not prevent a non persistent object from being cleaned up.

 

LinkedRefrences that involve non persistent objects can not be resolved when unloaded.

 

All the sorta kinda stuff you would expect & other stuff I cant rememebr thats peppered through this forum over time.

Link to comment
Share on other sites

@SKK - Thanks. All as expected but good to have it confirmed.

Just not sure what you mean by "Scripts that are idle but have a property to Object itself make it persistent."

I know this happens if another object has a reference to a temporary object (it acts persistent while being referred to) but are you saying an object can 'self refer'? Like it has a property on it's script that resolves to itself?

Link to comment
Share on other sites

Yes any script with a permanet property to an ObjectReference will make that target persistent.

 

Which is why using Self is best for scripts refering to their parent object/actor/quest/whatever.

 

One could declare a property as Auto but not Const Mandatory and then clear the property when the script is done to release the Object (itself). See the example script I posted on the recent [ Newbie Modder, Scripting Help for Settlement Mod ] thread.

Link to comment
Share on other sites

@SKK - I have used that for other objects (that I want to keep existent while I am) but not effectively 'self'. Thanks.

 

Some last (?) cleanup questions:

- under what conditions are ALL timers cancelled? Does 'unregisterforallevents()' do it?

- Similarly does that also unregister remote events (such as OnPlayerLoadGame)?

 

And is that all unnecessary on Actor death (ondeath, OnWorkshopObjectDestroyed, etc) - ie. the game automaticall does it?

Edited by PJMail
Link to comment
Share on other sites

I have not observed unregisterforallevents() cancelling timers. If cleaning up a script to shudown I always explicity cancel all unique timers that can be started, and set any LinkedRefs to null.

 

Unregisterforallevents() should unregister native remote and custom events, but again my cleanups always explicity unregister all unique custom events that could be registered by the script just to be sure. Yes each unregistration could take a frame, but in this case accuracy is more important than performance. It would be a comlex test harness to validate custom events so I never found the time to explore that.

 

Here is a standard cleanup script I attach to workshop constructible objects that is called when they are stored/destroyed

 

 

 

Function Cleanup()

If (bCleanupRunning == False) && (Self.IsBoundGameObjectAvailable() == TRUE) ;handle multiple calls
	bCleanupRunning = True ;if this is a Const script can set an ActorValue flag on the object 

	Self.CancelTimer(iSummoningTimer) 

	Self.UnregisterForAllEvents()
	Self.UnRegisterForCustomEvent(pWorkshopParentScript, "WorkshopPlayerOwnershipChanged")

	Self.SetLinkedRef(None, pWorkshopLinkCenter)
 
	Alias_SummoningSpeakerLocation.Clear() ;release me
	Alias_SummoningSpeakerActors.RemoveAll() ;release my bitches

	Self.Disable()
	Self.Delete()

	; bCleanupRunning = False ; not unsetting this as who now cares, and could hold the script open blocking delete. 
EndIf

EndFunction

 

 

 

Some may say "hey you dont need to specify Self. as thats implicit", for maintainability I prefer my fully qualified explicit notation.

Link to comment
Share on other sites

Something I do: Instead of using Const Properties to obtain references, I obtain them through GetFormFromFile and later explicitly discard them all during shutdown/cleanup. I do like to put the formIDs to load in properties sometimes tho, so I have an easy configuration block.

 

IsBoundGameObjectAvailable() comes in handy as well to abort loops and other long running procedures. Especially those that might get stuck when references become invalid because a plugin was yanked from the load order or whatever.

 

And as always, remember: Running loops are stored on the stack and thus in the save. As a consequence of this, they will continue running until the abort condition is met, even if their corresponding PEX file was removed entirely.

Link to comment
Share on other sites

I agree IsBoundGameObjectAvailable() is very useful for cleanup when someone removes your mod 'badly' (not the way you instructed because... noone reads instructions...). I have it on remote events (such as ongamestart) as they still fire after the pex is gone. As far as I have found, though, local events, and events attached to objects that have now gone don't seem to fire. I may just be lucky in my testing though.

 

However I am not going to spread that call at intervals throughout my longer procedures on the off chance someone saves in the middle of them then deletes the mod. A very low likelyhood - and that practice will cause them grief in the end anyway... And I ALWAYS have a count limit on loops so they can never run forever, though very few scripts I have seen do that. Many times I have seen "While (condition) Endwhile" loops used to wait for a condition... Horrors...

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...