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

[SCRIPT HELP] TokenMod not working in new campaign

Greetings Scriptomancers! I am wrapping up a long campaign and setting up a new one.  I have copied over all the scripts I use, and I am having trouble with TokenMod.  It does not appear to be responsive at all.  No command prompts trigger any action, including !token-mod --help. I installed the script from the 1-click repository, and selected Players can -ids, just in case, and still nothing.  The script still works in my old campaign. Is there some dependency that I am missing? Any help would be greatly appreciated.
1661724703

Edited 1661724719
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Hi CatSwann! Do other scripts operate, or is token mod the only holdout? Does it respond if you refresh the sandbox?
1661726489
The Aaron
Roll20 Production Team
API Scripter
Can you post some of your macros that aren't working?  And are your a GM or player?  Does it work when you have a token selected?
Ok, so after hours of tooling around, creating yet another new game and adding scripts one at a time (starting with my favorite little script, courtesy of theAaron I call YourAPIisRunning.js that just spits out a chat message saying YourAPIisRunning once the sandbox is spun up), I discovered there were two scripts that were gumming up the works. It seems Select Manager was causing an unlogged crash in my sandbox. Nothing came up in my console log, and it appeared it was up and running, but no API commands were triggering through the chat window. Once I eliminated that script, it seemed to be working fine until I installed my final script, Zero Frame, which caused TokenMod to crash every time I entered a command. Having taken those two scripts out of the running, I can get everything to work fine, except... Now when I am updating my default token settings (bar assignments, player view permissions, etc.), it works fine to update the token settings, then apply the default token. When I drag the updated token from the compendium, everything works fine.  But whenever I delete any token, it crashes my sandbox. Here is the error that pops up: For reference, the error message generated was: TypeError: Cannot read property 'graphics' of undefined TypeError: Cannot read property 'graphics' of undefined at Function.delete (apiscript.js:23014:25) at apiscript.js:22867:31 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.destroy (/home/node/d20-api-server/api.js:1337:10) at deleteFromLocalCache (/home/node/d20-api-server/api.js:1477:18) at /home/node/d20-api-server/api.js:1617:11 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147) at Kd (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:546) Any thoughts?
FWIW, here is my TokenMod command: !token-mod {{ --on  showname  showplayers_bar3  showplayers_name --off  showplayers_bar1  showplayers_bar2  playersedit_name  playersedit_bar1  playersedit_bar2  playersedit_bar3  playersedit_aura1  playersedit_aura2 --set  name|"@{selected|token_name} %%NUMBERED%%"  bar1_link|npc_speed  bar2_link|npc_ac  bar3_link|  bar_location|overlap_bottom }} Followed by: !token-mod --set defaulttoken ...using separate macros imported from my original game using a macro mule character sheet.
1662525250
timmaugh
Pro
API Scripter
Ears... a'flambe over here. =D I'm interested in what is going on, once/if you get your current issue straightened around. If you get it cleared up and then reenable ZeroFrame and/or SelectManager to an error, I'd be interested in hunting that down. I did have a strange situation where, for a script I was developing, I couldn't have it before another script in a game. Nothing about the in-dev script should have caused a problem, but the existing script was having an issue if it was installed after the in-dev one. It wasn't a misplaced comma or semi-colon, not an open closure... nothing. All the code linted just fine. It just wouldn't work. Until one day, it did. No change to either script (to others, but not those two). Strangest thing. Anyway, if ZF and/or SM continue to be a problem, I'll look into it. I've got them running in my active game and in 2 or 3 testing games, with no problem.
1662575143

