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 .
×

Allowing a script to sleep?

I have a long complex algorithm I'm running to process a TSV file into useable infomation that will then go into a map by generating the tiles and lighting. it works but the system seems to think that I've hit an endless loop (I havent it just a long loop) is there a way to allow the thread to sleep and let the sandbox get a fresh cycle before moving on? then I can just do it row by row and allow a wait between row change.
1488081357
The Aaron
Pro
API Scripter
Sure!  I use _.delay and _.defer for this all the time. 
1488081381

Edited 1488081394
The Aaron
Pro
API Scripter
See: <a href="http://underscorejs.org" rel="nofollow">http://underscorejs.org</a>
Thanks!
1488088102

Edited 1488088135
PaprikaCC
API Scripter
Wait that's possible?! I have a script that constantly times out because the sandbox thinks it's in a loop, but it's really just because it's looking through a lot of objects. How could I use delay and defer if I'm not sure how long I should delay and defer by (and if I need to do it multiple times)? Script in question . It works fine in a fresh campaign with little characters and handouts inside, but I was using this to gather statistics about ~40 characters in a Living World style game. Using it to find level and racial breakdown worked, but it always timed out when I tried to find class level totals.
1488133029

Edited 1488133160
The Aaron
Pro
API Scripter
The basic technique is to create work queues and then process them in small chunks asynchronously. &nbsp;Your countCharacterClasses would look something like this: (untested!) &nbsp; &nbsp; countCharacterClasses = function(msg, namearray){ &nbsp; &nbsp; &nbsp; &nbsp; state.CharacterCount.active = true; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('Character Count', `/w ${msg.who}&lt;br&gt; Checking Classes now!`, null, {noarchive:true}); &nbsp; &nbsp; &nbsp; &nbsp; // build classes count object: { ranger: 0, monk: 0, ... } &nbsp; &nbsp; &nbsp; &nbsp; let classes = _.object( namearray, _.times( namearray.length, _.constant(0) ) ), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // setup work queue: [ {id: -kJas123123af, name: 'ranger'}, ... ] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; work = _.chain(characterlist) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .pluck('id') //&lt; gets id from characterlist &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .reduce((m, id)=&gt;{ &nbsp; &nbsp; //&lt; builds the {id: ..., name: ...} objects &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.each(namearray,(n)=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m.push({id:id,name:n}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return m; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },[]) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .value(), //&lt; returns the array of objects &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // create a function that handles a single instance&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // of {id: ..., name: ...} or reports if there aren't any more. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; workQueue = ()=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // checks if there are things left to work on &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(work.length){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // removes the next thing in the list &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let part = work.shift(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // adds the levels of the class or 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; classes[part.name]+=parseInt(getAttrByName(part.id,`${part.name}_level`),10)||0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // defers calling itself for the next bit of work. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // could use _.delay(workQueue,10) or similar &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.defer(workQueue); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // if there is nothing left in the work queue, output the data. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printOutput(classes,'Combined Class levels', msg); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // kick of the first iteration of workQueue &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; workQueue(); &nbsp; &nbsp; }, This will be Asynchronous, so wherever you're calling countCharacterClasses(), it will return immediately. Just as an aside,&nbsp;anywhere you can use findObjs() followed by _.filter() instead of filterObjs(), it will be much faster because of the new indexing.
Wow, thanks!