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

Belated Continuation With Learning CRT...

This is a continuation of&nbsp; <a href="https://app.roll20.net/forum/post/11740051/slug%7D" rel="nofollow">https://app.roll20.net/forum/post/11740051/slug%7D</a> I am finally able to continue working on this sheet and it is still absolutely kicking my ass.&nbsp; Here's what I have thus far: Button: &lt;div class="sheet-row"&gt; &lt;div class="sheet-col"&gt; &lt;button type="roll" value="&amp;{template:default} {{name=Syphon}} {{Roll=[[@{syphonroll}d6&gt;4]]}}" name="SyphonRoll"&gt;Syphon&lt;/button&gt; &lt;/div&gt; &lt;div class="sheet-col"&gt; &lt;button type="action" name="StainCheck"&gt;Stain&lt;/button&gt; &lt;/div&gt; &lt;div class="sheet-col"&gt; &lt;button type="roll" value="&amp;{template:default} {{name=Spell Battery}} {{Roll=[[@{spellbatt}d6kh1]]}}" name="SpellBatt"&gt;Spell Battery&lt;/button&gt; &lt;/div&gt; &lt;div class="sheet-col"&gt; &lt;button type="roll" value="&amp;{template:default} {{name=Syp Check}} {{Roll=[[1d6]]}}" name="SypCheck"&gt;Syp Check&lt;/button&gt; &lt;/div&gt; &lt;/div&gt; Worker Sheet: on('clicked:StainCheck', () =&gt; { getAttrs(["AETHERSCORE","AETHERSTAIN","CORRUPTIONSCORE","CORRUPTIONSTAIN","DESTRUCTIONSCORE","DESTRUCTIONSTAIN","PURITYSCORE","PURITYSTAIN","VITALITYSCORE","VITALITYSTAIN"], function(values) { let aetherscore = parseInt(values.AETHERSCORE)||0; let aetherstain = parseInt(values.AETHERSTAIN)||0; let corruptionscore = parseInt(values.CORRUPTIONSCORE)||0; let corruptionstain = parseInt(values.CORRUPTIONSTAIN)||0; let destructionscore = parseInt(values.DESTRUCTIONSCORE)||0; let destructionstain = parseInt(values.DESTRUCTIONSTAIN)||0; let purityscore = parseInt(values.PURITYSCORE)||0; let puritystain = parseInt(values.PURITYSTAIN)||0; let vitalityscore = parseInt(values.VITALITYSCORE)||0; let vitalitystain = parseInt(values.VITALITYSTAIN)||0; setAttrs({ aetherscore: aetherscore, aetherstain: aetherstain, corruptionscore: corruptionscore, corruptionstain: corruptionstain, destructionscore: destructionscore, destructionstain: destructionstain, purityscore: purityscore, puritystain: puritystain, vitalityscore: vitalityscore, vitalitystain: vitalitystain }) const stain_string = '&amp;{template:default} {{name=StainCheck}} {{roll=[[ [[@{aetherscore}d6&gt;@{aetherstain}]] + [[@{corruptionscore}d6&gt;@{corruptionstain}]] + [[@{destructionscore}d6&gt;@{destructionstain}]] + [[@{purityscore}d6&gt;@{puritystain}]] + [[@{vitalityscore}d6&gt;@{vitalitystain}]] ]]'; startRoll(stain_string, stain_roll =&gt; { console.log(stain_roll); finishRoll(stain_roll.rollId); }); }); }) HTML: &lt;rolltemplate class="sheet-rolltemplate-staincheck"&gt; &lt;div class="aetherstainheading"&gt;{{title}}&lt;/div&gt; &lt;div class="results"&gt; &lt;div class="key"&gt;Aether Stain&lt;/div&gt; &lt;div class="value"&gt;{{aetherstain}} + "+"&lt;/div&gt; &lt;div class="key"&gt;Roll&lt;/div&gt; &lt;div class="value"&gt;&lt;span class="dice"&gt; {{computed::roll}}&lt;/span&gt; = {{roll}} &lt;/div&gt; &lt;div class="key"&gt;Result&lt;/div&gt; &lt;div class="value"&gt; {{#rollGreater() computed::score 0}} ({{computed::score}} {{/rollGreater() computed::score 0}})&lt;/div&gt; &lt;div class="corruptionstainheading"&gt;{{title}}&lt;/div&gt; &lt;div class="results"&gt; &lt;div class="key"&gt;Corruption Stain&lt;/div&gt; &lt;div class="value"&gt;{{corruptionstain}} + "+"&lt;/div&gt; &lt;div class="key"&gt;Roll&lt;/div&gt; &lt;div class="value"&gt;&lt;span class="dice"&gt; {{computed::roll}}&lt;/span&gt; = {{roll}} &lt;/div&gt; &lt;div class="key"&gt;Result&lt;/div&gt; &lt;div class="value"&gt; {{#rollGreater() computed::score 0}} ({{computed::score}} {{/rollGreater() computed::score 0}})&lt;/div&gt; &lt;div class="destructionstainheading"&gt;{{title}}&lt;/div&gt; &lt;div class="results"&gt; &lt;div class="key"&gt;Destruction Stain&lt;/div&gt; &lt;div class="value"&gt;{{destructionstain}} + "+"&lt;/div&gt; &lt;div class="key"&gt;Roll&lt;/div&gt; &lt;div class="value"&gt;&lt;span class="dice"&gt; {{computed::roll}}&lt;/span&gt; = {{roll}} &lt;/div&gt; &lt;div class="key"&gt;Result&lt;/div&gt; &lt;div class="value"&gt; {{#rollGreater() computed::score 0}} ({{computed::score}} {{/rollGreater() computed::score 0}})&lt;/div&gt; &lt;div class="puritystainheading"&gt;{{title}}&lt;/div&gt; &lt;div class="results"&gt; &lt;div class="key"&gt;Purity Stain&lt;/div&gt; &lt;div class="value"&gt;{{puritystain}} + "+"&lt;/div&gt; &lt;div class="key"&gt;Roll&lt;/div&gt; &lt;div class="value"&gt;&lt;span class="dice"&gt; {{computed::roll}}&lt;/span&gt; = {{roll}} &lt;/div&gt; &lt;div class="key"&gt;Result&lt;/div&gt; &lt;div class="value"&gt; {{#rollGreater() computed::score 0}} ({{computed::score}} {{/rollGreater() computed::score 0}})&lt;/div&gt; &lt;div class="vitalitystainheading"&gt;{{title}}&lt;/div&gt; &lt;div class="results"&gt; &lt;div class="key"&gt;Vitality Stain&lt;/div&gt; &lt;div class="value"&gt;{{vitalitystain}} + "+"&lt;/div&gt; &lt;div class="key"&gt;Roll&lt;/div&gt; &lt;div class="value"&gt;&lt;span class="dice"&gt; {{computed::roll}}&lt;/span&gt; = {{roll}} &lt;/div&gt; &lt;div class="key"&gt;Result&lt;/div&gt; &lt;div class="value"&gt; {{#rollGreater() computed::score 0}} ({{computed::score}} {{/rollGreater() computed::score 0}})&lt;/div&gt; &lt;div class="unstainedstainheading"&gt;{{title}}&lt;/div&gt; &lt;div class="results"&gt; &lt;div class="key"&gt;Unstained Stain&lt;/div&gt; &lt;div class="value"&gt;&lt;span class="dice"&gt; {{computed::roll}}&lt;/span&gt; = {{roll}} &lt;/div&gt; &lt;div class="key"&gt;Result&lt;/div&gt; &lt;div class="value"&gt; {{#rollGreater() computed::score 0}} ({{computed::score}} {{/rollGreater() computed::score 0}})&lt;/div&gt; &lt;/div&gt; &lt;/rolltemplate&gt; CSS: .sheet-rolltemplate-staincheck { background: white; } .sheet-rolltemplate-staincheck .sheet-heading { background: black; color: white; text-align: center; } .sheet-rolltemplate-staincheck .sheet-results { display: grid; grid-template-columns: 49% 49%; column-gap: 2%; line-height: 1.8em; } .sheet-rolltemplate-staincheck .sheet-results { text-align: right; } Right now, my ONLY objective is to at least get the console.log to show so I know what I have to work with.&nbsp; Any help is appreciated!
1711459747
GiGs
Pro
Sheet Author
API Scripter
In your first code, for the button, there is a mistake. This: &lt;div class="sheet-col"&gt; &lt;button type="action" name="StainCheck"&gt;Stain&lt;/button&gt; &lt;/div&gt; should be &lt;div class="sheet-col"&gt; &lt;button type="action" name="act_StainCheck"&gt;Stain&lt;/button&gt; &lt;/div&gt; I'd use all lower-case letters just in case, like &lt;div class="sheet-col"&gt; &lt;button type="action" name="act_staincheck"&gt;Stain&lt;/button&gt; &lt;/div&gt;
1711459849

