logo logo

 Back to main page

The NWNX Community Forum

 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 
Use of SQLFetch() and TMI Errors
Goto page 1, 2  Next
 
Post new topic   Reply to topic    nwnx.org Forum Index -> General Discussion
View previous topic :: View next topic  
Author Message
weldieran



Joined: 05 Aug 2005
Posts: 71

PostPosted: Tue Aug 16, 2005 21:29    Post subject: Use of SQLFetch() and TMI Errors Reply with quote

OK - I've been getting some TMI errors i'm trying to track down.

I wonder if it has to do with my use of SQLFetch.
Code:

    while (SQLFetch() == SQL_SUCCESS)
    {
        iCount++;
    }


Is something like that possible with aps?

Or if it returns one record, will it be SQL_SUCCESS to infinite?
Back to top
View user's profile Send private message
weldieran



Joined: 05 Aug 2005
Posts: 71

PostPosted: Tue Aug 16, 2005 21:32    Post subject: Reply with quote

look at the Fetch code, it does seem it was made for that.. hmm.. perhaps i'm barking up the wrong tree, but can anyone confirm?
Back to top
View user's profile Send private message
weldieran



Joined: 05 Aug 2005
Posts: 71

PostPosted: Tue Aug 16, 2005 22:56    Post subject: Reply with quote

ok, yes, barked up the wrong tree.

Apparently looping thru certain PCs inventories causes this.

Anyone know how many instructions before bioware cancels with TMI Error?

The PC in question had a recorded value of 413 - and i am not even sure if that was totally accurate.


Anyone know how I could possibly NOT loop through 99 arrows in a stack? I think its ridiculous that it would loop 99 times on 99 arrows when each time it returns the SAME EXACT VALUE as the other arrows in the stack. Same object, same stacksize, same stacked amt, etc. ARG!
Back to top
View user's profile Send private message
Acrodania



Joined: 02 Jan 2005
Posts: 208

PostPosted: Wed Aug 17, 2005 0:06    Post subject: Reply with quote

Looping through stacked items is a known issue and one reason that some PWs don't allow magic bags/bags of holding. No way around it.... I know that I have several players that between arrows and potions can run over 10k things in their inventory. Pack rats! Laughing

I read in a thread back a while ago that the maximum executions (loop, GetVariable, etc) you could perform in a single script before getting a TMI was around 65,000 which makes some sense if its a 16 bit stack (65,536). It seems like a lot but its really easy to to hit.
Back to top
View user's profile Send private message
Alosynth



Joined: 06 Jan 2005
Posts: 24

PostPosted: Wed Aug 17, 2005 3:02    Post subject: Reply with quote

I don't know how this would work for looping through inventories, but it might be worth a shot.

You could put a fail-safe into main loop that stops it from looping after a certain number of loops (say 100) when/if that number is hit, the loop breaks and a recursive function is called that continues to go through another 100 items before breaking and re-calling itself. I don't believe that there is a GetNthItemInInventory type function, but if you include the last object that was set as the focused object, using GetNext should continue on without skipping or repeating any items in inventory.

For example:
Code:
DoInventoryLoop (object oItem) {
  int nCount = 0;
  while(GetIsObjectValid(oItem) && nCount <= 100) {
    {/* Do what ever it is your doing with the items here */}
    ++nCount;
    oItem = GetNextItemInInventory(oPC);
  }

  // if there is still a valid item, do it again, else we're done
  if(GetIsObjectValid(oItem)) {
    DelayCommand(1.0, DoInventoryLoop(oItem));
  }
}

void main () {
  object oPC; // Define the PC in some way
  object oItem = GetFirstItemInInventory(oPC);
  DoInventoryLoop(oItem);
}


It may need some tweaking to do what you need (or even to work) since I just wrote this off the top of my head and have never tried this.
Back to top
View user's profile Send private message
dguntner



Joined: 31 Dec 2004
Posts: 116

PostPosted: Wed Aug 17, 2005 4:46    Post subject: Reply with quote

weldieran - now there's a name I haven't seen in a while.... Mr. Green

You're right, Alosynth - players do tend to be pack-rats. And with a persistent container, once TMI is hit, they tend to lose whatever might have been left in the database table storing their stuff. Thanks for posting that - you reminded me that I need to do something along the lines of what you posted, to keep the TMIs away. Very Happy

--Dave
Back to top
View user's profile Send private message
weldieran



Joined: 05 Aug 2005
Posts: 71

PostPosted: Wed Aug 17, 2005 17:48    Post subject: Reply with quote

But wouldn't it be necessary to utilize ExecuteScript in your theory Alosynth?

If its 65k instructions allowed per script before TMI, then your example would n't do the trick would it?

And then if we did use executescript, do you still think "GetNextItemInInventory" will still truly call the next item - being that it is in seperate script?

And does ExecuteScript really get its own max before TMI, or is it all added together to the main calling script?


