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 keeps getting hung up on certain variables

1536451297

Edited 1536451490
Missingquery
Pro
Sheet Author
API Scripter
I've posted about this problem before, but the problem seems to be extending itself to several variables. Take something as simple as this, for instance: //leveldiff is a positive/negative integer let mod = 0; //leveldiff is busted what if (leveldiff >= 0){ mod = (31 + leveldiff)/3; } else if (leveldiff == -1){ EXPAmod = 10; } else { mod = Math.max((33 + leveldiff)/3, 1); } log(Math.floor(mod)) Something like this makes the script take too long to execute. I was thinking before that the problem I was having (I posted about it in a previous topic) was that it didn't like the script getting and setting a global variable, which is fine, but something local and theoretically easy to compute like this makes the entire script freeze. Is it simply some memory management issue and I have too many global variables or something? What gives? And if it is some memory management issue, how can I fix it? The full script can be found here .
1536451712

Edited 1536451856
GiGs
Pro
Sheet Author
API Scripter
I am pretty sure that code isnt your problem, but something else in the macro. That's just a snippet, it's hard to tell where the problem may be without seeing the rest. If leveldiff is causing the problem, we'd need to see how that variable is being set, It's a pretty weird logical construction you have there though. If leveldiff = 0+, and -2 or less calculates mod, but at exactly -1 you dont do anything with mod and instead set a different attribute. also if leveldiff is -2 or less, mod cant be lower than 1, but if its 0 or higher, it can be. And mod can have fractional values, but in your log statement you remove the fractions.  Are you sure that construction is doing exactly what you need it to do?
1536452051
GiGs
Pro
Sheet Author
API Scripter
It's looking to me like EXPAmod should actually be mod, and that entire code block could be replaced by something like let mod = Math.round(leveldiff/3);
1536452558
GiGs
Pro
Sheet Author
API Scripter
I just registered this: Marth Lowell said: I was thinking before that the problem I was having (I posted about it in a previous topic) was that it didn't like the script getting and setting a global variable , which is fine, but something local and theoretically easy to compute like this makes the entire script freeze. Is it simply some memory management issue and I have too many global variables or something? What gives? And if it is some memory management issue, how can I fix it? The full script can be found here . If you have global variables, i would recommend you remove them, and just use them where needed, if possible. And i didnt notice you linked the script so I went and had a look. Oh my god, what a monster. Thats way too big for me to attempt to debug it. I copied your code to jshint , and it reported a lot of errors. It also noted you were using eval in the script, and I am going to go out on a very short limb and sugegst that that is the likely source of the script's issues. I suggest pasting the script into jshint and following its suggestions on how to fix the existing errors, and seeing how it goes. And also, look into replacing the eval code.
1536452859

Edited 1536452886
Missingquery
Pro
Sheet Author
API Scripter
Oh, I know for a fact eval isn't causing the problem- it's being triggered conditionally, and not in this condition. Unfortunately, I can't see a way around either not using the global variables or eval, since I literally need eval to parse expressions from strings, and I need to be able to use the global variables in multiple functions on the global scope.
1536453392

Edited 1536458007
GiGs
Pro
Sheet Author
API Scripter
You dont need to use eval to parse strings. Javascript has a lot of methods to manipulate strings. It looks to me like a lot of those big functions should be broken down into smaller ones, and most if not all of the global variables could be replaced with parameters that you pass from function to function as needed. With so many global functions, it's really hard to track how they are being set and changed, and you can't guarantee their values. It's also very easy for an error in one function to propagate to another function, without realising it.  I'd suggest creating a logger function like function logging(position) { log("=================================="); log("Position: " + position); log("variable1 name": variable1value); log("variable2 name": variable2value); } replace the variable1, variable2, with a list of every single global function. Then in each function, wherever problems are occurring, put the code: logging("line number 23"); This way you'll get a print out of all the global values at each problem point, and can analyse then to see if any are weird, undefined, or whatever. But I do think that script probably needs a major overhaul. There's not much beyond this advice I can do to help with its current form. I noticed that in the previous thread, Aaron abandoned any hope of figuring out the solution. Trust me, if Aaron  can't see a way to a solution, it's a lost cause. Frankly, I've never seen that happen before.
1536457321

Edited 1536457824
The Aaron
Pro
API Scripter
Yeah.  It's hard to debug something like this from the outside, and frankly, it's more effort than I want to put into it.  I have no idea what this script is supposed to do, only that it nebulously crashes at some point.  You didn't explicitly say it in this thread, but if it's getting a "possible infinite loop detected" error, it's taking too long to run somewhere.  As I mentioned in the other thread, if setting a variable causes something to run for too long, the problem is probably somewhere it branches based on that variable.  The eval() function is dangerous because of the potential for injection attacks (something you honestly don't have to worry about on Roll20's API Sandbox, you're the only user), but it also makes debugging difficult as you have even less visibility into the code as it executes than you do on API scripts.  But possibly more importantly, it's very slow. It basically has to spin up a mini-sandbox each time you call it, and you're calling it 15 times.  Additionally, we don't know what the implementation is like in the Roll20 sandbox, it's entirely possible that any crashes in eval()'d code will just hang, causing the a "possible infinite loop detected" because there isn't a connection between the eval()'s sandbox and the API sandbox.  Several of the eval() calls are being executed on obj properties that are not defined anywhere, which means you'd be eval()'ing undefined, which throws a SyntaxError exception.  (Those properties are coming out of whatever JSON is in the skillA and skillB, so who knows what it is...) Something else to consider is the attrLookup() and attrNameLookup() functions, both of which I wrote.  They are super handy for dealing with repeating group attributes in the API, but they are pretty expensive.  Each one does a 2 findObjs() calls and some complicated sorting.  They could be optimized with some caching, but avoiding calling them unless necessary would be a good idea. The code you linked has this in it: let leveldiff = InLvB - InLvA; let ohno = 0; //leveldiff is busted what if (leveldiff >= 0){ ohno = (31 + leveldiff)/3; } else if (leveldiff == -1){ ohno = 10; } else { ohno = Math.max((33 + leveldiff)/3, 1); } log(ohno) //EXPAmod = mod log(Math.floor(ohno)) //EXPAmod = mod; which I think is the code you're talking about in this thread.  Right after, it loops over all the SkillsA and SkillsB arrays and uses them in invoking the Skill() function.  The 8th (!!!) parameter to that function is the skill data from the SkillA and SkillB arrays.  The Skill() function will call eval() on 2 of that skill object's properties.  It then has several places where it will can call skillMain(), which then calls eval() on 8-10 other properties. The only way to track down this bug is to log things like crazy and analyze where it's going.
1536471095
Jakob
Sheet Author
API Scripter
Honestly, for any kind of code that contains eval(), you pretty much have to give up debugging it ... better write your own parser for the kind of expressions you want to evaluate, I'm pretty sure that you don't need the full power of eval to parse whatever this skill needs to parse. Furthermore, unless you're using them as some kind of cache or database, you can probably avoid the use of globals by just passing around values as function parameters instead ... but perhaps you should also cut down the number of function parameters if I'm reading The Aaron correctly :D. In any case, this script is a good example of why you shouldn't write methods that do not fit on one screen!