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

Mod from Library not triggering sheetworkers

1678414315

Edited 1678414610
I don't know if there is already a topic open for this, but searching for my problem I was unable to find anything recent... I am using a roll button to set an attribute to that of a data holding sheet. (The data is json) When this attribute is changed it triggers sheetworkers to set the initial state of other attributes on the sheet using this data. I am nearly done implementing all features of this sheet, but for weeks I have been experiencing issues with it going through periods of time where it will not trigger the sheetworker. The mod I am using is chatSetAttr which seems to be a very commonly used and well kept mod, so I am unsure of where the cause is. Trigger sheet workers when setting attributes:   is confirmed checked. I have tried disable/enable script and refreshing the api sandbox and sandboxtabletop several times in several combinations, but can't get it to work. I don't think it is my on('change: because if I manually change for ex. 'base_level' it triggers, but if I !setattr --sel --base_level|2 it changes the base_level to 2, but doesn't trigger the sheet worker. Some days, I will log on and it will just work, other days regardless of what I try I can not get it to work which really affects the sheet's functionality.
1678421892
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
This is an issue with the Roll20 backend. When an attribute is it's default value on a character sheet, it exists in a weird limbo state where both of the following are true: It does  exist for attribute calls, and the sheetworkers themselves. It does not  exist to the API. Creating the attribute with a value is a creation event and doesn't trigger change listeners. This leads to the behavior you are seeing. There is a newer way for api scripts to trigger sheetworkers that should get around this, but I don't believe CSA uses it.
I feel like I have an understanding of what you are saying. So because it does not initially exist in the attributes & abilities tab it won't trigger a sheetworkers listener? I tried a hacky workaround just now which I believed would make it work for me as I was manually changing the data for the attribute which I thought should have taken it out of that limbo by making it an official attribute before activating the roll/CSA command. This did not work, and it still does not show up in the list of attributes?!?!? Couple of questions: 1. What makes something show up in the attributes list? I have tried numerous different things trying to figure this out such as default values, visibility visible and now manually editing the input... I just can't wrap my head around it and haven't been able to find anything over the last few months of searching the wiki and forums. I create a new sheet and have attributes in the list that are blank and inputs connected to attributes that have data and don't show up in that list. It's driving me mad. 2. What is this  newer way for api scripts to trigger sheetworkers that should get around this I will write my own mod script just for this initial setting of the sheet's json if I have to. I have come this far after fighting with promises and async just to realize they don't work in roll20.
1678467248
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
The attributes & abilities tab is sort of related to this, but should be ignored in most cases as it doesn't take into account things like pseudo attributes (e.g. character_name) or repeating section attributes. I tried a hacky workaround just now which I believed would make it work for me as I was manually changing the data for the attribute which I thought should have taken it out of that limbo by making it an official attribute before activating the roll/CSA command. This did not work, and it still does not show up in the list of attributes?!?!? I'd need to see the code you tried, or more detailed description of what you tried to critique 2. What is this  newer way for api scripts to trigger sheetworkers that should get around this The api has access to a version of the setAttrs function used by character sheets. It is a newer method for scripts to trigger sheetworkers and I don't think CSA has been updated since it was released several years ago. I will write my own mod script just for this initial setting of the sheet's json if I have to. I have come this far after fighting with promises and async just to realize they don't work in roll20. Promises/Async work in some specific situations. You can use them in API scripts without an issue, but unfortunately character sheets can only use them with the startRoll function. A possible solution would be to create a setup function for your character sheet that would run when it is opened and check the version of the sheet. If the version doesn't exist, set the default value via sheetworker. This will then create those attributes so that CSA can edit them and trigger sheetworkers. This will only work if your CSA macro is only setting non-repeating attributes unfortunately. If you need to set repeating attributes as well, I'd recommend writing a parser into your character sheet that will set up the sheet based on some sort of pasted in data. I've done this for several sheets using text statblocks (Starfinder HUD [discontinued], and Genefunk 2090). You could also have it parse json or some other structured data format.
1678469929

