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

Why isnt this firing my timed events?

1708543160

Edited 1708549035
GM
Pro
I'm making an End Credits for my campaign sessions using a setInterval to time some events. Those timed events aren't firing, and i think it's something to do with the   ecCounter variable iteration, or reading the values of it in the if statements. HELP! CODE IS BELOW on("ready",function(){         var flip;     var ecCounter = 0;     on("change:campaign:playerpageid",function(){         var currentPage = getObj("page",Campaign().get("playerpageid"));         sendChat("api","!token-mod --config players-can-ids|on");         if (currentPage.get("name")=="ECGloria"){             flip = setInterval(flipper, 5000);         }         else {             clearInterval(flip);             flip = null;         }              function flipper(ecCounter){             ecCounter += 5;             if(ecCounter === 5){                 sendChat("API","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBaVr_xm4BdIXBIoGG --set layer|gmlayer");             }             if(ecCounter === 10){             }             else if(ecCounter === 30){                 sendChat("API","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set layer|token");                 sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set currentside|1");                             }             else if(ecCounter === 45){                 sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set currentside|2");                          }             else if(ecCounter === 60){                 sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set currentside|3");                                           }             else if(ecCounter === 75){                 sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set currentside|4");                          }             else if(ecCounter === 95){                 sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set currentside|5");                              }             else if(ecCounter === 105){                 sendChat("API","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set layer|gmlayer");                 sendChat("API","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBgFNKcTQ2UNDReKGw --set layer|token");             }             else if(ecCounter === 160){                 //black screen w final messsage                              }             //sendChat("api","!token-mod --config players-can-ids|on");             //sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NobNO6uHnya6FmREuhJ --set currentside|*");             //sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NobNNjT4sLnOW64Qbau --set currentside|*");         }     });     });
I suspect it has something to do with not recognizing (or maybe setting) the value for ecCounter
1708550019
The Aaron
Roll20 Production Team
API Scripter
You're on the right track.  What is happening is your definition of ecCounter on about the 3rd line is not being used for anything.  Your function flipper takes as argument a variable with the same name, but that will shadow the variable by that name in the outer scope.  Since setInterval() does not pass arguments to the function it calls, the ecCounter argument to flipper will be assigned the value undefined.  When you +=5 it, it will then become NaN.  NaN doesn't match anything (not even itself), so none of your if cases are firing. If you remove the argument to flipper, then it won't shadow the outer ecCounter variable, and will likely work as intended, or at least get you closer to what you want.  You can use the log() function to take a look at things in your script, which can make debugging things like this faster: log(`ecCounter has the value: ${ecCounter}`);
Fixed that, and TYVM getting this output: "Map Change Started" "Blocked Players" [] "Maps Constructed" "Map Change Ready" "ecCounter has the value: 0" "Change Handler" "Track ID:-Nr6Wbw-YHSpzKoEZOfH" "Track Finished:Gleave5 " "Output Config:undefined" TypeError: Cannot read properties of null (reading 'indexOf') TypeError: Cannot read properties of null (reading 'indexOf')     at d20.textchat.doChatInput (eval at <anonymous> (/home/node/d20-api-server/api.js:172:1), <anonymous>:332:18)     at sendChat (/home/node/d20-api-server/api.js:1920:16)     at outputConfig (apiscript.js:341:13)     at changeHandler (apiscript.js:751:21)     at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:168:1), <anonymous>:65:16)     at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:168:1), <anonymous>:70:8)     at TrackedObj.set (/home/node/d20-api-server/api.js:1107:14)     at updateLocalCache (/home/node/d20-api-server/api.js:1442:18)     at /home/node/d20-api-server/api.js:1656:7     at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 "Loading character sheet data..." ______________________________ on("ready",function(){         var flip;     var ecCounter = 0;     on("change:campaign:playerpageid",function(){         var currentPage = getObj("page",Campaign().get("playerpageid"));         var ecCounter = 0;         sendChat("api","!token-mod --config players-can-ids|on");         if (currentPage.get("name")=="ECGloria"){             log(`ecCounter has the value: ${ecCounter}`);             flip = setInterval(flipper, 5000);         }         else {             clearInterval(flip);             flip = null;         }              function flipper(){             log(`ecCounter has the value: ${ecCounter}`);             ecCounter +=5;             if(ecCounter === 5){                 sendChat("API","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBaVr_xm4BdIXBIoGG --set layer|gmlayer");             }             if(ecCounter === 10){             }             else if(ecCounter === 30){                 sendChat("API","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set layer|token");                 sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set currentside|1");                             }             else if(ecCounter === 45){                 sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set currentside|2");                          }             else if(ecCounter === 60){                 sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set currentside|3");                                           }             else if(ecCounter === 75){                 sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set currentside|4");                          }             else if(ecCounter === 95){                 sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set currentside|5");                              }             else if(ecCounter === 105){                 sendChat("API","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBloLVocW0LFFdNToD --set layer|gmlayer");                 sendChat("API","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NrBgFNKcTQ2UNDReKGw --set layer|token");             }             else if(ecCounter === 160){                 //black screen w final messsage                              }             //sendChat("api","!token-mod --config players-can-ids|on");             //sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NobNO6uHnya6FmREuhJ --set currentside|*");             //sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NobNNjT4sLnOW64Qbau --set currentside|*");         }     });     });
and this _________________ Your scripts are currently disabled due to an error that was detected. Please make appropriate changes to your script's code and click the "Save Script" button. We will then attempt to start running the scripts again.  More info...  If this script was installed from the Mod Library, you might find help in the Community API Forum. For reference, the error message generated was:  TypeError: Cannot read properties of null (reading 'indexOf') TypeError: Cannot read properties of null (reading 'indexOf') at d20.textchat.doChatInput (eval at <anonymous> (/home/node/d20-api-server/api.js:172:1), <anonymous>:332:18) at sendChat (/home/node/d20-api-server/api.js:1920:16) at outputConfig (apiscript.js:341:13) at changeHandler (apiscript.js:751:21) at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:168:1), <anonymous>:65:16) at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:168:1), <anonymous>:70:8) at TrackedObj.set (/home/node/d20-api-server/api.js:1107:14) at updateLocalCache (/home/node/d20-api-server/api.js:1442:18) at /home/node/d20-api-server/api.js:1656:7 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560
1708553916

Edited 1708553945
The Aaron
Roll20 Production Team
API Scripter
This doesn't have to do with the error, but I do want to point out that your ecCounter variable on about line 3 is now being shadowed by your ecCounter variable on  about line 6.   It's hard to say what the issue above is.  It seems to be happening in another script, something with a changeHandler() function and outputConfig() function.  Just based on the log messages, I'm guessing it does something with the jukebox... Ok, looks like it's Roll20 Audio Master.  The reason it's crashing is likely because some of your sendChat calls have 'api' instead of 'API', and it's trying to look up the player 'api', failing, but then passing undefined as the first argument to it's own sendChat() call, which is resulting in a crash in the API sandbox. Honestly, I would not use sendChat() to do this with TokenMod.  I'd just get the object yourself in the API side and make the adjustments needed.  This is what it would look like to translate what you have into directly manipulating the graphics.  This probably isn't exactly the way I'd do it, but I don't know exactly what you're trying to do: on("ready",function(){ let flip; let ecCounter = 0; const decodeSides = (s) => s.length ? s.split("|").map(i=>unescape(i)) : []; const flipper = () => { log(`ecCounter has the value: ${ecCounter}`); ecCounter +=5; if(ecCounter === 5){ let t = getObj('graphic', '-NrBaVr_xm4BdIXBIoGG'); if(t) { t.set({ layer: 'gmlayer' }); } } if(ecCounter === 10){ // } else if(ecCounter === 30){ let t = getObj('graphic', '-NrBloLVocW0LFFdNToD'); if(t) { let sides = decodeSides(t.get('sides')); t.set({ layer: 'objects', imgsrc: sides[1], // note that sides is zero-biased, so the first image is 0, 1 is the second, etc. currentside: 1 }); } } else if(ecCounter === 45){ let t = getObj('graphic', '-NrBloLVocW0LFFdNToD'); if(t) { let sides = decodeSides(t.get('sides')); t.set({ imgsrc: sides[2], currentside: 2 }); } } else if(ecCounter === 60){ let t = getObj('graphic', '-NrBloLVocW0LFFdNToD'); if(t) { let sides = decodeSides(t.get('sides')); t.set({ imgsrc: sides[3], currentside: 3 }); } } else if(ecCounter === 75){ let t = getObj('graphic', '-NrBloLVocW0LFFdNToD'); if(t) { let sides = decodeSides(t.get('sides')); t.set({ imgsrc: sides[4], currentside: 4 }); } } else if(ecCounter === 95){ let t = getObj('graphic', '-NrBloLVocW0LFFdNToD'); if(t) { let sides = decodeSides(t.get('sides')); t.set({ imgsrc: sides[5], currentside: 5 }); } } else if(ecCounter === 105){ let t = getObj('graphic', '-NrBloLVocW0LFFdNToD'); if(t) { t.set({ layer: 'gmlayer' }); } let t2 = getObj('graphic', '-NrBgFNKcTQ2UNDReKGw'); if(t2) { t.set({ layer: 'objects' }); } } else if(ecCounter === 160){ //black screen w final messsage } //sendChat("api","!token-mod --config players-can-ids|on"); //sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NobNO6uHnya6FmREuhJ --set currentside|*"); //sendChat("api","!token-mod --api-as -NgLL39aMVMGSgYa69Tq --ids -NobNNjT4sLnOW64Qbau --set currentside|*"); }; on("change:campaign:playerpageid",function(){ let currentPage = getObj("page",Campaign().get("playerpageid")); if (currentPage.get("name")=="ECGloria"){ log(`ecCounter has the value: ${ecCounter}`); flip = setInterval(flipper, 5000); } else { clearInterval(flip); flip = null; } }); });
this is way beyond where I am currently in terms of knowledge, but it's amazeballs. It's also a new goal... learn how to do this the way TheAaron did it. To Whit - WWTAD?
1708556122
The Aaron
Roll20 Production Team
API Scripter
Lols.&nbsp; Here's some threads to ramp you up: <a href="https://app.roll20.net/forum/post/6605115/namespaces-novice-seeks-help-exploring-the-revealing-module-pattern" rel="nofollow">https://app.roll20.net/forum/post/6605115/namespaces-novice-seeks-help-exploring-the-revealing-module-pattern</a> <a href="https://app.roll20.net/forum/post/6584105/creating-an-object-that-holds-specific-character-dot-id-and-character-name/?pagenum=1" rel="nofollow">https://app.roll20.net/forum/post/6584105/creating-an-object-that-holds-specific-character-dot-id-and-character-name/?pagenum=1</a> <a href="https://app.roll20.net/forum/post/6237754/slug%7D" rel="nofollow">https://app.roll20.net/forum/post/6237754/slug%7D</a>
1708557918
GiGs
Pro
Sheet Author
API Scripter
GM said: this is way beyond where I am currently in terms of knowledge, but it's amazeballs. It's also a new goal... learn how to do this the way TheAaron did it. To Whit - WWTAD? That's a great acronym, although the answer will probably be, "ask The Aaron, because if I knew what he would do, I wouldn't be in this mess!"