Author Topic: Counting Item Stacks  (Read 555 times)

Legacy_WoC_Builder

  • Sr. Member
  • ****
  • Posts: 425
  • Karma: +0/-0
Counting Item Stacks
« on: September 13, 2012, 05:44:21 pm »


               In an effort to reduce "packratting" on our mod, I'm going to be counting items, and if they fall over 200, send them to a pawn broker, and not allow them to leave til they get under 150 items.  '<img'>

I'm curious though, does NWN count stackable items as a single item, or does say a stack of 99 arrows (or potions, gems; any stackable item) count as 99 items?  I would hope 1, or this is all for naught.

I checked the Lexicon and Wiki, but found nothing definitive.
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Counting Item Stacks
« Reply #1 on: September 13, 2012, 06:02:55 pm »


               omg, thats exactly the wrong way how to deal with this problem

but whatever, I bet you are running one of those "don't do this, don't do that and that or you will be banned" kind of modules

answer is that stackable items are considered as a one item regarless of how many items is in the stack
               
               

               


                     Modifié par ShaDoOoW, 13 septembre 2012 - 05:03 .
                     
                  


            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Counting Item Stacks
« Reply #2 on: September 13, 2012, 06:05:55 pm »


               IIRC the items are counted as single ones whatever the stack. GetItemStackSize() returns the number of items in the stack if needed.

EDIT: Never mind, beaten by the punch


Kato
               
               

               


                     Modifié par Kato_Yang, 13 septembre 2012 - 05:06 .
                     
                  


            

Legacy_WoC_Builder

  • Sr. Member
  • ****
  • Posts: 425
  • Karma: +0/-0
Counting Item Stacks
« Reply #3 on: September 13, 2012, 06:40:22 pm »


               

ShaDoOoW wrote...

omg, thats exactly the wrong way how to deal with this problem

but whatever, I bet you are running one of those "don't do this, don't do that and that or you will be banned" kind of modules

answer is that stackable items are considered as a one item regarless of how many items is in the stack


Well, I thank you for the answer, but am surprised by the tone and your judgement of us by a single post of mine, considering chances are you have not played there.  I am trying to reduce lag, if you must know, not beat players over the head with another rule.

Since you seem to have a better idea how to handle the situation, please...share it.
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Counting Item Stacks
« Reply #4 on: September 13, 2012, 07:35:59 pm »


               

WoC_Builder wrote...

ShaDoOoW wrote...

omg, thats exactly the wrong way how to deal with this problem

but whatever, I bet you are running one of those "don't do this, don't do that and that or you will be banned" kind of modules

answer is that stackable items are considered as a one item regarless of how many items is in the stack


Well, I thank you for the answer, but am surprised by the tone and your judgement of us by a single post of mine, considering chances are you have not played there.  I am trying to reduce lag, if you must know, not beat players over the head with another rule.

Since you seem to have a better idea how to handle the situation, please...share it.

I was under impression that you read THIS thread. Now the conclusion you came to is wrong and lame - sorry if this sounds harsh, but bothering players with stuff like this is not professional at all.

Saying this again. Too many items in inventory is not a problem by default. If you have the problem with this - and make sure you tracked the lagging to the PC logging in - the problem is in the scripts. It might be in the OnAcquire script as that will run for each item player have in the inventory. But as good it might be in OnEnter as this all happens in merely same time. Make this scripts more efficient and you shouldnt have these issues.

But anyway - your post, while I dont have anything about you I admit that, looks like under panic that this might cause some lag issues due to the what you have read in this thread in the toolset forum.
               
               

               
            

Legacy_WoC_Builder

  • Sr. Member
  • ****
  • Posts: 425
  • Karma: +0/-0
Counting Item Stacks
« Reply #5 on: September 13, 2012, 08:12:17 pm »


               Until your link above, I had not read that thread.  '<img'>

This is not a panic attack (and a knee-jerk reaction), but a systemic approach, and working through the list provided on the Lexicon www.nwnlexicon.com/index.php/Lag_Busting.  This is simply one of the steps we are taking.

Thanks for your concern though.  I'll make sure and read the other thread for additional ideas.  '<img'>

Item 11 reads as follows:


Limit the Number of Items Your Players can Carry


The
more items a player carries, the more load they place on a server. This
is one of the areas in which our knowledge is largely anecdotal, but
it’s also been commonly accepted in the community for some time – so
much so that a limiter was already in place under our PW’s last admin
in 2004, before it changed hands. It was originally set to teleport
players to ‘Encumbria’ and not let them leave until they got below
200 items, but this limit was lowered in several steps to a 150 item
limit over a period of some months, with noticeable performance
improvements resulting. It also stands to reason, since more items means
more for the server to keep track of, and more for scripts to loop
through, though those alone probably don’t fully account for the
performance increases we noticed. Any lag generated by packrat players
is probably mostly server lag, unless item data is streamed to other
players for some reason (and we have no reason to believe that it is),
in which case there might also be a connection lag component.


               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Counting Item Stacks
