Author Topic: Technical Question - GetObjectByTag or...  (Read 2198 times)

Legacy_Hardcore UFO

  • Full Member
  • ***
  • Posts: 157
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« on: August 19, 2011, 06:10:50 am »


               This is a question for the more advanced scripters who know about the systems that keep the scripts running. I'm trying to decide between two script versions for an OnEnter event on most areas. This will light placeable torches and lamps while circumventing the need for heartbeat scripts.

The first script uses GetObjectByTag, where all the lamps (probably across the module) would have the same tag; the second uses GetObjectByType followed by GetLocalInt.

The dealbreaker here is which one would be most efficient/less strenuous on the resources? I've been told GetObjectByTag is pretty reliable but it depends on how the engine itself keeps track of what it's scanning for. If an area is large with many doors and placeables, and GetObjectByTag cycles all things considered an object (doors, placeables, creatures, etc) to compile a list of valid tags, it seems like it might end up slower.

Now this isn't a huge deal, but it's something that piqued my curiosity - both scripts run fine, but every bit of streamlining counts. Replies and/or debate is appreciated!
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #1 on: August 19, 2011, 07:18:46 am »


               Hmm,  First Question:

Where does the   GetObjectByType function come from.  NWNx?  or an Include?

If it comes from NWNx it may be faster.
If it is from an include, it is a wrapper?? well I dont know.  GetNeareast Object maybe?

