Aller au contenu

Photo

How DelayCommand() works in this case?


  • Veuillez vous connecter pour répondre
16 réponses à ce sujet

#1
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

Hello Scripters, 

 

I have just two question of this issue:

 

1) In this case, supposing that the integer variable "Aaaaa" could change because another event script, what happens in the check of the void "doCheck()"? The iCurrentVal variable will be different of the iInitialVal?

 

2) Do the loop here works fine? The object oAny will be unique because of the delay of 60 seconds or only one? What happens with the loop when we have delay inside?

void doCheck(object oPC, int iInitialVal)
{
	int iCurrentVal = GetLocalInt(oPC, "Aaaaa");
	if(iCurrentVal == iInitialVal)
	{
		// * The actions I want that must be added here.
	}
}

void main()
{
	object oAny = GetFirstPC();
	int iInitialVal;

	while(GetIsObjectValid(oAny))
	{
		SetLocalInt(oAny, "Aaaaa", Random(999999)+1);
		iInitialVal = GetLocalInt(oAny,"Aaaaa");
		DelayCommand(60.0, doCheck(oAny, iInitialVal)); 
		oAny = GetNextPC();
	}
}


#2
Tarot Redhand

Tarot Redhand
  • Members
  • 2 688 messages

Before I answer your queries, you might like to consider this more efficient alternative version of your void main function.

void main()
{
    object oAny = GetFirstPC();
    int iInitialVal = Random(999999)+1;

    while(GetIsObjectValid(oAny))
    {
        SetLocalInt(oAny, "Aaaaa", iInitialVal);
        DelayCommand(60.0, doCheck(oAny, iInitialVal)); 
        iInitialVal = Random(999999)+1;
        oAny = GetNextPC();
    }
}

To answer your questions

 

  1. It depends on what the other event does to "Aaaaa". The function doCheck tests iInitialVal against iCurrentVal at the time that doCheck actually executes.
  2. Yes the loop will work fine. oAny will be unique. The delay does not affect the loop, only when the function doCheck actually fires. One possible problem with your code as it stands is that oPC may have left the pw in that 1 minute delay. To prevent this you could use -