« Reply #6 on: September 13, 2012, 09:56:54 pm »


               well its not so big deal to bother players with such pseudosolution like the one mentioned in the article. I also wonder of the author of that article as on HG you are carrying hundreds of stuff normally. I definitely havent found any issues with this personally and im running one PW loot related without any persistent storage so players are keeping items on character. I dont want to sound like ehye_khandee now, but the module im running has no lag issues and can run smoothly almost undefinitely until crashes (once it lasts two weeks, but more often random crash comes into few days)

So, do you have lag issues with players carrying too many items? Or you just read the article and now you are worrying about it? which is basically the panic attack '<img'>

Until you dont have the issues with this, you definitely dont need to maintain such hardcore restrictions. Make the OnAcquire/OnEnter scripts more efficient however never hurts.
               
               

               


                     Modifié par ShaDoOoW, 13 septembre 2012 - 08:58 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Counting Item Stacks
« Reply #7 on: September 13, 2012, 10:12:39 pm »


               I myself Do not agree that Items cause lag in a server.  That is unless the server itself has poorly written scripts that are looping through players inventories to much.  

To answer your question though,  well, it is hard to answer your question with out knowing how you are counting you items.   I would assume that it is by GetFitst/NextItemInInventory.   In that case you are counting instances of items on the player.   A stack of 99 arrows would be only 1 Instance of the item with a stack count of 99.  

However I do not really like the way you are adding your limit count to the module.   Could I sugest that you do it a different way.   Perhaps if you instead had the PC drop the item as soon as they aquired it,  Sending them a message that the Item Just would not fit in there over full pack.
               
               

               
            

Legacy_acomputerdood

  • Sr. Member
  • ****
  • Posts: 378
  • Karma: +0/-0
Counting Item Stacks
« Reply #8 on: September 13, 2012, 11:14:47 pm »


               but doesn't that mean you have to count the entire inventory in the OnAcquire script each time a player picks something up?  that seems to contradict your statement that poorly written scripts loop through an inventory too often.

why not on login just send a message saying "hey, let's keep our inventories down to <an arbitrary number>.  the next time you log in, and you're over that, you're gonna lose some gear.  we're doing this for <arbitrary reason | roleplay reason | because DM is on power trip | it makes ShaDoOoW really mad | the lexicon says so>".
               
               

               


                     Modifié par acomputerdood, 13 septembre 2012 - 10:18 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Counting Item Stacks
« Reply #9 on: September 13, 2012, 11:35:10 pm »


               Lol, I never said I would do such a system with a loop count in the OnAquire. But you are correct if it was done that way it would be at least a little draining on the system.


Now I would use the OnAquire. But not a loop. It would simply add one to a count. Once the count went over by a few. Not one a few. I would then count the items  to make sure the count was correct. Stacked items would cause errors in the count. Then take the the action required.

Most likely I would not even have them drop the item right then. I would give it a delay then drop out the last item added to the pack. Then Delay and drop again untill the count was under. That way you could have a player pick up a whole bunch of stuff and litteraly scatter it every where trying to get it to where it is going.
               
               

               


                     Modifié par Lightfoot8, 13 septembre 2012 - 10:36 .
                     
                  


            

Legacy_acomputerdood

  • Sr. Member
  • ****
  • Posts: 378
  • Karma: +0/-0
Counting Item Stacks
« Reply #10 on: September 14, 2012, 12:27:14 am »


               now maybe i'm not appreciating the speed of variables, but i was always under the impression that Get/SetLocal* on objects was VERY slow.  or at least that's what the nwnx_odbc taught me.  i realize now that i only have 1/2 of the story since they said it was slow compared to a true database.

have i been working under a false assumption that it was just slow in general?  do we have any data on relative speeds of these functions?  i guess i have to assume that setting a local int on a PC or item each time an item is picked up must be faster than cycling through 150/200 items per OnAcquire, but do we really know if that's the case?

of course, if you're not committed to the minute by minute granularity of item counts, i still maintain a count once per login or maybe even once a rest/game day/etc would be sufficient.

though i do like the idea of leaving a trail of gear behind you - haha.


and yes, i realize that this topic has now drifted FAR off course.  :/  but since the topic of efficiency came up.....
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Counting Item Stacks
« Reply #11 on: September 14, 2012, 12:39:24 am »


               local variables speed is meaningless in this issue

