Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

[HELP] Script goes into an infinite loop whenever I try to change a variable

1536064659
Missingquery
Pro
Sheet Author
API Scripter
//Attack multiplier for stuff like Astra if (obj.attack_multiplier != 0 && combat != false) { let mult = obj.attack_multiplier; if (DoubledB) { //needs to be adjusted to be user-agnostic mult -= 1; //check if user has doubled yet if (TripledB) { mult -= 1; //tripled? if (QuadedB) { mult -= 1; //quadrupled? } } } for (i = 0; i < mult; i++) { if (randomInteger(100) < (MHitU - MAvoE)) { Chatstr += '<p style = "margin-bottom: 0px;">' + UName + " hits for " + Dmg_U + " damage! </p>"; //Check if attack crits if (randomInteger(100) < (MCritU - MDdgE)) { Dmg_U *= 3; Chatstr += '<p style = "margin-bottom: 0px;">' + UName + " crits for " + Dmg_U + " damage! </p>"; hasCritB = true; } Temp_HPE -= Dmg_U; DmgtotalA += Dmg_U; CurrHPE.set("current", Temp_HPE); log(CurrHPE); log(CurrHPU); //Nobody gets any WEXP for now //DecUsesB(); log("Decreased weapon uses!"); if (hasCritB) { Dmg_U /= 3; hasCritB = false; } } else { Chatstr += '<p style = "margin-bottom: 0px;">' + UName + " misses! </p>"; } } DoubleB = false; //likewise, needs to be adjusted to be user-agnostic DisableatkB = true; if (user == "attacker"){ //here is where the problem is //HPB = Temp_HPE; } else { HPA = Temp_HPE } } The full script can be found here . So I keep trying to change this one global variable named HPB (representing the numerical HP value of the secondary character), but whenever I attempt to do so within the Skill() function, the console throws me an infinite loop error. Which is odd, because HPB isn't linked whatsoever to any loops at all in the script- I checked. Any help would be appreciated, because I'm honestly stumped. (For context- I decided to globalize the Skill() function as opposed to having 4 slightly different versions in different scripts, but as a result, I had to globalize some variables that used to be within the scope of the localized versions, HPB being one of them.)
1536066827

Edited 1536067027
The Aaron
Pro
API Scripter
That error isn't about a loop in the "for", "while", etc sense.  It means your function takes longer to run than it is permitted to. The API Sandbox uses cooperative multitasking . The basic idea is that there is some controlling system (the API Sandbox) which executes sub operations (the API Scripts).  It doesn't have the capability to suspend them (like in preemptive multitasking), so all it can do is relinquish control to them for the duration of their execution.  There is a second controlling system (called a WatchDog) that monitors the API Sandbox.  Before the Sandbox runs a script, it sends a message to the WatchDog.  When the script finishes, it sends another message to the WatchDog.  If the time between those two messages is over some threshold (i.e. the WatchDog doesn't hear back in time), the WatchDog kills the Sandbox with the message "Possible Infinite Loop Detected". The practical upshot of all that is that setting HPB causes the execution to take to long.  It's unlikely that the actual act of setting it is the issue, but some side effect of having it set.  I'd look for some place that HPB is used to determine if something is executed, which might lead to recursion.  You'll likely need to add a bunch of log statements to track down what is happening.  It might be somewhat removed from the HPB variable, but a chain of events set in motion by having a value in HPB.
1536094584
Missingquery
Pro
Sheet Author
API Scripter
Hmmm, no dice. Ctrl+F'ing HPB yielded only that it seems to be gotten and set fairly often, but the exact same things are happening to its twin variable, HPA, and that one seems to be working perfectly. I have no idea why setting only HPB in this specific function is causing it to take too long. If it's any help, the console seems to return the character id of the selected character before shutting down.
1536105135
The Aaron
Pro
API Scripter
There's too much going on in that script for me to help you with it, I'm afraid.  If you want to track down the issue, I'd suggest adding logging at the beginning of every function and at the return in every function (or end if there is no return).  I would also suggest adding a global integer for depth which starts at 0 and is incremented whenever you enter a function, and decremented when you leave it.  Use it to pad your output.  That should give you a good idea if there is infinite recursion occuring.
1536105919
The Aaron
Pro
API Scripter
Something like this: let depth = 0; const padStr = '. '; const pad = (str) => `${Array(Math.max(depth+1,0)).join(padStr)}${str}`; const enter = (funcName, args,msg) => { ++depth; if(msg){ log(`${funcName||'[UNKNOWN]'}:: ${msg}`); } log(pad(`-> ${funcName||'[UNKNOWN]'}(${JSON.stringify(args||[])})`)); }; const exit = (funcName,args,msg) => { --depth; if(msg){ log(`${funcName}:: ${msg}`); } log(pad(`<- ${funcName||'[UNKNOWN]'}(${JSON.stringify(args||[])})`)); }; Should help, just use it like this: function MyFunctionName(arg, argb,argc){     enter('MyFunctionName', {arg,argb,argc});     if( arg ){         exit('MyFunctionName', {arg,argb,argc}, "Returning arg+argb");         return (arg+argb);     }     exit('MyFunctionName', {arg,argb,argc}, "Returning argc");     return argc; } That will give you lines like . -> MyFunctionName({"arg":false,"argb":1,"argc":"taco"}) MyFunctionName:: Returning argc . <- MyFunctionName({"arg":false,"argb":1,"argc":"taco"}) With more and more . at the beginning for more depth: . . . -> foo({"a":"bar"}) Hope that helps.
1536338849

Edited 1536362801
Missingquery
Pro
Sheet Author
API Scripter
EDIT: I've figured out a workaround! But I seem to be having a similarproblem elsewhere, and it's kind of weird. var EXPAmod = 0         //...         //InLvB and InLvA are both ints         let leveldiff = InLvB - InLvA; let mod; //parseint breaks stuff for some reason???? if (leveldiff >= 0){ mod = parseInt((31 + leveldiff)/3); } else if (leveldiff == -1){ EXPAmod = 10; } else { mod = parseInt(Math.max((33 + leveldiff)/3, 1)); } log(mod); //EXPAmod = mod; So EXPAmod throws the thing into an infinite loop if uncommented. The weird thing is that if I eliminate the parseInts on the mod statements, EXPAmod works perfectly fine. I have no idea why it crashes the API if it's set to a value that was defined by a parseInt at any point in time. However, I can make an educated guess- I solved my last problem by commenting out all of the logs to speed up program time, and that magically fixed the infinite loop problem. I'm assuming it's some weird backend thread delay problem, but I'm not 100% sure. Given that I've commented out all the logs and am still experiencing this problem, I genuinely have no idea what else to do.