shatsnazzle Posted April 3, 2018 Share Posted April 3, 2018 (edited) Hello all! I've seen a lot of stuff around about things remaining persistent if they're a script property or a reference alias. My question is, for an actor that I spawn in the following way (with a property and thrown into an alias), will they remain persistent after they die, or have I obliterated them from memory completely after death? ScriptA is on an activator button for testingScriptB is on QuestB to allow access to a RefCollectionAlias property called RefCollectionBScriptC is on a RefCollectionAlias called RefCollectionB on QuestB Scriptname ScriptA extends ObjectReference ScriptB property QuestB auto Actorbase property LvlRaider auto Event OnActivate(ObjectReference akRef) actor TheRaider = self.PlaceActorAtMe(LvlRaider) QuestB.RefCollectionB.AddRef(TheRaider) EndEvent Scriptname ScriptB extends Quest RefCollectionAlias Property RefCollectionB Auto Scriptname ScriptC extends RefCollectionAlias Event OnDeath(ObjectReference akSenderRef, Actor akKiller) RemoveRef(akSenderRef) akSenderRef.delete() akSenderRef = none endEventWhen I tested this with a RefCollectionB.GetCount() it returned 0 as I hoped and when I tested with FindRandomActorFromRef it returned 0 as well.Thank you for your help guys and girls! Edited April 3, 2018 by shatsnazzle Link to comment Share on other sites More sharing options...
SKKmods Posted April 3, 2018 Share Posted April 3, 2018 I have had some fun with volumes (64 to 128) of spawned live and killed NPCs: Live NPCs in a reference/collection alias and/or script ObjectReference property will persist whilst in the alias/property and the quest is running, even when 3D unloads over uGridsToLoad or fLODFadeOutMultActors threshold from the player. Live NPCs removed from a reference/collection alias and/or script ObjectReference property can do really strange stuff when 3D unloads over uGridsToLoad or fLODFadeOutMultActors threshold from the player (I have posted youtubes on this) and eventually disappear. Dead NPCs in a reference/collection alias and/or script ObjectReference property will persist whilst in the alias and the quest is running, even when there are more than iRemoveExcessDeadCount scavenge threshold and/or when 3D unloads over uGridsToLoad or fLODFadeOutMultActors threshold from the player. Dead NPCs removed from a reference/collection alias and/or script ObjectReference property will be automatically disabled and cleaned up when more than iRemoveExcessDeadCount are around either in or out of the 3D loaded area. Now for the strange but: Live NPCs in an alias/property that die when on the 3d and AI activity processing boundaries of uGridsToLoad / fLODFadeOutMultActors (standard around 15,000 game units) from range tweaked projectiles or npc/npc hostility can report both alive and dead states and generate ambigious alias collection counts. More youtube videos posted on that. TL;DR if you clear an NPC from Alias and ObjectReference property, it will eventually be removed by a game engine scavenging process dead or alive depending on threshold counts and 3d status. When dealing with volumes of spawned NPCs I would suggest managing the reference release, disable and delete as a scavenge process on a regular timer in script (for you timer haters: at high volumes a flood of OnDeath events can stack and be lost leaving dirty hanging references, so only a timer tick will do). Link to comment Share on other sites More sharing options...
shatsnazzle Posted April 3, 2018 Author Share Posted April 3, 2018 (edited) SKK50 thank you again as always! I just watched your vids, that poor dead NPC stuck in limbo with a quest marker on him. When dealing with volumes of spawned NPCs I would suggest managing the reference release, disable and delete as a scavenge process on a regular timer in script (for you timer haters: at high volumes a flood of OnDeath events can stack and be lost leaving dirty hanging references, so only a timer tick will do). Instead of an OnDeath() event would it be more thorough if I throw something like this on the quest? Event OnInit() StartTimerGameTime(24, someIndex) EndEvent Event OnTimerGameTime(int Index) StartTimerGameTime(24, someIndex) int counter = RefCollectionB.GetCount() - 1 while counter >= 0 if RefCollectionB.GetAt(counter).IsDead() actor DeleteMe = RefCollectionB.GetAt(counter) RefCollectionB.GetAt(counter).RemoveRef DeleteMe.delete() DeleteMe = none endif counter = counter - 1 endwhile EndEventShould I disable() before I delete() and should I set it = none afterwards? Or is this overkill? And something I've always been a little unclear on:How do I clear something from being a script property?If on scriptA above I added a line: LvlRaider = nonewould that clear the property in the manner that I am looking for? Or should I just set the actor "TheRaider" = none?Or is it unnecessary since ActorBase is not an ObjectReference property?Edit: nevermind on the last part I think I found the answer right under my nose in the wiki: "When a script property is pointed at a reference in the editor....you should not use properties to point at references directly."and the ActorBase is a Form so I think I'm in the clear there. Or am I mistaken? Thank you again!! :smile: Edited April 3, 2018 by shatsnazzle Link to comment Share on other sites More sharing options...
SKKmods Posted April 3, 2018 Share Posted April 3, 2018 (edited) All looks good, best to use realtime intervals for system management cadence as players can run game timescale as low as 2:1 rather than 20:1 which may subvert your cycles. 24 game seconds is agressive at only 1 default realtime second, 30 to 60 realtime seconds is my default as a high END player can sprint 15 to 30,000 game units from a stuck or dead npc in that time which is a reasonable 3d unload window. I prefer to disable and then delete as its a better UX visual pop if it happens in player line of sight. It may even complete faster due to synch/asynch calls ... I misplaced those test notes. Edit: to finish as your deleteme ref is defined in the while loop scope it should only last in that code block, but, its good practice to none refs incase they get moved to a wider scope when your not concentrating. Edited April 3, 2018 by SKK50 Link to comment Share on other sites More sharing options...
kitcat81 Posted April 4, 2018 Share Posted April 4, 2018 (edited) Some time ago I saw somewhere that OnDying works better that OnDeath. Don't know if it's true, but I used OnDying and it seemed to work for me. Depending on the purpose you can also use event OnUnload. Despite of it's description, it works pretty well and used in many vanilla scripts. Then your actor will be always deleted when he can't be seen by player. Another way is to use player events to clear your collection (i.e. OnPlayerSleepStop). You don't have anything in your script to keep the NPC persistent apart from the Alias. But as soon as you remove the NPC ftrom collection, he will stop to be persitent.When you create your Actor or ObjectReference property inside a function or event, it does not create persitence. But if you create it ouside a function , the reference will be persintent untill you clear your propertyCreation kit base ID don't make anything persistent. Only references ID do.Example: Script MyScriptA Form Property MyObject Auto Const ObjectReference MyRef ; A property outside functions and events makes it possible to access it from different functions and events, but then you have to clear to it to avoid persitence Event OnActivate(ObjectReference akActionRef) MyRef = PlaceAtMe(MyObject, 1) EbdEvent Event OnUnload() If MyRef MyRef.Delete() MyRef = none ; clear the property so the object don't get stuck in the world EndIf EndEvent Script MyScriptB Event OnActivate(ObjectReference akActionRef) ObjectReference MyRef = PlaceAtMe(MyObject, 1) ; there is no need to clear anything in this case MyRef.Disable() EbdEvent Edited April 4, 2018 by kitcat81 Link to comment Share on other sites More sharing options...
shatsnazzle Posted April 5, 2018 Author Share Posted April 5, 2018 Thank you very much kitkat81! :) And thank you again SKK50 for the messages you sent and your answers here! Link to comment Share on other sites More sharing options...
Recommended Posts