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

Delay in sfx

I'm trying to get a series of explosions in a sequence, on different locations - basically a random x,y location using spawnFx  for the f/x, but having issues with trying to time them out. setTimeout() seems to just delay the group of explosions rather than spacing them out. Admittedly I don't understand setTimeout at all, figuring there has to be a better way to do this. for (let i=0;i<30;i++) { setTimeout(function() { dX = randomInteger(350) dY = randomInteger(350) x = targetToken.get("left") - 175 + dX; y = targetToken.get("top") - 175 + dY; sound = findObjs({type: "jukeboxtrack", title: "Explosion"})[0]; sound.set({playing: true,softstop:false}); spawnFx(x,y,"explosion-fire"); },500); }
1635389308
The Aaron
Roll20 Production Team
API Scripter
Try: for (let i=0;i<30;i++) { setTimeout(function() { dX = randomInteger(350) dY = randomInteger(350) x = targetToken.get("left") - 175 + dX; y = targetToken.get("top") - 175 + dY; sound = findObjs({type: "jukeboxtrack", title: "Explosion"})[0]; sound.set({playing: true,softstop:false}); spawnFx(x,y,"explosion-fire"); },500 *i ); }
1635390837
David M.
Pro
API Scripter
I feel I should mention that I have experienced occasional unpredictable lag with fx triggered via api. Sometimes it's amazing and exactly the timing I intended, while other times the same code results in several seconds of delay and my entire map exploding with everything at once (with sometimes very choppy animation). Might be the crappy laptop I run Roll20 on, might be something server-side. So, YMMV.
Thanks guys for the replys. The Aaron's suggestion works. I am sure I would not have thought of this, I was thinking too much of serial execution, not this essentially parallel execution.  Asynchronicity makes:
1635393954
The Aaron
Roll20 Production Team
API Scripter
Legit, it takes some serious getting used to if you haven't worked with it before. You could also write it like this, which might help with David's clustering issue: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const CreateExplosion = () => { dX = randomInteger ( 350 ) dY = randomInteger ( 350 ) x = targetToken . get ( "left" ) - 175 + dX ; y = targetToken . get ( "top" ) - 175 + dY ; sound = findObjs ({ type : "jukeboxtrack" , title : "Explosion" })[ 0 ]; sound . set ({ playing : true , softstop : false }); spawnFx ( x , y , "explosion-fire" ); }; let numExplosions = 30 ; const ChainExplosions = () => { if ( numExplosions -- ){ CreateExplosion (); setTimeout ( ChainExplosions , 500 ); } }; ChainExplosions (); Lines 11-20 will probably make your brain hurt, but let me explain the difference. In the original code I posted, the execution of immediately schedules 30 timeouts at 0ms, 500ms, 1000ms, ... 15000ms.  setTimeout() sets the minimum amount of time before the function gets called.  That means if you specified 500, it will always be at least 500ms before being called (usually ~507ms or so), but it could be much, much longer.  The reason is that Javascript is single threaded, and basically uses cooperative multitasking.  If something is running and doesn't return control to the virtual machine, then whatever is waiting to run won't get run for a while.  If you've seen the "possible infinite loop detected" error when something runs for too long, that's exactly what's happened.  There is a watchdog timer inside the sandbox virtual machine that is monitored by another process.  If control doesn't return to the virtual machine so it can reset that timer, the external process kills the sandbox. The code here on lines 11-20 is set up to instead have each explosion schedule the next explosion when it happens.  That means if he first one doesn't go off until 1673ms, the earliest the next could happen would be 2173ms.  Line 11 sets up the number of times to call the explosion Line 13 defines the chain explosions function.  Line 14 checks that there are still explosions to schedule and decrements the number of explosions left to do.  Line 15 calls the function to create the explosion (it gets targetToken from the outer scope via a Closure) Line 16 schedules the next explosion for 500ms from this one Line 20 starts the first explosion.
If you run this in a session on the dev server it will be highly reactive and reliable.  If you run it on production at 8pm on the weekends EST, its going to lag out and all fire at once 4 minutes after you press the button, roll20 does not handle /fx right sadly and never has.  They don't dedicate enough hardware to hosting the service.  
The code is making more sense thanks. and yes I have experienced the lag of sfx before, can be very weird sometimes. 
And Aaron, thank you so much for all the help you give (to me and others) on this forum. Putting the code down and then explaining what each part does is incredibly helpful AND educational - you really have a talent both for coding and for teaching. Cheers!
1635438791
The Aaron
Roll20 Production Team
API Scripter
No problem, I love talking about code, I'm happy to do it any time!&nbsp; If you have any code you want explained, feel free to post it and I'll tease out the details for you. =D&nbsp; I think that benefits the whole community, and often these discussions turn into a thread that I save and pass off to people wanting to learn to write API scripts.&nbsp; For example: <a href="https://app.roll20.net/forum/permalink/6605115/" rel="nofollow">https://app.roll20.net/forum/permalink/6605115/</a> <a href="https://app.roll20.net/forum/permalink/6584105/" rel="nofollow">https://app.roll20.net/forum/permalink/6584105/</a> <a href="https://app.roll20.net/forum/permalink/6237754/" rel="nofollow">https://app.roll20.net/forum/permalink/6237754/</a>