Edited 1678478718
I'd need to see the code you tried, or more detailed description of what you tried to critique Pseudo-simplification: dropdown = attr_c_name      roll = !setAttr p_json|@{otherSheet|json}    sheetworker = on(change: c_json you would choose the creature name from dropdown and click confirm/roll button which sets json and would trigger sheetworker to set other attrs --- changed to dropdown = attr_c_json       roll = !setAttr c_name|@{c_json}  !setAttr p_json|@{otherSheet|json}      sheetworker =    on(change: c_json basically now c_json gets set manually then sets c_name then has c_json set to the data from other sheet which I thought would fix it because it was being set manually first before being set by the setAttr btw I know I can !setAttr --attr1|0 --attr2|0 inline, but can also use another !setAttr on a new line and wanted to break up the two just in case also having the c_json trigger while there's a name in it instead of proper json is fine as I have catches in place to keep it from breaking anything like I said **hacky** A possible solution would be to create a setup function for your character sheet that would run when it is opened and check the version of the sheet. If the version doesn't exist, set the default value via sheetworker. This will then create those attributes so that CSA can edit them and trigger sheetworkers. This will only work if your CSA macro is only setting non-repeating attributes unfortunately. This is a great idea. I'm going to try this out. Thanks a lot for your help Scott.
1678473127

Edited 1678473349
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Oh, if you're running these CSA commands as part of the sheet itself, not as personal set up macros, I'd recommend not using CSA. Instead use the recently(ish) available custom roll parsing of character sheets to grab the data from the sheet you want. Then parse it directly in the sheet. No api weirdness to deal with at all.
1678474519

Edited 1678478726
recently(ish) available custom roll parsing of character sheets to grab the data from the sheet you want Incredible. This is actually something else that I looked for. The only forum responses I found related to a) setting anything in a sheet based on a roll or b) a button that could execute an action and roll together were that they could not be done. I really really really wish there were an advanced search option for the forums for filtering by date and the like. Thank you so so much. I'm about to reprogram several things in my character sheets just with this one function I was unaware of.
1678478698

Edited 1678478856
Looking into the  Custom Roll Parsing  page on the wiki, there is a statement that  Only template properties that are rolls (i.e wrapped with  [[ ]] ) will be available in the results object.   Attributes   containing text only and passed as a roll can cause the startRoll to fail. so I did some more searching. I am assuming that your reply in  this post  is what you are suggesting that I should do? I had issues trying to use async/await and promises before, but I'm guessing that the way you have it set up there won't break connection to the character sheet? Also, is this fairly reliable?
1678482583

Edited 1678482655
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Yep, that's what I was thinking. I've used CRP a lot more since I wrote that, and it is a lot less hacky than I thought it would be back then. I've actually adapted some of that into a function provided by the K-scaffold . I still wouldn't recommend using the technique for event propagation, like was being asked about in that thread, as you could wind up with several hundred - several thousand script generated messages flashing back and forth between sheets. But f or something like this that is a one off use case, the extraneous chat messages aren't as big of a problem as they would be for event propagation. As for reliability, I've switched to using only CRP in the sheets I make for publishers. It is more reliable than roll buttons in my opinion because you can do data validation on attribute values before a roll is sent and prevent chat errors.
I think I'm just going to write my own mod. I just can't seem to get this to work. Using your code from that post and yes I know you disclaimed it as  untested code for demo purposes only but as far as I can tell, everything looks right. But alas, using it or even writing my own, while I can get 'results' to log to the console show the object and show query and expression in the drop down ,when I try to log results.query.expression directly while still in the startRoll all I keep getting is undefined. I guess I just can't seem to work with async while in the roll20 environment. I may come back to CRP if I can ever get it figured out. I've looked over what is in the wiki, your post and even Oosh's Adventures with startRoll() post. I'm just lost on this result. Thanks anyway for the suggestion.
1678488378
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
I've gotten much better at crp (and coding in general) since then. Post your code and I can probably find the problem.
1678490839