void doCheck(object oPC, int iInitialVal)
{
    if(!(GetIsPC(oPC)))
        return;    ...
One other thing. Studying either version of the lexicon can help when you have queries about such things as this.
 
TR

  • WhiteTiger aime ceci

#3
MrZork

MrZork
  • Members
  • 941 messages

What TR said, particularly that DoCheck should probably have a call to GetIsObjectValid(oPC).

 

I am curious what the purpose of the script is? Specifically, why the random number? It almost appears like an attempt to have something happen 1 in 999999 times unless some other script changes local in Aaaaa. But, it seems more likely that, whatever the random number is, unless something changes Aaaaa in the intervening seconds, the other actions in DoCheck always happen 60 seconds later, and they still rarely happen even if some other script has changed Aaaaa, unless that other script sets Aaaaa to something outside the range [1, 999999].


  • WhiteTiger aime ceci

#4
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

What TR said, particularly that DoCheck should probably have a call to GetIsObjectValid(oPC).

 

I am curious what the purpose of the script is? Specifically, why the random number? It almost appears like an attempt to have something happen 1 in 999999 times unless some other script changes local in Aaaaa. But, it seems more likely that, whatever the random number is, unless something changes Aaaaa in the intervening seconds, the other actions in DoCheck always happen 60 seconds later, and they still rarely happen even if some other script has changed Aaaaa, unless that other script sets Aaaaa to something outside the range [1, 999999].

 

Sorry, I does not use GetFirstPC() and GetNextPC() in my original code. I use GetFirstObjectInArea() and GetNextObjectInArea(). This script fires ondamaged, so the 1/999.999 chance isn't for rarely happen, is for never happen.



#5
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

TR why you deleted it?
 

SetLocalInt(oAny, "Aaaaa", Random(999999)+1;
iInitialVal = GetLocalInt(oAny, "Aaaaa");

the Random() function has a bug when you use this directly has ever a different value according my experiences



#6
Tarot Redhand

Tarot Redhand
  • Members
  • 2 688 messages
Yes Random has a bug. That bug means that you get the same sequence of numbers produced for any given area. It only affects mp/pw games when there is one and only one PC playing. The way that the start point in the list of numbers produced is by taking numeric bits from certain parts of an area. This information is in the lexicon. I double checked both versions of the lexicon to make sure. The method that you are using to try to get around this will not work according to the information in the lexicon (if it does work, get in touch with the people behind the lexicon so they can alter it). If you are worried about this bug put a call to this little function in your void main() before Random is called.
void PseudoRandomise()
{
    intMaxIteration = GetTimeMillisecond() + 100;
    int iIndex;
    int iDummy;


    for(iIndex = 0 ; iIndex < intMaxIteration ; iIndex++)
        iDummy = Random(iIndex + intMaxIteration);
)
In answer to your question as to why I changed it, I did so because my version is both more efficient and more elegant.
 
Now for the Really bad news. The only object that has a chance of doing the actions that you want in doCheck is the very last one found. There is a very remote chance that the other event script that you mention in your 1st question could alter the variable "Aaaaa" so that it matches a different object but the chances of this happening are vanishingly small.
 
The reason why is as follows. Each time through your while loop the value of "Aaaaa" is changed. All that the DelayCommand function does is to place the call to the delayed function on a list of functions that will be executed later. Once it has done that the next instruction in your loop is executed. As this happens very fast and you have a delay of 60 seconds the only value for "Aaaaa" your delayed function calls will all see is the very last one generated.
 
TR

  • WhiteTiger aime ceci

#7
WhiZard

WhiZard
  • Members
  • 1 204 messages

 

Yes Random has a bug. That bug means that you get the same sequence of numbers produced for any given area.

 

 

Do you have solid evidence of this?  I have seen the bug reported on many posts of the past, some with extensive calculations (which are now retracted) for determining exactly the seed, but when tested over the last five years, no one has been able to replicate these circumstances.  No matter where the random number is being calculated (client enter, module enter, area enter) there keeps on being a different seed value.


  • WhiteTiger aime ceci

#8
Tarot Redhand

Tarot Redhand
  • Members
  • 2 688 messages

I have not done any testing on this. I rely on what's in the lexicon (both versions). TBH I wasn't even aware there might be a problem until WhiteTiger mentioned it. At that point I checked first the downloadable (and so much easier to search) lexicon 1.69. I then checked the online version to be sure there hadn't been any updates to that information. Not being as knowledgeable about NwN script as some people on here are, I rely on the lexicon and trust what is written therein. Assuming that it is correct I wrote that small PseudoRandomise routine which should go some way to mitigating any such bug as is reported in the lexicon.

 

TR



#9
Proleric

Proleric
  • Members
  • 2 356 messages
The Lexicon is very reliable, but, like any wiki, there are occasional errors. If other people have verified this one, I'll change it.

#10
WhiZard

WhiZard
  • Members
  • 1 204 messages


The Lexicon is very reliable, but, like any wiki, there are occasional errors. If other people have verified this one, I'll change it.

 

There are a lot of old conversations to dig through, but if you want a completely independent source try this one.  Notice toward the bottom a second statistical tests was performed for the reseeding (which does not reseed to the same value).


  • Proleric aime ceci

#11
Proleric

Proleric
  • Members
  • 2 356 messages
I changed the wiki, leaving the alleged bug details on the discussion page, in case anyone wants to make a case for it.

Evidently, measurement shows no significant bias in the random numbers, which is consistant with Acaos's finding that the server timestamp is used to reseed the function.

#12
Tarot Redhand

Tarot Redhand
  • Members
  • 2 688 messages

Which is all fine and dandy for pw's but what about sp mods? Do the claims that were on the lexicon hold or not in that case?

 

TR



#13
WhiZard

WhiZard
  • Members
  • 1 204 messages

Which is all fine and dandy for pw's but what about sp mods? Do the claims that were on the lexicon hold or not in that case?

 

TR

 

The claims do not hold at all for SP mods.  Random() does not just reset to the same seed.



#14
Proleric

Proleric
  • Members
  • 2 356 messages
Since the engine seeds from the timestamp, you'd expect SP to be equally random. My latest SP module does a bunch of random stuff on first area entry, which turns out different every time, so it's good enough, for practical purposes.

#15
Tarot Redhand

Tarot Redhand
  • Members
  • 2 688 messages

I am glad we have apparently cleared that up. Is it possible that this bug existed in previous versions of NwN but was fixed in a more modern (i.e. 1.65, 1.67, whatever) and we just weren't told?

 

TR



#16
WhiZard

WhiZard
  • Members
  • 1 204 messages

If it existed at all it would have been before the release of the Platinum Edition (whichever patch that was).



#17
Proleric

Proleric
  • Members
  • 2 356 messages
That was my first instinct, but I couldn't find a reference in any of the patch release notes on NWNWiki, which I checked as due diligence before changing the Lexicon. At any rate, if there ever was a problem, it's now fixed.