Edited 1711460210
GiGs
Pro
Sheet Author
API Scripter
In your sheet worker, this MUST be in lower case: on('clicked:StainCheck', () =&gt; { so it should be on('clicked:staincheck', () =&gt; { This is true even if you use upper case letters in the HTML. The event line of a sheet worker (the one that starts on) must always use lower case, or sometimes the sheet worker will not recognise it has been triggered. This may be why your console.log isn't showing (actually, the lack of act_ on the name is more important).
1711460073

Edited 1711460107
GiGs
Pro
Sheet Author
API Scripter
what is the purpose of the getAttrs and setAttrs in your sheetworker? It seems like they read in the attributes, and then write them out again, without changes. So you could skip that step entirely, and have on('clicked:staincheck', () =&gt; { const stain_string = '&amp;{template:default} {{name=StainCheck}} {{roll=[[ [[@{aetherscore}d6&gt;@{aetherstain}]] + [[@{corruptionscore}d6&gt;@{corruptionstain}]] + [[@{destructionscore}d6&gt;@{destructionstain}]] + [[@{purityscore}d6&gt;@{puritystain}]] + [[@{vitalityscore}d6&gt;@{vitalitystain}]] ]]'; startRoll(stain_string, stain_roll =&gt; { console.log(stain_roll); finishRoll(stain_roll.rollId); }); });
1711460340

Edited 1711460546
GiGs
Pro
Sheet Author
API Scripter
Also if you're struggling with sheet design in roll20, look here: <a href="https://cybersphere.me/roll20-sheet-author-master-list/" rel="nofollow">https://cybersphere.me/roll20-sheet-author-master-list/</a> PS: the rolls in your html are also missing roll_ at the start of their names, For example &lt;button type="roll" value="&amp;{template:default} {{name=Syphon}} should be &lt;button type="roll" value="&amp;{template:default} {{name="roll_Syphon"}} I'd also eliminate the spaces from those that have them in the name - replacing the space with an underscore is a good move.
Thank you! I have applied your remedies and I am now getting a read of the console.log...unfortunately, it turns out to not be reading anything at all! Buttons: &lt;div class="sheet-row"&gt; &lt;div class="sheet-col"&gt; &lt;button type="roll" value="&amp;{template:default} {{Roll=[[@{syphonroll}d6&gt;4]]}} {{name="roll_Syphon"}} "&gt;Syphon&lt;/button&gt; &lt;/div&gt; &lt;div class="sheet-col"&gt; &lt;button type="action" name="act_staincheck"&gt;Stain&lt;/button&gt; &lt;/div&gt; &lt;div class="sheet-col"&gt; &lt;button type="roll" value="&amp;{template:default} {{Roll=[[@{spellbatt}d6kh1]]}} {{name="roll_SpellBatt"}} "&gt;Spell Battery&lt;/button&gt; &lt;/div&gt; &lt;div class="sheet-col"&gt; &lt;button type="roll" value="&amp;{template:default} {{Roll=[[1d6]]}} {{name="roll_SypCheck"}} "&gt;Syp Check&lt;/button&gt; &lt;/div&gt; &lt;/div&gt; HTML: &lt;rolltemplate class="sheet-rolltemplate-staincheck"&gt; &lt;div class="aetherstainheading"&gt;{{title}}&lt;/div&gt; &lt;div class="results"&gt; &lt;div class="key"&gt;Aether Stain&lt;/div&gt; &lt;div class="value"&gt;{{aetherstain}} + "+"&lt;/div&gt; &lt;div class="key"&gt;Roll&lt;/div&gt; &lt;div class="value"&gt;&lt;span class="dice"&gt; {{computed::roll}}&lt;/span&gt; = {{roll}} &lt;/div&gt; &lt;div class="key"&gt;Result&lt;/div&gt; &lt;div class="value"&gt; {{#rollGreater() computed::score 0}} ({{computed::score}} {{/rollGreater() computed::score 0}})&lt;/div&gt; &lt;div class="corruptionstainheading"&gt;{{title}}&lt;/div&gt; &lt;div class="results"&gt; &lt;div class="key"&gt;Corruption Stain&lt;/div&gt; &lt;div class="value"&gt;{{corruptionstain}} + "+"&lt;/div&gt; &lt;div class="key"&gt;Roll&lt;/div&gt; &lt;div class="value"&gt;&lt;span class="dice"&gt; {{computed::roll}}&lt;/span&gt; = {{roll}} &lt;/div&gt; &lt;div class="key"&gt;Result&lt;/div&gt; &lt;div class="value"&gt; {{#rollGreater() computed::score 0}} ({{computed::score}} {{/rollGreater() computed::score 0}})&lt;/div&gt; &lt;div class="destructionstainheading"&gt;{{title}}&lt;/div&gt; &lt;div class="results"&gt; &lt;div class="key"&gt;Destruction Stain&lt;/div&gt; &lt;div class="value"&gt;{{destructionstain}} + "+"&lt;/div&gt; &lt;div class="key"&gt;Roll&lt;/div&gt; &lt;div class="value"&gt;&lt;span class="dice"&gt; {{computed::roll}}&lt;/span&gt; = {{roll}} &lt;/div&gt; &lt;div class="key"&gt;Result&lt;/div&gt; &lt;div class="value"&gt; {{#rollGreater() computed::score 0}} ({{computed::score}} {{/rollGreater() computed::score 0}})&lt;/div&gt; &lt;div class="puritystainheading"&gt;{{title}}&lt;/div&gt; &lt;div class="results"&gt; &lt;div class="key"&gt;Purity Stain&lt;/div&gt; &lt;div class="value"&gt;{{puritystain}} + "+"&lt;/div&gt; &lt;div class="key"&gt;Roll&lt;/div&gt; &lt;div class="value"&gt;&lt;span class="dice"&gt; {{computed::roll}}&lt;/span&gt; = {{roll}} &lt;/div&gt; &lt;div class="key"&gt;Result&lt;/div&gt; &lt;div class="value"&gt; {{#rollGreater() computed::score 0}} ({{computed::score}} {{/rollGreater() computed::score 0}})&lt;/div&gt; &lt;div class="vitalitystainheading"&gt;{{title}}&lt;/div&gt; &lt;div class="results"&gt; &lt;div class="key"&gt;Vitality Stain&lt;/div&gt; &lt;div class="value"&gt;{{vitalitystain}} + "+"&lt;/div&gt; &lt;div class="key"&gt;Roll&lt;/div&gt; &lt;div class="value"&gt;&lt;span class="dice"&gt; {{computed::roll}}&lt;/span&gt; = {{roll}} &lt;/div&gt; &lt;div class="key"&gt;Result&lt;/div&gt; &lt;div class="value"&gt; {{#rollGreater() computed::score 0}} ({{computed::score}} {{/rollGreater() computed::score 0}})&lt;/div&gt; &lt;div class="unstainedstainheading"&gt;{{title}}&lt;/div&gt; &lt;div class="results"&gt; &lt;div class="key"&gt;Unstained Stain&lt;/div&gt; &lt;div class="value"&gt;&lt;span class="dice"&gt; {{computed::roll}}&lt;/span&gt; = {{roll}} &lt;/div&gt; &lt;div class="key"&gt;Result&lt;/div&gt; &lt;div class="value"&gt; {{#rollGreater() computed::score 0}} ({{computed::score}} {{/rollGreater() computed::score 0}})&lt;/div&gt; &lt;/div&gt; &lt;/rolltemplate&gt; Work Sheet: on('clicked:staincheck', () =&gt; { const stain_string = '&amp;{template:default} {{name=StainCheck}} {{roll=[[ [[@{aetherscore}d6&gt;@{aetherstain}]] + [[@{corruptionscore}d6&gt;@{corruptionstain}]] + [[@{destructionscore}d6&gt;@{destructionstain}]] + [[@{purityscore}d6&gt;@{puritystain}]] + [[@{vitalityscore}d6&gt;@{vitalitystain}]] ]]'; startRoll(stain_string, stain_roll =&gt; { console.log(stain_roll); finishRoll(stain_roll.rollId); }); }); CSS: .sheet-rolltemplate-staincheck { background: white; } .sheet-rolltemplate-staincheck .sheet-heading { background: black; color: white; text-align: center; } .sheet-rolltemplate-staincheck .sheet-results { display: grid; grid-template-columns: 49% 49%; column-gap: 2%; line-height: 1.8em; } .sheet-rolltemplate-staincheck .sheet-results { text-align: right; } Console.log read: So my question from here on...is this console.log a result of a failure in the HTML or the CSS?&nbsp; How do I get the console.log to show so I can start getting to the real work...
1711556455
GiGs
Pro
Sheet Author
API Scripter
That doesn't look like the console.log, just the chat message. To see the console.log you have to press F12, and tap the console tab. Then what exactly are you getting in the console.log? even if it's something like "undefined" or "N/A" there should be something there if the worker is working. Do you have attributes for your roll created? There is no HTML for them above.
Greetings.&nbsp; So it is running, but it is not storing any rolls done in the Work Sheet...which is fair since I hadnt made them yet anyway, but why does it look like the rolls are not even being done, let alone not scored? This is what I got.
1711627251
GiGs
Pro
Sheet Author
API Scripter
You havent answered my question about the attributes.
Okay I think I see what you mean.&nbsp; My apologies.&nbsp; I do not think I have made any attributes made, technically,&nbsp; I think I was mistaken in the thought that if I put them down in the HTML they would magic themselves into the Work Sheet...so no, I do not believe I have.
1711647783

Edited 1711647822
GiGs
Pro
Sheet Author
API Scripter
You'll need to create each attribute in the HTML. I usually use spans for the labels, and input (type="number") for the attribute scores.
1712092898

Edited 1712093468
Okay. I got what you were saying...I did what I could until I hit the next roadblock. Button: &lt;div class="sheet-col"&gt; &lt;button type="action" name="act_staincheck"&gt;Stain&lt;/button&gt; &lt;/div&gt; Work-Sheet: on('clicked:staincheck', event =&gt; { setAttrs({ unstained: 0 }) const stain_string = "&amp;{template:default} {{name=Stain Check}} {{Aether Shade=[[@{aetherscore}d6&gt;@{aetherstain}]]}} {{Corruption Shade=[[@{corruptionscore}d6&gt;@{corruptionstain}]]}} {{Destruction Shade=[[@{destructionscore}d6&gt;@{destructionstain}]]}} {{Purity Shade=[[@{purityscore}d6&gt;@{puritystain}]]}} {{Vitality Shade=[[@{vitalityscore}d6&gt;@{vitalitystain}]]}} {{Unstained=[[@{unstained}]]}}"; startRoll(stain_string, roll =&gt; { console.log(roll); finishRoll(roll.rollId); }); }); Roll-Template: &lt;rolltemplate class="sheet-rolltemplate-staincheck"&gt; &lt;span&gt;{{name}}&lt;/span&gt; &lt;span&gt;{{roll}}&lt;/span&gt; &lt;span&gt;{{aether_shade}}&lt;/span&gt; &lt;span&gt;{{corruption_shade}}&lt;/span&gt; &lt;span&gt;{{destruction_shade}}&lt;/span&gt; &lt;span&gt;{{purity_shade}}&lt;/span&gt; &lt;span&gt;{{vitality_shade}}&lt;/span&gt; &lt;span&gt;{{unstained}}&lt;/span&gt; &lt;/rolltemplate&gt; As you can see, I am trying to add a span called "Unstained".&nbsp; Unstained Shade is Shade that failed to be 'Stained' into a more potent flavor of Shade in the game.&nbsp; So every failed roll still gives you Shade, but in an allbeit weakened form. So I have tried a few things like: on('clicked:staincheck', event =&gt; { setAttrs({ unstained: 0 }) const stain_string = "&amp;{template:default} {{name=Stain Check}} {{Aether Shade=[[@{aetherscore}d6&gt;@{aetherstain}]]}} {{Corruption Shade=[[@{corruptionscore}d6&gt;@{corruptionstain}]]}} {{Destruction Shade=[[@{destructionscore}d6&gt;@{destructionstain}]]}} {{Purity Shade=[[@{purityscore}d6&gt;@{puritystain}]]}} {{Vitality Shade=[[@{vitalityscore}d6&gt;@{vitalitystain}]]}} {{Unstained=[[@{unstained}]]}}"; startRoll(stain_string, roll =&gt; { console.log(roll); let aether_dice = roll.results.["Aether Shade"].dice; let aether_results = roll.results.["Aether Shade"].result; let corruption_dice = roll.results.["Corruption Shade"].dice; let corruption_results = roll.results.["Corruption Shade"].result; let destruction_dice = roll.results.["Destruction Shade"].dice; let destruction_results = roll.results.["Destruction Shade"].result; let purity_dice = roll.results.["Purity Shade"].dice; let purity_results = roll.results.["Purity Shade"].result; let vitality_dice = roll.results.["Vitality Shade"].dice; let vitality_results = roll.results.["Vitality Shade"].result; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let unstained = (aether_dice - aether_results) + (corruption_dice - corruption_results) + (destruction_dice - destruction_results) + (purity_dice - purity_results) + (vitality_dice - vitality_results); finishRoll(roll.rollId); }); }); and: on('clicked:staincheck', event =&gt; { setAttrs({ unstained: 0 }) const stain_string = "&amp;{template:default} {{name=Stain Check}} {{Aether Shade=[[@{aetherscore}d6&gt;@{aetherstain}]]}} {{Corruption Shade=[[@{corruptionscore}d6&gt;@{corruptionstain}]]}} {{Destruction Shade=[[@{destructionscore}d6&gt;@{destructionstain}]]}} {{Purity Shade=[[@{purityscore}d6&gt;@{puritystain}]]}} {{Vitality Shade=[[@{vitalityscore}d6&gt;@{vitalitystain}]]}} {{Unstained=[[@{unstained}]]}}"; startRoll(stain_string, roll =&gt; { console.log(roll); let aether_dice = roll.results["Aether Shade"].dice; let aether_results = roll.results["Aether Shade"].result; let corruption_dice = roll.results["Corruption Shade"].dice; let corruption_results = roll.results["Corruption Shade"].result; let destruction_dice = roll.results["Destruction Shade"].dice; let destruction_results = roll.results["Destruction Shade"].result; let purity_dice = roll.results["Purity Shade"].dice; let purity_results = roll.results["Purity Shade"].result; let vitality_dice = roll.results["Vitality Shade"].dice; let vitality_results = roll.results["Vitality Shade"].result; let total_dice = aether_dice + corruption_dice + destruction_dice + purity_dice + vitality_dice; let total_results = aether_results + corruption_results + destruction_results + purity_results + vitality_results; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getAttrs(["UNSTAINED","TOTAL_DICE","TOTAL_RESULTS"], function() { let unstained = parseInt(values.UNSTAINED)||0; let total_dice = parseInt(values.TOTAL_DICE)||0; let total_results = parseInt(values.TOTAL_RESULTS)||0; }); setAttrs({ unstained: total_dice - total_results }); and most recently: on('clicked:staincheck', event =&gt; { setAttrs({ unstained: 0 }) const stain_string = "&amp;{template:default} {{name=Stain Check}} {{Aether Shade=[[@{aetherscore}d6&gt;@{aetherstain}]]}} {{Corruption Shade=[[@{corruptionscore}d6&gt;@{corruptionstain}]]}} {{Destruction Shade=[[@{destructionscore}d6&gt;@{destructionstain}]]}} {{Purity Shade=[[@{purityscore}d6&gt;@{puritystain}]]}} {{Vitality Shade=[[@{vitalityscore}d6&gt;@{vitalitystain}]]}} {{Unstained=[[@{unstained}]]}}"; startRoll(stain_string, roll =&gt; { console.log(roll); let aether_dice = roll.results["Aether Shade"].dice; let aether_results = roll.results["Aether Shade"].result; let corruption_dice = roll.results["Corruption Shade"].dice; let corruption_results = roll.results["Corruption Shade"].result; let destruction_dice = roll.results["Destruction Shade"].dice; let destruction_results = roll.results["Destruction Shade"].result; let purity_dice = roll.results["Purity Shade"].dice; let purity_results = roll.results["Purity Shade"].result; let vitality_dice = roll.results["Vitality Shade"].dice; let vitality_results = roll.results["Vitality Shade"].result; let total_dice = aether_dice + corruption_dice + destruction_dice + purity_dice + vitality_dice; let total_results = aether_results + corruption_results + destruction_results + purity_results + vitality_results; let new_unstained = total_dice - total_results; let old_unstained = roll.results["Unstained"].result; let roll.results["Unstained"].result = new_unstained; finishRoll(roll.rollId); }); }); None of which of course have worked thus far...I am trying to figure out how to change the value of Unstained after the roll() has been completed, but not yet finished and displayed.&nbsp; This is where I am having trouble. Otherwise, its working pretty well!
1712093207
GiGs
Pro
Sheet Author
API Scripter
Sheet workers don't know any contents of the character sheet. To grab those attribute values, you need a getAttrs line like you had earlier. I recommended tremoving it because it looked like you weren't using any of the stats in the worker - you might be now. I'll have to look at your code to igure out what's going on and what you really need to do. Can you describe exactly what this roll is, what happens on success, and what happens on failure (and how you determine success and failure)?
Sure.&nbsp; This roll tests how much Shade you pull and how much of it is "Stained" You have a Shade Score in each of the 5 Dominions, and the higher the score the easier it is to Stain for Shade in that Dominion, using D6's. Shade Scores determine both the amount of dice rolled, and the difficulty of Staining. Each Failed Stain roll, is an Unstained Shade. Shade Score Stain&nbsp; 1 6+ 2 5+ 3 4+ 4 3+ 5+ 2+
1712094414

Edited 1712094452
So lets say you have a Shade Score of 3 in Destruction, and a Shade Score of 4 in Aether. You would roll 3d6 for Destruction and 4d6 for Aether. Of your 3 Destruction dice, only results of 4 or higher will be Stained. If you roll [1,3,5] you would get 1 Destruction Shade and 2 Unstained Shade. Of your 4 Aether dice, results of 3 or higher will be Stained.&nbsp; If you roll [2,3,4,6] you would get 3 Aether Shade and 1 Unstained Shade,
1712100545
GiGs
Pro
Sheet Author
API Scripter
How are the shaded and stained ratings used after the roll, later in the game?
1712101324
GiGs
Pro
Sheet Author
API Scripter
By the way, for getting data out of the roll object, first I'd recomment having all your rolls be a single word - you can change the output in a rolltemplate. For example, instead of something like: const stain_string = "&amp;{template:default} {{name=Stain Check}} {{Aether Shade=[[@{aetherscore}d6&gt;@{aetherstain}]]}} {{Corruption Shade=[[@{corruptionscore}d6&gt;@{corruptionstain}]]}} {{Destruction Shade=[[@{destructionscore}d6&gt;@{destructionstain}]]}} {{Purity Shade=[[@{purityscore}d6&gt;@{puritystain}]]}} {{Vitality Shade=[[@{vitalityscore}d6&gt;@{vitalitystain}]]}} {{Unstained=[[@{unstained}]]}}"; Instead have something like const stain_string = "&amp;{template:default} {{name=Stain Check}} {{Aether=[[@{aetherscore}d6&gt;@{aetherstain}]]}} {{Corruption=[[@{corruptionscore}d6&gt;@{corruptionstain}]]}} {{Destruction=[[@{destructionscore}d6&gt;@{destructionstain}]]}} {{Purity=[[@{purityscore}d6&gt;@{puritystain}]]}} {{Vitality=[[@{vitalityscore}d6&gt;@{vitalitystain}]]}} {{Unstained=[[@{unstained}]]}}"; Then you'd grab their total like this: let aether_dice = roll.results.Aether.dice; let aether_results = roll.results.Aether.result; You had this which should have worked, but I see why it didnt: let aether_dice = roll.results["Aether Shade"].dice; let aether_results = roll.results["Aether Shade"].result; You were treating .dice as a number, but it is not, it is an array of dice. You need to add .length if you want it to be a number, like let aether_dice = roll.results.Aether.dice.length; let aether_results = roll.results.Aether.result; or let aether_dice = roll.results["Aether Shade"].dice.length; let aether_results = roll.results["Aether Shade"].result;
Ah! The .length is probably what I was missing...lemme give that a go...
Okay.&nbsp; What the heck??? Sheet-Worker on('clicked:staincheck', event =&gt; { setAttrs({ unstained: 0 }) const stain_string = "&amp;{template:default} {{name=Stain Check}} {{Aether=[[@{aetherscore}d6&gt;@{aetherstain}]]}} {{Corruption=[[@{corruptionscore}d6&gt;@{corruptionstain}]]}} {{Destruction=[[@{destructionscore}d6&gt;@{destructionstain}]]}} {{Purity=[[@{purityscore}d6&gt;@{puritystain}]]}} {{Vitality=[[@{vitalityscore}d6&gt;@{vitalitystain}]]}} {{Unstained=[[@{unstained}]]}}"; startRoll(stain_string, roll =&gt; { console.log(roll); let aether_dice = roll.results.Aether.dice.length; let aether_results = roll.results.Aether.result; let corruption_dice = roll.results.Corruption.dice.length; let corruption_results = roll.results.Corruption.result; let destruction_dice = roll.results.Destruction.dice.length; let destruction_results = roll.results.Destruction.result; let purity_dice = roll.results.Purity.dice.length; let purity_results = roll.results.Purity.result; let vitality_dice = roll.results.Vitality.dice.length; let vitality_results = roll.results.Vitality.result; let dice_total = aether_dice + corruption_dice + destruction_dice + purity_dice + vitality_dice; let result_total = aether_results + corruption_results + destruction_results + purity_results + vitality_results; const new_unstained = dice_total - result_total; roll.results.Unstained.expression = new_unstained; unstained = new_unstained; finishRoll(roll.rollId); }); }); I can successfully alter BOTH Expression and Result, but NEITHER will communicate back to the Roll-Template.
1712115239
GiGs
Pro
Sheet Author
API Scripter
The work you are doing there is calculating computed values, but you haven't set p the function to save those values. You need to do that in finishRoll. What properties do you want to be visible in the rolltemplate?
Oh! Well that makes sense...the only properties I need visible are the Shade amounts generated (Successes) for each Dominion (Aether...Vitality) and the Amount of Unstained Shade generated (Unstained).&nbsp; So six total properties. Aether-Vitality+Unstained.
1712122959
GiGs
Pro
Sheet Author
API Scripter
You can store one property in each rolltemplate key, like so const stain_string = "&amp;{template:default} {{name=Stain Check}} {{Aether=[[@{aetherscore}d6&gt;@{aetherstain}]]}} {{Corruption=[[@{corruptionscore}d6&gt;@{corruptionstain}]]}} {{Destruction=[[@{destructionscore}d6&gt;@{destructionstain}]]}} {{Purity=[[@{purityscore}d6&gt;@{puritystain}]]}} {{Vitality=[[@{vitalityscore}d6&gt;@{vitalitystain}]]}} {{Unstained=[[@{unstained}]]}}"; startRoll(stain_string, roll =&gt; { finishRoll(roll.rollId =&gt; { name: "something", Aether: 3, Corruption: 3+5 }); }); }); You can create empty "rolls" to store values: const stain_string = "&amp;{template:default} {{save_here=[0]}} {{name=Stain Check}} {{Aether=[[@{aetherscore}d6&gt;@{aetherstain}]]}} {{Corruption=[[@{corruptionscore}d6&gt;@{corruptionstain}]]}} {{Destruction=[[@{destructionscore}d6&gt;@{destructionstain}]]}} {{Purity=[[@{purityscore}d6&gt;@{puritystain}]]}} {{Vitality=[[@{vitalityscore}d6&gt;@{vitalitystain}]]}} {{Unstained=[[@{unstained}]]}}"; startRoll(stain_string, roll =&gt; { finishRoll(roll.rollId =&gt; { Aether: 3, Corruption: 3+5, save_here: "something" }); }); }); You can only store these values in inline rolls, so you can't use name because Stain Check is not an inline roll. So can store variables or the result of calculations from earlier in the sheet worker. Then in your rolltemplate, you can use these values with the computed properly. You know how you can show the Aether result with {{Aether}}? You can show the computed value you stored in finish roll like this: {{computed::Aether}} It always starts with computed:: then that key.
...all I was missing was the computed:: &nbsp;part. I had already read up on the empty rolls for adding more stuff...but when I tried to add it back in via {{unstained}}, it would only send out the original value.&nbsp; Lemme give it a try now.
1712173879
GiGs
Pro
Sheet Author
API Scripter
I should have linked this earlier - I have a guide on creating CRP: <a href="https://cybersphere.me/guide-to-custom-roll-parsing/" rel="nofollow">https://cybersphere.me/guide-to-custom-roll-parsing/</a>
1712177395

Edited 1712177564
Yes, I already have that site open in my tabs...sooo, what am I doing wrong? Sheet Worker: on('clicked:staincheck', event =&gt; { const stain_string = "&amp;{template:default} {{name=Stain Check}} {{Aether=[[@{aetherscore}d6&gt;@{aetherstain}]]}} {{Corruption=[[@{corruptionscore}d6&gt;@{corruptionstain}]]}} {{Destruction=[[@{destructionscore}d6&gt;@{destructionstain}]]}} {{Purity=[[@{purityscore}d6&gt;@{puritystain}]]}} {{Vitality=[[@{vitalityscore}d6&gt;@{vitalitystain}]]}} {{Unstained=[[0]]}}"; startRoll(stain_string, roll =&gt; { console.log(roll); let aether_dice = roll.results.Aether.dice.length; let aether_results = roll.results.Aether.result; let corruption_dice = roll.results.Corruption.dice.length; let corruption_results = roll.results.Corruption.result; let destruction_dice = roll.results.Destruction.dice.length; let destruction_results = roll.results.Destruction.result; let purity_dice = roll.results.Purity.dice.length; let purity_results = roll.results.Purity.result; let vitality_dice = roll.results.Vitality.dice.length; let vitality_results = roll.results.Vitality.result; let dice_total = aether_dice + corruption_dice + destruction_dice + purity_dice + vitality_dice; let result_total = aether_results + corruption_results + destruction_results + purity_results + vitality_results; const computed = dice_total - result_total; roll.results.Unstained.result = computed; finishRoll(roll.rollId, **/ =&gt; also does not work here/**){ Unstained: computed, }); }); }); Roll-Template: &lt;rolltemplate class="sheet-rolltemplate-staincheck"&gt; &lt;span&gt;{{name}}&lt;/span&gt; &lt;span&gt;{{roll}}&lt;/span&gt; &lt;span&gt;{{aether}}&lt;/span&gt; &lt;span&gt;{{corruption}}&lt;/span&gt; &lt;span&gt;{{destruction}}&lt;/span&gt; &lt;span&gt;{{purity}}&lt;/span&gt; &lt;span&gt;{{vitality}}&lt;/span&gt; &lt;span&gt;{{computed::unstained}}&lt;/span&gt; &lt;/rolltemplate&gt; I still get this:
1712180866

Edited 1712180941
GiGs
Pro
Sheet Author
API Scripter
You don't have much inside your finishRoll function. If you want to use the computed:: property and the second item in each roll property (Aether, etc..), you'll need to add more there. Your system is pretty complex - I'm not following exactly what you need which is why I was pointing you to places you could hopefully figure it out on your own. If you want my help (and I'm happy to help once I understand what you need), you'll need to describe exactly what you want, all in one post. Give everything I need in that one post, and assume you have said nothing about your system up to now.
Okay, after playing around with some of my other rolls and making more Roll Templates out of them, I eventually got it....now I have an aesthetic issue...I am trying to shrink an image down to 20x20px...but I am now remembering WHY I avoided CSS!!!&nbsp;&nbsp; Here is what I have got... Button/Roll Template: &lt;button type="action" name="act_staincheck"&gt;Stain&lt;/button&gt; &lt;rolltemplate class="sheet-rolltemplate-staincheck"&gt; &lt;div class="sheet-header"&gt; {{#name}}&lt;div class="sheet-name"&gt;{{name}}&lt;/div&gt;{{/name}} &lt;/div&gt; &lt;table&gt; &lt;tbody&gt; &lt;div class="sheet-template-content"&gt; &lt;tr class="sheet-aether_row"&gt; {{#Aether}} &lt;td&gt;&lt;div class="sheet-aether-roll-icon"&gt;&lt;img class="sheet-aether-icon" src="<a href="https://s3.amazonaws.com/files.d20.io/images/387716976/LoT1TR39hDI8vQiFTd34Kg/thumb.png?1712432342" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/387716976/LoT1TR39hDI8vQiFTd34Kg/thumb.png?1712432342</a>" alt="Aether Icon Logo"&gt;&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;div class="sheet-aether-roll-title"&gt;Aether&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;div class="sheet-aether-roll-result"&gt;{{Aether}}&lt;br&gt;&lt;/div&gt;&lt;/td&gt; {{/Aether}} &lt;/tr&gt; &lt;tr class="sheet-corruption_row"&gt; {{#Corruption}} &lt;td&gt;&lt;div class="sheet-corruption-roll-icon"&gt;&lt;img class="sheet-corruption-icon" src="<a href="https://s3.amazonaws.com/files.d20.io/images/387716826/vQzXciBjpL8mmM4d6zwu7g/thumb.png?1712432290" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/387716826/vQzXciBjpL8mmM4d6zwu7g/thumb.png?1712432290</a>" alt="Corruption Icon Logo"&gt;&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;div class="sheet-corruption-roll-title"&gt;Corruption&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;div class="sheet-corruption-roll-result"&gt;{{Corruption}}&lt;br&gt;&lt;/div&gt;&lt;/td&gt; {{/Corruption}} &lt;/tr&gt; &lt;tr class="sheet-destruction_row"&gt; {{#Destruction}} &lt;td&gt;&lt;div class="sheet-destruction-roll-icon"&gt;&lt;img class="sheet-destruction-icon" src="<a href="https://s3.amazonaws.com/files.d20.io/images/387716891/GreHB-W2DFGcHqwUrmfqSw/thumb.png?1712432316" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/387716891/GreHB-W2DFGcHqwUrmfqSw/thumb.png?1712432316</a>" alt="Destruction Icon Logo"&gt;&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;div class="sheet-destruction-roll-title"&gt;Destruction&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;div class="sheet-destruction-roll-result"&gt;{{Destruction}}&lt;br&gt;&lt;/div&gt;&lt;/td&gt; {{/Destruction}} &lt;/tr&gt; &lt;tr class="sheet-purity_row"&gt; {{#Purity}} &lt;td&gt;&lt;div class="sheet-purity-roll-icon"&gt;&lt;img class="sheet-purity-icon" src="<a href="https://s3.amazonaws.com/files.d20.io/images/387716865/pJTQKWHxPghesYG2oRv7Sw/thumb.png?1712432306" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/387716865/pJTQKWHxPghesYG2oRv7Sw/thumb.png?1712432306</a>" alt="Purity Icon Logo"&gt;&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;div class="sheet-purity-roll-title"&gt;Purity&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;div class="sheet-purity-roll-result"&gt;{{Purity}}&lt;br&gt;&lt;/div&gt;&lt;/td&gt; {{/Purity}} &lt;/tr&gt; &lt;tr class="sheet-vitality_row"&gt; {{#Vitality}} &lt;td&gt;&lt;div class="sheet-vitality-roll-icon"&gt;&lt;img class="sheet-vitality-icon" src="<a href="https://s3.amazonaws.com/files.d20.io/images/387716923/J3FOFhYEFRuRveVN9_nWTg/thumb.png?1712432328" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/387716923/J3FOFhYEFRuRveVN9_nWTg/thumb.png?1712432328</a>" alt="Vitality Icon Logo"&gt;&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;div class="sheet-vitality-roll-title"&gt;Vitality&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;div class="sheet-vitality-roll-result"&gt;{{Vitality}}&lt;br&gt;&lt;/div&gt;&lt;/td&gt; {{/Vitality}} &lt;/tr&gt; &lt;tr class="sheet-unstained_row"&gt; {{#Unstained}} &lt;td&gt;&lt;div class="sheet-unstained-roll-icon"&gt;&lt;img class="sheet-unstained-icon" src="<a href="https://s3.amazonaws.com/files.d20.io/images/387718371/YUXVmE5_RKEaaOy_UEcCVA/thumb.png?1712432787" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/387718371/YUXVmE5_RKEaaOy_UEcCVA/thumb.png?1712432787</a>" alt="Unstained Icon Logo"&gt;&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;div class="sheet-unstained-roll-title"&gt;Unstained&lt;/div&gt;&lt;/td&gt; &lt;td&gt;&lt;div class="sheet-unstained-roll-result"&gt;{{computed::Unstained}}&lt;br&gt;&lt;/div&gt;&lt;/td&gt; {{/Unstained}} &lt;/tr&gt; &lt;/div&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;/rolltemplate&gt; CSS: .sheet-rolltemplate-staincheck table { width: 100%; background-color: inherit; border: 1px solid rgba(112, 32, 130, 1); } .sheet-rolltemplate-staincheck tbody { display: table-row-group; vertical-align: middle; unicode-bidi: isolate; border-color: inherit; } .sheet-rolltemplate-staincheck td { padding: 5px; line-height: 1.4em; vertical-align: middle; } *, *::before, *::after { box-sizing: content-box; } .sheet-rolltemplate-staincheck .sheet-template-content .sheet-results .sheet-name .sheet-header { background: default; color: default; text-align: default; display: default; column-gap: default; line-height: default; } .sheet-rolltemplate-staincheck .sheet-template-content .sheet-aether-roll-icon .sheet-aether-row .sheet-aether-icon img.sheet-aether-icon { width: 20px; height: 20px; float: left; } .sheet-rolltemplate-staincheck .sheet-roll-icon .sheet-Corruption img.sheet-corruption-icon { width: 20px; height: 20px; float: left; } .sheet-rolltemplate-staincheck .sheet-roll-icon .sheet-Destruction img.sheet-destruction-icon { width: 20px; height: 20px; float: left; } .sheet-rolltemplate-staincheck .sheet-roll-icon .sheet-Purity img.sheet-purity-icon { width: 20px; height: 20px; float: left; } .sheet-rolltemplate-staincheck .sheet-roll-icon .sheet-Vitality img.sheet-vitality-icon { width: 20px; height: 20px; float: left; } .sheet-rolltemplate-staincheck .sheet-roll-icon .sheet-Unstained img.sheet-unstained-icon { width: 20px; height: 20px; float: left; } Sheet Worker: on('clicked:staincheck', event =&gt; { const stain_string = "&amp;{template:staincheck} {{name=Stain Check}} {{Aether=[[@{aetherscore}d6&gt;@{aetherstain}]]}} {{Corruption=[[@{corruptionscore}d6&gt;@{corruptionstain}]]}} {{Destruction=[[@{destructionscore}d6&gt;@{destructionstain}]]}} {{Purity=[[@{purityscore}d6&gt;@{puritystain}]]}} {{Vitality=[[@{vitalityscore}d6&gt;@{vitalitystain}]]}} {{Unstained=[[0]]}}"; startRoll(stain_string, roll =&gt; { console.log(roll); let aether_dice = parseInt(roll.results.Aether.dice.length)||0; let aether_results = parseInt(roll.results.Aether.result)||0; let corruption_dice = parseInt(roll.results.Corruption.dice.length)||0; let corruption_results = parseInt(roll.results.Corruption.result)||0; let destruction_dice = parseInt(roll.results.Destruction.dice.length)||0; let destruction_results = parseInt(roll.results.Destruction.result)||0; let purity_dice = parseInt(roll.results.Purity.dice.length)||0; let purity_results = parseInt(roll.results.Purity.result)||0; let vitality_dice = parseInt(roll.results.Vitality.dice.length)||0; let vitality_results = parseInt(roll.results.Vitality.result)||0; let unstained_results = parseInt(roll.results.Unstained.result)||0; let dice_total = aether_dice + corruption_dice + destruction_dice + purity_dice + vitality_dice; let result_total = aether_results + corruption_results + destruction_results + purity_results + vitality_results; let new_unstained = dice_total - result_total; roll.results.Unstained.result = new_unstained; roll.results.Unstained.expression = new_unstained; finishRoll(roll.rollId, { Unstained: new_unstained }); }); }); Here is what I am getting thus far, and the goal is to make the Icons on the left small enough to fit in the row naturally:
1712512489
GiGs
Pro
Sheet Author
API Scripter
I don't know how to help you because I don't know what you need. I refer you back yo my previous post. Also, if you hate CSS, writing this caused my hate of CSS to drop significnatly: <a href="https://cybersphere.me/guide-to-css-styling-a-character-sheet/" rel="nofollow">https://cybersphere.me/guide-to-css-styling-a-character-sheet/</a>
Okay I have hit a snag again. What I need is a Skill Test sheet worker, button and roll-template that will output the following: Result Total: 3d6 + Skill Test Modifier If "normal" (rolls of 4-17): "@{This_Character} has rolled {{skillcheck_roll}} + {{modifier}} for {{title}} If Fail (roll of 3, (1 + 1 + 1))): "@{This Character} has failed their {{title}} If Crit (roll of 18, (6 + 6 + 6))):&nbsp;The Shade blesses this {{title}}! TO DO THIS, I need to extract values from the sheet that will change depending on which Skill Test button is pressed, so I need all of them to be able to fill in their own blanks as it were. All of the Skill Test Buttons are all the same: &lt;button type="action" name="act_skillcheck" skill="acrobatics" roll="3d6"&gt;Acrobatics&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="athletics" roll="3d6"&gt;Athletics&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="bluff" roll="3d6"&gt;Bluff&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="diplomacy" roll="3d6"&gt;Diplomacy&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="endurance" roll="3d6"&gt;Endurance&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="heal" roll="3d6"&gt;Heal&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="history" roll="3d6"&gt;History&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="insight" roll="3d6}"&gt;Insight&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="intimidate" roll="3d6"&gt;Intimidate&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="nature" roll="3d6"&gt;Nature&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="perception" roll="3d6"&gt;Perception&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="religion" roll="3d6"&gt;Religion&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="stealth" roll="3d6"&gt;Stealth&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="streetwise" roll="3d6"&gt;Streetwise&lt;/button&gt; &lt;button type="action" name="act_skillcheck" skill="thievery" roll="3d6"&gt;Thievery&lt;/button&gt; The Roll Template is Solid as well: &lt;rolltemplate class="sheet-rolltemplate-skillcheck"&gt; &lt;div class="sheet-container"&gt; &lt;div class="sheet-header"&gt; {{#title}}&lt;div class="sheet-title"&gt;{{title}}&lt;br&gt;&lt;/div&gt;{{/title}} {{#skillcheck_roll}}&lt;div class="sheet-skillcheck-result"&gt;&lt;br&gt; &lt;span&gt;: &lt;/span&gt;{{skillcheck_roll}} + {{modifier}}&lt;br&gt;&lt;/div&gt;&lt;br&gt;{{/skillcheck_roll}} &lt;div class="sheet-skillcheck-norm"&gt; {{#rollBetween() skillcheck_roll 4 17}} {{#skillcheck_norm}}&lt;div class="norm"&gt;{{skillcheck_norm}}&lt;span&gt;: &lt;/span&gt;{{skillcheck_roll}} + {{modifier}}&lt;/div&gt;{{/skillcheck_norm}} {{/rollBetween() skillcheck_roll 4 17}} &lt;/div&gt; &lt;div class="sheet-skillcheck-crit"&gt; {{#rollWasCrit() skillcheck_roll}} {{#skillcheck_crit}}&lt;br&gt;&lt;div class="crit"&gt;{{skillcheck_crit}}&lt;span&gt;&lt;/span&gt;&lt;/div&gt;{{/skillcheck_crit}} {{/rollWasCrit() skillcheck_roll}} &lt;/div&gt; &lt;div class="sheet-skillcheck-fail"&gt; {{#rollWasFumble() skillcheck_roll}} {{#skillcheck_fail}}&lt;div class="fail"&gt;{{skillcheck_fail}}&lt;span&gt;&lt;/span&gt;&lt;/div&gt;{{/skillcheck_fail}} {{/rollWasFumble() skillcheck_roll}} &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/rolltemplate&gt; I suspect my problem is in the Sheet Worker, where I am unsure how to grab that one value from inside the roll to generate the string I need... on('clicked:skillcheck', () =&gt; { getAttrs(['skill'], values =&gt; { const skill = values.skill; let modifier = parseInt(@{values.skill})||0; const rolll_string = `&amp;{template:skillcheck} {{title=${skill} Check}} {(skillcheck_roll=[[3d6]]}} {{modifier=${modifier} }} {{spellbatt_norm= @{magename} has rolled }} {{spellbatt_crit=The Shade blesses this {{title}}!}} {{spellbatt_fail=@{magename} has failed their {{title}}}}` startRoll(roll_string, roll =&gt; { console.log(roll); finishRoll(roll.rollID); }); }); }); const roll_string = `&amp;{template:skillcheck} {{title=Skill Check}} {(skillcheck_roll=[[3d6]]}} {{modifier=""}} {{spellbatt_norm=""}} {{spellbatt_crit=""}} {{spellbatt_fail=""}}` I suspect the primary problem is how I am using the getAttrs and I am unclear HOW I can getting what I need from the Sheet.
1712814258

Edited 1712814338
GiGs
Pro
Sheet Author
API Scripter
From the sounds of things, you need a roll button not an action button. By the way, action buttons can't include all this: &lt;button type="action" name="act_skillcheck" skill="acrobatics" roll="3d6"&gt;Acrobatics&lt;/button&gt; They can only include &lt;button type="action" name="act_acrobatics"&gt;Acrobatics&lt;/button&gt; (They should have unique names, naming them after the skill is esensible.) And then you use the name of skill button to find the information you want. But since you're grabbing stuff that can easily be represented through things like @{acrobatics} and roll=[[3d6]], you are better off setting up roll buttons and don't need a sheet worker: &lt;button type="roll" name="roll_acrobatics" value="&amp;{template:skillcheck} {{title=Acrobatics Skill Check}} {(skillcheck_roll=[[3d6]]}} {{modifier=[[?{modifier?|0}]]}} {{spellbatt_norm=[[0]}} {{spellbatt_crit=[[0]]}} {{spellbatt_fail=[[0]]}}"&gt;Acrobatics&lt;/button&gt; You probably want to change those [[0]] entries to something meaningful, and includer the skill value in there somewhere (@{acrobatics})
1712814740
GiGs
Pro
Sheet Author
API Scripter
I took the roll from the last roll in your worker, and didn't notie the first ine. Seeing that, I'd moify the roll and the rolltemplate. I'fd start by moving the output text into the rolltemplate: &lt;div class="norm"&gt;&lt;span&gt;{{magename}} has rolled : &lt;/span&gt;{{skillcheck_roll}} + {{modifier}}&lt;/div&gt; then change the button value to something like value="&amp;{template:skillcheck} {{title=Acrobatics Skill Check}} {{magename=@{magename}}} {(skillcheck_roll=[[3d6]]}} {{modifier=[[?{modifier?|0}]]}} }}
Thank you!&nbsp; I will try to get that working...quick question as I do though... This is a screenshot from the&nbsp; <a href="https://cybersphere.me/" rel="nofollow">https://cybersphere.me/</a> &nbsp;that reflects something close to what I was trying to do...but as I was doing so, I hit something that seemed a bit unclear... The LAST section of code, in the `getAttrs(['an_input_containing_title', 'the_roll'], values =&gt;` portion... Could you provide me an example of what&nbsp; 'an_input_containing_title' would look like and where on the character sheet it would be pulling those values? So in this example, you Click "Example" Button (an Action Button), and then the Sheet Worker says: "Get this stuff" and turns "stuff" into usable variables, which are then used to make the Roll String...because it doesn't sound like I would be able to refer back to any extra "Button data" to do so...and if that is the case, what COULD you use?
1712851019
GiGs
Pro
Sheet Author
API Scripter
A page link would be helpful!
<a href="https://cybersphere.me/the-crp-roll-string-and-many-buttons-2/" rel="nofollow">https://cybersphere.me/the-crp-roll-string-and-many-buttons-2/</a>
1712876853

Edited 1712877001
GiGs
Pro
Sheet Author
API Scripter
Thanks - thats a clunky URL, I've shortened it to : <a href="https://cybersphere.me/crp-roll-string-and-buttons/" rel="nofollow">https://cybersphere.me/crp-roll-string-and-buttons/</a> I'm not sure what you are really asking here. getAttrs just grabs any value stored in the character sheet as an attribute. It could pull that from any attribute.Here, the idea is that you have a section which contains the title that will be displayed, and the roll, and you use getAttrs to grab them both so you can display them in the output. I probably should have called that "an_input_which_equals_title" - its just meant to be an example, not an actual name used. Is there something specific you want to do?
Okay, I figured it out. Turns out I needed to just put the skills in a drop-down menu with one skill test button rather than having individual buttons for each skill.
1713070622
GiGs
Pro
Sheet Author
API Scripter
Congratilations on getting it sorted!
I started a new thread for the new set of problems, would you mind seeing if you could offer a helping hand? <a href="https://app.roll20.net/forum/post/11863456/automatically-checking-and-un-checking-checkboxes-after-pressing-buttons-to-spend-or-replenish-a-resource-dot-dot-dot/?pageforid=11863456#post-11863456" rel="nofollow">https://app.roll20.net/forum/post/11863456/automatically-checking-and-un-checking-checkboxes-after-pressing-buttons-to-spend-or-replenish-a-resource-dot-dot-dot/?pageforid=11863456#post-11863456</a>
1713124722
GiGs
Pro
Sheet Author
API Scripter
I do think that new threads should be started for new problems. Thanks for the update.