Edited 1662575893
oops, i thought it was the main thread, sorry !
UPDATE So I have managed to confirm that Zero Frame and Select Manager are definitely causing some issues in this campaign.  After the tedious process of elimination, all my scripts seem to be working fine as long as ZF is not on my mod list, but the moment I install it, everything becomes unresponsive, and when I install Select Manager, the sandbox crashes on every spinup. Even when I remove several custom scripts, leaving only repository scripts, the issue persists. I can do without these scripts if needed, but it sure would be nice to get to the bottom of this. I am still getting the issue that when I delete either a token or a map page, it crashes the sandbox and gives the above error. I have tried the process of elimination again by disabling script by script, and cannot seem to find the culprit. At the risk of opening a gigantic can of worms, I humbly beg assistance with these issues. @timmaugh, @theAaron, @keithcurtis, any ideas on how to proceed or at least help narrow the field of suspects?
And to follow up, I am using the exact same array of scripts for my current campaign without any issues...
1662693184
timmaugh
Pro
API Scripter
It really sounds like some corruption in the game, but if you invite/promote me, I'll take a look to see if there's something to be done (besides recreating). =D
1662694532
The Aaron
Roll20 Production Team
API Scripter
I agree with Tim. It's suspicious that the same set of scripts works in another campaign. I'd be curious to know where the call to delete that is crashing is happening and what the trigger is. That call stack doesn't seem like it would be in a script, but rather the sandbox itself. I might suggest cloning the campaign and resetting up the scripts to see if you still get the crash. 
Ok, I seem to be getting nowhere.  I have created the game six times now, loading in the exact same scripts from my current game, in the exact same order, but still hit a wall of issues. I have located the issue with the delete command.  It seems the Check It Out script was causing the crash any time a graphic instance was deleted (token or map). Removing that script, which I really never use anymore, fixed that problem, but I still can't get all my scripts to work. Every time I start a new game and begin loading scripts, I am checking the sandbox and verifying each script is working one at a time by waiting for spin-up to finish and firing any command associated with the newest script.  This works up to a point, where it seems any script I add does not initialize with any command I give.  It seems the magic number is 20 scripts that I can get working at once.  After loading my 20th script, I can't seem to get any script to work.  The log does not register the scripts on spin-up, which leads me to believe there is a problem with my account where my Pro subscription is unable to handle more mods than that. The really weird thing is that they all work fine in my current game.  I am using a module for this game (Dungeon of the Mad Mage). I thought this might have something to do with it, so I created a blank game, but still ran into the same issue. I am submitting a ticket for support with Roll20, and will let you guys know what they come up with.
Final update. It was the module that was causing problems. Dungeon of the Mad Mage is just too massive to be able to handle more than fifteen or twenty scripts. So I am working through the oh so tedious process of transferring the module in through Transmigrifier into my existing game. The upside is my scripts and macros are already set up and organized. The downside is...so very many maps, monsters and handouts to transfer. I'll be doing it three or four levels at a time to keep it manageable. Problem solved.  Somewhat.
1663436579
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Scripts can be written with longer timeouts, and scripts run in their own sandbox, irrespective of game size. But the size of the module shouldn't affect something like !token mod --help. It could be a specific script, particularly one that polls all tokens and is triggered automatically on something like a graphic movement or other change. Are you running something like Health Auras?
1663441249
The Aaron
Roll20 Production Team
API Scripter
If you have a moment, you should provide a list of the scripts you're using.  Many scripts are implemented fairly naively, but can be updated without too much effort to resolve the timeout contention. And that benefits everyone. =D 
It seems I forgot to mention that this was the response I got from Roll20 Help Desk. Here was their response: Hi there,   Thanks for reaching out, and deepest apologies for the troubles getting API up and running! Taking a look, there's two probable causes to this issue:  DOTMM is one of the biggest modules (if not the biggest, I believe) on Roll20 . We run into issues, on the rare occasion, of DM's adding so much to a DOTMM game that the game corrupts in various ways due to size. This could be a reflection on this issue, especially if it's working in non-DOTMM games.  If you're trying to use a 3rd party browser extension that affects Roll20 , especially with bigger games like this, issues can start appearing. The inability to install a mod could be stemming from something like that!  You may have luck using the Transmogrifier to transfer the desired DOTMM content to a game with the desired API scripts already installed, but your mileage may vary. Please don't hesitate to reach out if you encounter any further questions or concerns.   Happy Gaming, KM The Roll20 Team
The scripts I have in my working game that I am attempting to import to the new game are, in this order: From the Repository 5th Edition OGL by ROll20 Companion Token Mod ChatSetAttr 5E Resting in Style HTML Builder TokenNameNumber MonsterHitDice Roll20 Audio Master Customizable Roll Listener Death Tracker Vector Math Matrix Math Path Math Door Knocker Token Action Maker API Heartbeat PowerCards PowerCards Macro Helper SplitArgs Areas of Effect Carry Tokens Token Collision Character Sheet Utils It's a Trip - D&D 5e Generic Check It Out PCPP D&D GM Sheet Combat Master CashMaster Inspiration Tracker (not the Geiger version) Flight Message of the Day RecursiveTable libTokenMarkers ScriptCards API Logic Select Manager Spawn Default Token Lazy Experience Fetch UDLWindows GroupCheck ZeroFrame LibInLine Custom Scripts: LazyLoot TreasureGenerator APIisRunning GMMysteryRoll ApplyDamage InventoryTracker PlayerIDRoll TempHP (theAaron version) The only scripts on the list that I am aware of that polls tokens are TokenNameNumber and CombatMaster, but I could definitely be very wrong about that. I am still a newbie at scripting, and know just enough to get myself in trouble. The troubling bit that keeps nagging at me is that I can get all of these scripts working in a new blank game, and they work great in my old game, but as soon as I start a new game with the DOTMM, I can only install 19 scripts.  Everything past 19 fails to load. I recreated a Lost Mines of Phandelver module to test, and everything worked fine again. It just seems to be a problem with the DOTMM module installed.
1663516050
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
I believe a lot of those poll all tokens on the VTT,  particularly It's a Trap, which has to know where everything is. UDL Windows can be dropped. That's built in now. Have you tested in an order that the 20th script is not always the same script?
1663518607
The Aaron
Roll20 Production Team
API Scripter
Just to be clear, most of those are querying the tokens, not polling. Polling would be periodically grabbing a set of data to compare it to prior data/look for updates. Most scripts will be reacting to events to query the state of a set of data. It's a subtle difference, but the takeaway is that polling generates load on a regular period (every time it polls), event driven scripts generate load on an event.  Possible infinite loop happens when scripts take too long before returning execution to the sandbox. The fix in scripts for that is to assemble a work queue and defer processing it against many callbacks. What's happening here is that there are lots of things happening on the ready event which all execute as part of the same call to preserve registration order. Probably changing all the scripts to defer straight from the ready event would fix this on most cases because that would let execution return to the sandbox between each ready handler. Better would be to have the Roll20 event system reset it's watchdog timer between callbacks, but we'd have to get Roll20 to do that. 
1663521539
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Thanks for the clarification, Aaron. I was using those terms as a total layman.
Thanks for the quick response, guys. @KiethCurtis, I have tried loading scripts in in various orders, and it always stops working after the 19th script, no matter what order I load them in. I can go back and delete an earlier script, and that will make the new #19 script work, but if I re-install the deleted one, it does not work if it is after #19 in the list. @theAaron, I don't suppose there is an "easy" way to get the scripts to defer from the ready event, is there? I imagine I would have to find the source script and manually adjust the code to do so.  Am I wrong? Either way, I have committed to Transmogrifying the module levels one at a time.  It is giving me a chance to really feel out the levels as I set them up, which is not a bad thing. The real pain is the module has multiple handouts (three for each level, 27 levels) that are all named the same thing, so the Transmogrifier only recognizes one script of a given name, so I am having to copy and paste each instance of the handouts manually.  Not a huge deal, but kind-of annoying. I did manage to get all my macros transferred from the Module game with no APIs by following Nick Olivo's video tutorial for a custom script.  That saved me TONS of time. Everything else I can swap over with Transmogrifier.
1663600520
The Aaron
Roll20 Production Team
API Scripter
It is a simple change, but it would require editing all scripts.  Here's what the change would look like: Example script: on('ready',()=>{ on('chat:message',msg=>{ if('api'===msg.type && /^!do(\b\s|$)/i.test(msg.content) && playerIsGM(msg.playerid)){ let who = (getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname'); sendChat('',`/w "${who}" Hello World!`); } }); }); Deferring ready event: on('ready', setTimeout( ()=>{ on('chat:message',msg=>{ if('api'===msg.type && /^!do(\b\s|$)/i.test(msg.content) && playerIsGM(msg.playerid)){ let who = (getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname'); sendChat('',`/w "${who}" Hello World!`); } }); } ,0) ); That changes the ready event from executing the passed function, to scheduling a callback to call the function. Because the delay is 0, it will get called immediately after the ready event finishes, but each callback will have it's own watchdog timer.
1663739342

Edited 1663739394
Oosh
Sheet Author
API Scripter
Another option (which I can't guarantee will work, but should achieve the same thing as Aaron's post) is to add a single script to the start of the load. This does mean removing all scripts (or making a copy of the game with no scripts installed yet) and adding this one in the very first tab: const _originalOn = on.bind({}); const _asyncTimeout = async (ms) => new Promise(res => setTimeout(() => res(), ms)); let _queuedReadies = 0; on = async (...args) => { if (args[0] === 'ready') { await _asyncTimeout(0); if (typeof(args[1]) === 'function') { _queuedReadies ++; log(`Queued ${_queuedReadies} scripts...`); args[1](); } } else { _originalOn(...args); } } That might be easier, depending on where you are with setting up the scripts. Although it also might not work - I don't have a campaign the size of mad mage to test it out on.