according to the old speed tests done by acaos or somebody, the speed starts to be issue after there is many local variables on item. But, items generally doesnt have many variables on them and if they have then its a bad concept. You can always use bitwise to spare some variables you know.

Also I dont see there other way to do that. The speed comparsion has meaning only if you can do the job via different approach. Now if your OnAcquire is huge, with plently of stuff and you want to track items so they are not processed more than once, then you need local variable on item. I cant see there any other way to do that at all so there is no point of talking about local variables speed. The efficiency of one GetLocalInt call vs "fifty assumed string comparsions" is unquestionable.

EDIT: basically the old local var test just proves that using local variables on making some pseudo 2DA tables is not such great idea due to the ammount of variables on the object. The more row and collumns the less efficient this is in comparsion to the Get2DAString which has been greatly improved in last official patch. It doesnt mean that local variables are bad or evil. They are just fine for 99% stuff you need to be done.
               
               

               


                     Modifié par ShaDoOoW, 13 septembre 2012 - 11:42 .
                     
                  


            

Legacy_Squatting Monk

  • Hero Member
  • *****
  • Posts: 776
  • Karma: +0/-0
Counting Item Stacks
« Reply #12 on: September 14, 2012, 05:28:22 am »


               I don't wanna get this thread further off-topic, but it's the SetCampaign* functions and 2da reads that were unreasonably slow as compared to NWNX's database functions. Local variables are really fast (and only get significantly slow once you get around 5k on a single object). A quick look in the Omnibus yielded this...

motu99 wrote...

The typical overhead to execute a nwn script (for instance via ExecuteScript) lies between 2.5 and 10 msec, depending whether the script is cached or not. Note that this is the overhead required by the aurora engine to properly initialize the script, call its main() and do any necessary clean up after the script's main finished. The 2.5 - 10 msec range does NOT include the time the engine - possibly - requires to load the *.nsc file of the script from disc.
Of course the absolute values for execution times depend on your processor (on other things, too, but mostly the processor). I measured the times with an AMD Sempron 2800+.
Now compare those 2.5 to 10 msec with the time that the same machine typically requires to set/get a local:
~5 usec for <10 total(*)
~10 usec for < 100 total(*)
~100 usec for < 1000 total(*)
(*) "total" meaning total nr of locals of a given type stored (in a single linked list) on the object.
By comparing the figures you can easily see, that as long as your script doesn't read or write a huge nr of locals, the overhead for calling (and ending) the script is still quite a bit higher than the time the script spends reading / writing locals, as long as the total nr of locals on the object is <~1000.

Edit: also, when the PC is first logging in, you don't need to increment the item count on every single OnAcquireItem as his inventory loads. Instead, you can do a single inventory scan and set the item count after he's fuly loaded in. (I imagine this would be faster than getting and setting a local variable every time if there's a large number, but I could be wrong about this.)
               
               

               


                     Modifié par Squatting Monk, 14 septembre 2012 - 04:33 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Counting Item Stacks
« Reply #13 on: September 14, 2012, 06:17:03 am »


               

Squatting Monk wrote...

Edit: also, when the PC is first logging in, you don't need to increment the item count on every single OnAcquireItem as his inventory loads. Instead, you can do a single inventory scan and set the item count after he's fuly loaded in. (I imagine this would be faster than getting and setting a local variable every time if there's a large number, but I could be wrong about this.)



I do not know the differance there either,  My guess though, is that it would not be much.

Here are my thoughts on why.  

First  the only way to stop the OnAquire event from firing is to simply not have one. 

Second, with the large amounts of on core cache memory in CPU now a days, I would bet that the  script being fired back to back that many time, from  module load,  would stay in the cache on core.  I dout that even a read from main memory would be needed after the first run. 
               
               

               
            

Legacy_Squatting Monk

  • Hero Member
  • *****
  • Posts: 776
  • Karma: +0/-0
Counting Item Stacks
« Reply #14 on: September 14, 2012, 06:31:17 am »


               Sorry, I miscommunicated. The bit about script initialization was just for reference compared to local variable speeds.

What I meant was, when the PC logs in, instead of running this on all those initial OnAcquireItems...

int nCount = GetLocalInt(oPC, "ItemCount");
SetLocalInt(oPC, "ItemCount", nCount + 1);

... you could wait until a few seconds after the PC has logged in and just do a scan to count them. Still, I dunno if that'd save you any cycles (you'd have to do a GetLocalInt() to see if the PC has finished loading, after all, so all you're avoiding is a SetLocalInt(); what you save not doing that will not likely be much more that what it costs to loop through the inventory once).

So... yeah. Silliness on my part. Carry on!
               
               

               


                     Modifié par Squatting Monk, 14 septembre 2012 - 05:32 .