Author Topic: Occasional Crash - when deleting / destroying objects from an area  (Read 782 times)

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0


               I've got a script, that fires when a player dies.
It then calls a nwnx function, that duplicates the area (to make a spookier version of the place they die in - to be a ghost plane of sorts.


In order to accomplish this, several things need to be done


1. Area duplicated  - Check  (works fine)
2. Area Name, Fog, Tag Changed - Check (ensures no porting, or scripts referenceing this area by accident, also makes the place look like the after life.)
3. Loop through the area's objects, and depending on the type of object do certain things - Works 80-90% of the time.

The issue is that when it is looping through the objects, occasionally, it gets to an object, and then the server crashes.
I have reporting done in my loop, to report what object it was on, and there doesnt seem to be any pattern.
Just randomly crashes within this loop.


object oObj = GetFirstObjectInArea(oArea);
while(oObj != OBJECT_INVALID)
{
      switch(GetObjectType(oObj))
          {
              case OBJECT_TYPE_PLACEABLE:
                        SetPlotFlag(oObj,FALSE);
                        DestroyObject(oObj);
              case OBJECT_TYPE_DOOR:
                        //Some nwnx functions here that change door script and tags
              case OBJECT_TYPE_WAYPOINT:
                       //Destroy Waypoints too
              case OBJECT_TYPE_TRIGGER:
                      //Destroy triggers
              case OBJECT_TYPE_ENCOUNTERS:
                      //Destroy encounters to prevent living monsters, appearing in the afterlife.
              case OBJECT_TYPE_ITEM:
                      //No painted items from toolset should appear in this realm, so we desotry these too
             case OBJECT_TYPE_CREATURE:
                      //No painted creatures should appear here either - destroy
         }

        oObj = GetNextObjectInArea(oArea);
}

Ok, so you can see kind what im doing above.
This is all pseudo-code.
But can anyone see any reason why a crash would be occuring within this loop?
I mean - is there any special rules required by DestroyObject when used in a loop?
Eg  - Does it affect the collection of objects, in such a way that indexes can be lost, causing exceptions etc?

I've tried this multiple ways.
Most recent code has got a DelayCommand(0.3,xxxxxx);
On destroy object calls, to ensure that enough time is given for the PlotFlag to disappear, and to allow the loop to continue on without being blocked.

I've also got code that 'Disables the encounter'  immediately, and then destroys it 0.3-0.6 seconds later, just to ensure that the encounter doesnt fire if the player gets into the area, before the destroy function has finished.

At the moment, I dont know what object, if any, is responsible.
seems to occur randomly, in different areas, and not 100% reproducable.
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Occasional Crash - when deleting / destroying objects from an area
« Reply #1 on: March 14, 2012, 03:48:22 pm »


               A couple things to consider:

"The plot flag should not affect wether DestroyObject works in any way whatsoever." ~NWN Lexicon.

So you can get rid of any of those lines. It is the destroyable flag that you need to worry about here. And only if you had specifically set an object to be undestroyable e.g. SetIsDestroyable(FALSE).


"Using DestroyObject in a loop can be dangerous - make sure that it
dosn't have DestroyObject as a standard function, but it has a delay.
Same goes for creating objects in loops." ~NWN Lexicon.

Have you tried using the delay included in the DestroyObject function itself?

DestroyObject(oObject, 0.1);

Just some thoughts. Hope it helps.
               
               

               


                     Modifié par GhostOfGod, 14 mars 2012 - 03:50 .
                     
                  


            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Occasional Crash - when deleting / destroying objects from an area
« Reply #2 on: March 14, 2012, 06:16:54 pm »


               

Baaleos wrote...
3. Loop through the area's objects, and depending on the type of object do certain things - Works 80-90% of the time.


How many objects are being looped through?  I have performed large loops before and every if-then or switch-case check within the loop significantly reduces the number of objects I can loop through before a script error.
               
               

               


                     Modifié par WhiZard, 14 mars 2012 - 06:19 .
                     
                  


            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Occasional Crash - when deleting / destroying objects from an area
« Reply #3 on: March 15, 2012, 09:28:35 am »


               

WhiZard wrote...

Baaleos wrote...
3. Loop through the area's objects, and depending on the type of object do certain things - Works 80-90% of the time.


How many objects are being looped through?  I have performed large loops before and every if-then or switch-case check within the loop significantly reduces the number of objects I can loop through before a script error.


It is essentially every object that is in the area - as it appears in toolset.

So, every placeable, trigger, encounter, waypoint, creature, item etc.

A very well laid and fancy looking area, can have maybe a hundred placeables placed for eye candy.

The functionality itself, was set up to be linear by using the DestroyObject  with a 0 delay.
Meaning the player would not be 'Portaled'/'Respawned' to the afterlife area, until it was finished being processed.

However, with any sort of delay, there exists the small chance that the iterating through the loop, will complete, before the actual destroying of the objects is complete, which can result in the player entering the area, before the destroy event has been carried out.

In the case of Static placeables - I believe if you enter the area while they exist, then destroy them, you need to re-enter the area to see them no longer existing? (correct?)


As such, I prefer the 'Linear' no delay approach, as it ensures that the destruction is completed before players are ported.

I've added more logging to the loop, to see what object resref,tag and name etc the object is, before it crashes.
I havent had a crash for about 72 hours now, so for all I know the issue may be gone.