Harmlezz Posted September 8, 2012 Share Posted September 8, 2012 I have observed a strange (or at least unexpected) behavior and would like to hear how it really works. What i did: I do have a scripted item i do remove immediately when the script starts to run. I have introduced a guard to ensure the item is evaluated only once. But even after 200 Frames sometimes the item gets still processed. Here a snippet of my script with debugging statements: int inProgressint hasBeenRemovedint tokenCountint frameCount Begin GameModeif (inProgress == 0)set inProgress to 1 ; some code goes here set hasBeenRemoved to 1set container to getContainercontainer.removeItem MyToken 1returnendif set frameCount to frameCount + 1 if (frameCount >= 200)set container to getContainerset tokenCount to container.getItemCount MyTokenshowMessage DebugMessage tokenCount hasBeenRemovedcontainer.removeItem MyToken tokenCountendifEndWhat I observe is that sometimes (half the times probably) the second if - endif block gets executed. As far as I do understand the Engine did ran the script 200 times. The message i show always has tokenCount == 1andhasBeenRemoved == 1 That means the item was already removed, but the Engine still runs the item script. So my expectation was a synchronous garbage collection of item but derived from my observations i guess the item get asynchronous garbage collected, someone in the future. Who knows for sure what the reason for this behavior is? Thanks a lot in advance, Harmlezz Link to comment Share on other sites More sharing options...
rickerhk Posted September 10, 2012 Share Posted September 10, 2012 It's a good idea to guard everything, and also not to assume that things happen instantly within one frame.To make sure that the object is actually removing itself, use removeme (in the event of multiple instances in the container). int inProgress int hasBeenRemoved int tokenCount int frameCount Begin GameMode if hasBeenRemoved return else if (inProgress == 0) set inProgress to 1 ; some code goes here set hasBeenRemoved to 1 removeme return endif endif End Link to comment Share on other sites More sharing options...
Harmlezz Posted September 10, 2012 Author Share Posted September 10, 2012 (edited) It's a good idea to guard everything, and also not to assume that things happen instantly within one frame.To make sure that the object is actually removing itself, use removeme (in the event of multiple instances in the container). int inProgress int hasBeenRemoved int tokenCount int frameCount Begin GameMode if hasBeenRemoved return else if (inProgress == 0) set inProgress to 1 ; some code goes here set hasBeenRemoved to 1 removeme return endif endif End I didn't used removeme because of this note in the G.E.C.K. Wiki: In Fallout3.esm the only usage of this function is inside OnAdd blocks. If used outside of this block, RemoveMe may crash the game. Use DropMe instead. The variable inProgress does exactly this. The variable hasBeenRemoved I introduced only to observe my code piece by piece and in my opinion it is not required (and has been already removed). Edited September 10, 2012 by Harmlezz Link to comment Share on other sites More sharing options...
rickerhk Posted September 10, 2012 Share Posted September 10, 2012 RemoveMe will cause a CTD if the script continues for another frame and runs RemoveMe a second time. RemoveMe works ok as long as it is guarded. Link to comment Share on other sites More sharing options...
Recommended Posts