Edited 1678491122
startRoll(`!{{query=[[0[@{Aobe Iiniwi|c_name}]]]}}`, (results) =>  { console.log(results); }); /* {rollId: '-NQCikLUmZC7wkGY2lgH', results: {…}} results:  query:  dice: [] expression: "0[minotaur]" result: 0 rolls: [] [[Prototype]]: Object [[Prototype]]: Object rollId: "-NQCikLUmZC7wkGY2lgH" [[Prototype]]: Object */ startRoll(`!{{query=[[0[@{Aobe Iiniwi|c_name}]]]}}`, (results) =>  { console.log(results.query); }); //undefined startRoll(`!{{query=[[0[@{Aobe Iiniwi|c_name}]]]}}`, (results) =>  { console.log(results.query.expression); }); //undefined startRoll(`!{{query=[[0[@{Aobe Iiniwi|c_name}]]]}}`, (results) =>  { console.log(results['query']); }); //undefined I haven't even made it to the point of getting the results back out of the startRoll so that I can test and debug the rest on('change:c_name', function() { console.log('Changing Name'); getAttrs(['c_name'],async (values) => { <!-- console.log("[[@{C_JSONalt|" + values.c_name + "}]]"); --> <!-- console.log(`!{{query=[[0[response=@{C_JSONalt|${values.c_name}}]]]}}`); --> <!-- startRoll("@{C_JSONalt|" + values.c_name + "}", (results) => { --> <!-- startRoll(`!{{query=[[0[response=@{C_JSONalt|${values.c_name}}]]]}}`, (results) => { --> <!-- startRoll(`!{{query=[[0[@{Aobe Iiniwi|c_name}]]]}}`, (results) => { --> <!-- console.log(results.query.expression.replace(/^.+?response=|\]$/g,'')); --> <!-- }); --> /* let c_json = {}; */ const setObj = {}; setObj.attribute_to_set = await getOtherAttribute('C_JSONalt',values.c_name); setAttrs(setObj); }); }); const getOtherAttribute = async function(charName,attrName){ console.log('entering extractQueryResult'); let queryRoll = await startRoll(`!{{query=[[0[response=@{${charName}|${attrName}}]]]}}`); finishRoll(queryRoll.rollId); /* return queryRoll.results.query.expression.replace(/^.+?response=|\]$/g,''); */ console.log(queryRoll.results.query); }; I just want to pull @{sheetA|c_name} from C_JSONalt|c_name and do nothing with it other than setting the attribute sheetA|c_json. &{template:default}{{query=[[0[@{Aobe Iiniwi|c_name}]]]}} works just fine in chat and gives the expected result Rolling 0[minotaur] = 0
I got a fresh start today and got the issue figured out let jsonGet = await startRoll(`!{{query=[[0[@{Aobe Iiniwi|c_name}]]]}}`); finishRoll(jsonGet.rollId); console.log(jsonGet.results.query.expression); let c_json = jsonGet.results.query.expression.replace(/^.+?response=|\]$/g,''); console.log(c_json); now just getting the entire result undefined when I swap out the internal attribute I was using to test !{{query=[[0[@{Aobe Iiniwi|c_name}]]]}} for the external one that I need from the other sheet !{{query=[[0[@{C_JSONalt|${c_name}}]]]}} I don't think it's the literal because this does not work either !{{query=[[0[@{C_JSONalt|minotaur}]]]}}
1678585153

Edited 1678587248
There must be something in the input itself causing the function to fail to return the roll. I set up other sheets with more basic attributes and they seem to work fine. These are all characters included in the attribute which is 1438 characters long. &\#;:[]-."[A-Za-z] I may move this over to another thread as this seems to be a deeper issue I am running into. Edit:  Custom Roll Parsing Limitations?