I did a test on an inventory stocked full of 99 arrow stacks. For each item in inventory, I wrote ObjectToString to the log. It didn't report 99 arrows in each stack, but rather just the stacks themselves.

So is this perhaps an old tale no longer true? I would've expected 99 of the same ObjectToString for each stack *boggle*
Back to top
View user's profile Send private message
Primogenitor



Joined: 08 Jan 2005
Posts: 88

PostPosted: Wed Aug 17, 2005 21:12    Post subject: Reply with quote

weldieran wrote:
But wouldn't it be necessary to utilize ExecuteScript in your theory Alosynth?

If its 65k instructions allowed per script before TMI, then your example would n't do the trick would it?
The delay command splits it up. You can use either ExecuteScript or DelayCommand.
Quote:

And then if we did use executescript, do you still think "GetNextItemInInventory" will still truly call the next item - being that it is in seperate script?
Yes, provided nothing else changes the pointer e.g. deleting an item, adding an item, a different loop.

Quote:
I did a test on an inventory stocked full of 99 arrow stacks. For each item in inventory, I wrote ObjectToString to the log. It didn't report 99 arrows in each stack, but rather just the stacks themselves.

So is this perhaps an old tale no longer true? I would've expected 99 of the same ObjectToString for each stack *boggle*
The problem is with containers. Since a container basically expands the inventory space of the PC, if each container is full of small items, such a potion stacks or arrow stacks, plus the original inventory is full of containers, the loop gets very very large.
Back to top
View user's profile Send private message
Papillon
x-man


Joined: 28 Dec 2004
Posts: 1060
Location: Germany

PostPosted: Wed Aug 17, 2005 23:09    Post subject: Reply with quote

It's also interesting that the hardcoded maximum number of instructions before a TMI occurs is measured in virtual machine instructions - which resembles assembler a bit, i.e. NWScript instructions are resolved into several small VM instructions. That's the main reason why one loop TMI's while another similar one does not.

It also only counts towards the maximum if there is no interruption in between, which can be caused e.g. by ExecuteScript. Each interruption resets the counter.
_________________
Papillon
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
weldieran



Joined: 05 Aug 2005
Posts: 71

PostPosted: Wed Aug 17, 2005 23:26    Post subject: Reply with quote

Good to know execute script resets that counter.

In my own tests, it appears that when a PC first enters the world, it processes all the inventory (on acqurie fires for each item) before it fires onClientEnter.

However, it seems there are sometimes when this doesn't happen? Anyone have any definitives about this?

Some people end up with two PCWands when they should only EVER have one. The onClientEnter checks for the item, if not found, creates one. So why is it onClientEnter sometimes seems to fire before all the inventory is on the person?

is it just me or is biowares crap extremely querky?
Back to top
View user's profile Send private message
Acrodania



Joined: 02 Jan 2005
Posts: 208

PostPosted: Thu Aug 18, 2005 0:59    Post subject: Reply with quote

From what I've heard others discussing (with situations like yours) is that when the character enters the module, it cycles the entire PC's inventory and fires the OnAquire script for each one.

I solved my issues with OnEnter() not creating/finding items correctly by using a DelayCommand of 5 seconds and doing all my checks in that script instead of the default OnEnter().
Back to top
View user's profile Send private message
Primogenitor



Joined: 08 Jan 2005
Posts: 88

PostPosted: Thu Aug 18, 2005 9:10    Post subject: Reply with quote

Yes, last time I checked it fires OnAquire for all items, OnEquip for all equiped items, then it fires the module OnEnter, then the areas OnEnter. I dont know if it doesnt fire events and/or fires twice in any conditions, but I suspect it may be lag-related (i.e in a small test it doesnt, but in a "real" module it does).
Back to top
View user's profile Send private message
weldieran



Joined: 05 Aug 2005
Posts: 71

PostPosted: Sat Aug 20, 2005 22:09    Post subject: onClientExit Reply with quote

Anyone know if onClientExit is fired properly for all logged in when server has been given command "exit" or "quit"?

Been having issues of loss of data, and i believe its due to onClientExit not firing on PCs when server performs a normal shutdown.
Back to top
View user's profile Send private message
dguntner



Joined: 31 Dec 2004
Posts: 116

PostPosted: Sat Aug 20, 2005 22:28    Post subject: Reply with quote

OnClientLeave fires, but from day one of this game, certain information about the exiting player is not available about the exiting player. GetPCPlayerName(), for one, will not function and will just return an empty string (because at that point the player is no longer in the game). I believe there are other things which also do not fucntion for the same reasons. Whether they leave the game via logging out or the server shutting down makes no difference.

--Dave
Back to top
View user's profile Send private message
Primogenitor



Joined: 08 Jan 2005
Posts: 88

PostPosted: Sun Aug 21, 2005 12:20    Post subject: Reply with quote

Any of the GetPC* fucntions I think fail to work. The solution is store then as local variable on the player when they log in.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    nwnx.org Forum Index -> General Discussion All times are GMT + 2 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group