I really thing nither one is the answer to your question. I would design a system where the objects(torches only had to be searcherd for once.  That way it really would not matter how hard they where to find the first time, since it would only be done once.

you could either do what bioware did with waypoints,  Serarching for them the first time and storing them in a list of local objects for future calls.  

or
daisy chain them after finding them the first time.   You could do that by storing a local object on the first one found that points to the second one.  on the second one you would store a local object that points to the second one.  ect.
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #2 on: August 19, 2011, 10:27:22 am »


               I have an odd question. Since placeables can be set to factions, would it be possible to set them all into a special placeable faction and search them by faction?

While the Lexicon suggests it's PC/NPC, it doesn't state that it won't also retrieve objects. I suppose likely I can slap a script together to test it, but that might be a way to do it if it includes all objects, not just creatures.

Edit:  Nope, looks like the faction setting is likely just for determining who'll respond to shouts from the placeables.
               
               

               


                     Modifié par Failed.Bard, 19 août 2011 - 09:35 .
                     
                  


            

Legacy_Hardcore UFO

  • Full Member
  • ***
  • Posts: 157
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #3 on: August 19, 2011, 10:11:57 pm »


               It's not from NWNx, it's just a fuction I found in the sidebar. It's not from another included script, nor a wrapper, the way I have it done; just plain old... OnEnter: Scan for this stuff here and do this to it. The two solutions you mentioned are unknown things to me that I'll look up, because they sound like they'd simplify this (at least once I figure out how to apply these things) greatly. These leads are much appreciated!

Too bad about the faction script, though.
               
               

               


                     Modifié par Hardcore UFO, 19 août 2011 - 09:12 .
                     
                  


            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #4 on: August 19, 2011, 10:37:06 pm »


               There is no standard NWN function "GetObjectByType". There is a "GetObjectType" which just returns what type of object oObject is. If it is actually "GetObjectByType" then it is included from some other script or that function is written directly in the OnEnter script. You'd have to post the function from there for anyone here to see if it is efficient or what not.
               
               

               
            

Legacy_Hardcore UFO

  • Full Member
  • ***
  • Posts: 157
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #5 on: August 20, 2011, 12:04:08 am »


               You're right. I got confused with GetNearestObject, which can filter object types. Derp.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #6 on: August 20, 2011, 06:06:49 am »


               You pretty much never want to use GetObjectByTag, if you're concerned about efficiency - it checks every object in the module. Instead, use GetNearestObjectByTag in the area, using GetFirstObjectInArea to get an object for GetNearest to compare to, if you need one. You can also loop objects in the area with the latter function and its GetNext counterpart.

Funky
               
               

               
            

Legacy_Mavrixio

  • Full Member
  • ***
  • Posts: 142
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #7 on: August 20, 2011, 01:58:52 pm »


               It is the opposite... you never want to you GetNearestObjectByTag, if you are concerned by efficiency.

The module keep a sorted array of all tags, which is used by GetObjectByTag. So no matter the number of objects you have in your module, GetObjectByTag will be very fast.

GetNearestObjectByTag doesn't use this sorted array and prefer looping through all objects in the area and it also need to check the distance of each object found... if you have many objects in your area and fewer objects with the tag that you are looking for, you may even want to use this function to get the nearest object with a specific tag:

object MyGetNearestObjectByTag(string sTag, object oTarget=OBJECT_SELF)
{
    int nNth = 0;
    float fNearestDistance = 100000.0;
    object oNearestObject;
    object oTargetArea = GetArea(oTarget);
    object oObject = GetObjectByTag(sTag, nNth);
    while (oObject != OBJECT_INVALID)
    {
        if (GetArea(oObject) == oTargetArea)
        {
            float fDistance = GetDistanceBetween(oObject, oTargetArea);
            if (fDistance < fNearestDistance)
            {
                fNearestDistance = fDistance;
                oNearestObject = oObject;
            }
        }
        oObject = GetObjectByTag(sTag, ++nNth);
    }
    return oNearestObject;
}

               
               

               


                     Modifié par Mavrixio, 20 août 2011 - 01:00 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #8 on: August 20, 2011, 04:50:45 pm »


               

Mavrixio wrote...

It is the opposite... you never want to you GetNearestObjectByTag, if you are concerned by efficiency.

The module keep a sorted array of all tags, which is used by GetObjectByTag. So no matter the number of objects you have in your module, GetObjectByTag will be very fast.


Interesting theory. In practice, however, completely wrong. I can't speak to the array, having not peeped that part of the engine, but GObT was incredibly slow in usage - one of several reasons we stopped using it. Granted, the distance-measuring in GNObT is wasteful in many cases, but it still FAR outperforms GObT in practice - probably because it's dealing with a few hundred objects instead of every object in the module. Have you done any actual profiling, or are you speaking solely from a theoretical perspective?

Funky
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #9 on: August 20, 2011, 07:10:44 pm »


               Funky, did you find at what point GNObT outperforms GObT? How many objects (roughly speaking) do you need to have for this to matter?
               
               

               
            

Legacy_Mavrixio

  • Full Member
  • ***
  • Posts: 142
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #10 on: August 20, 2011, 08:29:05 pm »


               

FunkySwerve wrote...

Mavrixio wrote...

It is the opposite... you never want to you GetNearestObjectByTag, if you are concerned by efficiency.

The module keep a sorted array of all tags, which is used by GetObjectByTag. So no matter the number of objects you have in your module, GetObjectByTag will be very fast.


Interesting theory. In practice, however, completely wrong. I can't speak to the array, having not peeped that part of the engine, but GObT was incredibly slow in usage - one of several reasons we stopped using it. Granted, the distance-measuring in GNObT is wasteful in many cases, but it still FAR outperforms GObT in practice - probably because it's dealing with a few hundred objects instead of every object in the module. Have you done any actual profiling, or are you speaking solely from a theoretical perspective?

Funky


Yes, i have tested it.
It certainly depend on the number of object the number of object in the area, i dont have stat about that, but for if there's 100+ object int the area, then GetObjectByTag is 2-3 times faster than GetNearestObjectByTag, I dont know you, but personally we have areas with 1000+ placeables, so GetNearestObjectByTag is a no-no.
               
               

               
            

Legacy_Hardcore UFO

  • Full Member
  • ***
  • Posts: 157
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #11 on: August 20, 2011, 08:42:49 pm »


               Interesting indeed. I might end up with 2 seperate OnEnter scripts for more/less decorated areas. That is, since the listing option mentioned by Lightfoot8 seems to already be embedded in the GetObjectByTag function.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #12 on: August 21, 2011, 01:09:33 am »


               

henesua wrote...

Funky, did you find at what point GNObT outperforms GObT? How many objects (roughly speaking) do you need to have for this to matter?

We found that GNoBT outperformed GObT radically even when our mod was much smaller - there was no evidence of any kind of optimization on GObT. It could take a second or two, even, which is outrageous as compared to GNObT.

Mavrixio wrote...

Yes, i have tested it.
It certainly depend on the number of object the number of object in the area, i dont have stat about that, but for if there's 100+ object int the area, then GetObjectByTag is 2-3 times faster than GetNearestObjectByTag, I dont know you, but personally we have areas with 1000+ placeables, so GetNearestObjectByTag is a no-no.


You say you've tested it, but you don't have any statistics on performance by object count? How exactly did you test it? I'd be very interested to see your profiling on it.

Also, if you have areas with 1k+ placeables, I'm a lilttle less inclined to take your claims about performance seriously. That's an unbelievable number, even if you're really decking an area out. Have you actually counted, or are you guestimating? The most obscene placeable count on HG is in the 500s, where I went seriously overboard decking out the Forest of Poisoned Dreams in Shedaklah with extra mushrooms in order to get the right effect.

For both of you, here's our mod set out in placeable and tile count, for purposes of comparison:
HG placeable/tile counts

FWIW, we stopped using GObT when the mod was less than half its current size.

Funky
               
               

               
            

Legacy_Mavrixio

  • Full Member
  • ***
  • Posts: 142
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #13 on: August 21, 2011, 02:37:30 am »


               I dont need to calculate any stats, the first pofiling result that i got was clear, and I have seen it while debugging nwserver that it use a sorted array for the tags.
I dont have the formula on the top of my  head, but the time that it takes to access an element in a sorted array can be considered as constant... so no matter the size of your module, GetObjectByTag will be relatively fast, it can easely be faster than GetLocalObject if you have many variables on the source.
               
               

               


                     Modifié par Mavrixio, 21 août 2011 - 01:37 .
                     
                  


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #14 on: August 21, 2011, 02:56:06 am »


               Funky, I have not seen GObT take a second or two. But my mod is very small right now. It is for that reason that I suspect size has something to do with the performance of these functions. I figure as off base as Mavrixio is coming across, there might be something to what he is saying.

That said... I certainly wasn't doubting you and pressing for your data. I just wanted to know what you thought on the matter.

Mavrixio, all I have to say is: show the data or it didn't happen.