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

trying to understand the worker scripts

I'm currently trying to understand the worker scripts. I made a small example as shown below. the sheet opened works as intended, but the change does never trigger. And I dont get any error messages in the console either, so I'm wondering where my train of thought went erronous?    <h1>MyName</h1>     <h2>Stats</h2>     <table>         <tr>             <th>                 Exp             </th>             <td>                 <input name="exp" id="exp" />             </td>             <th>                 Level             </th>             <td>                 <input name="level" id="level">             </td>         </tr>         <tr>             <th>                 Classes             </th>             <td>                 <input name="classes" id="classes">                              </td>             <th>                 Demon             </th>             <td>                 <input type="checkbox" id="isDemon" name="isDemon" />             </td>         </tr>         <tr>             <th>ST</th>             <td><input type="text" name="ST" id="ST"/></td>             <td><input readonly name="STTN" id="STTN"/></td>         </tr>     </table>           <script type="text/worker"> on("sheet:opened", function() {         console.log("Sheet opened, JS is running");         /*getAttrs(["level", "ST"], function(values) {             let operation = values.level + (5*values.ST);             setAttrs({                 "STTN": operation             });         });*/     }); on("change:ST", function() {     console.log("ST changed"); }); on("change:level", function() {     console.log("level changed"); });     </script>
1724507625

Edited 1724513681
GiGs
Pro
Sheet Author
API Scripter
Your problem isn't with the workers (though there is a problem there), it's with the HTML. The name tag in attributes must start attr_ , like so &lt;input type="number" name="attr_exp" id="exp" /&gt; Also, the type is required - you'll want to use text or number . (There are some exceptions- you have checkbox for example. But text or number will cover the vast majority of cases.) Also (this isn't necessary, just a preference though you may find things work better), I'd say generally avoid ids, uses classes instead, and include a default value, like this: &lt;input type="number" name="attr_exp" class="exp" value="0"/&gt; Having a default value will make the worker code easier and avoid a lot of errors. You'll need to edit every input. Your sheet workers were not running because the attribute change was not being triggered, because the attribute of the correct name wasn't changed (it didn't exist). When you have a sheet worker that starts like this: on("sheet:opened", function() { that sheet worker will run only when the sheet is opened. It will not run in response to any attribute changes, so you should only start certain types of workers like that. If you aren't sure, don't do it. This line also has a problem: let operation = values.level + (5*values.ST); Roll20 stores values by default as strings, a form of text. When the + operator is found, roll20 checks if it is a string, and if so it adds the number to the end - it does't attempt to try an addition. So lets say ST was 1, and level was 3, you would naively expect this to give operation = 8 . It's far more likely you would get operation = 35 , or an error. For this worker, you really need: on("change:ST change:level", function() { &nbsp; &nbsp; console.log("ST changed"); &nbsp; &nbsp; console.log("level changed"); getAttrs(["ST", "level"[, function(values) { const st = Number(values.ST) || 0; const level = Number(values.ST) || 0; const operation = level + st * 5; setttrs({ STTN: operation }); } }); This thing: Number(values.ST) || 0; does two things. Numer(something) converts something into a number, if it is something that can be converted into a number , and returns an error if it can't be converted. The || 0 says OR&nbsp; 0 . This basically means if the bit before || returns an error, use the number 0 instead. Hope this helps! Also check out <a href="https://cybersphere.me/roll20/" rel="nofollow">https://cybersphere.me/roll20/</a> for an approachable guide to all the pats of creating a character sheet.
1724509970

Edited 1724513857
GiGs
Pro
Sheet Author
API Scripter
I'd be remiss if I didn't say, don't use tables . Use CSS Grid instead. You HTML would look something like this &lt; h1 &gt; MyName &lt;/ h1 &gt; &lt; h2 &gt; Stats &lt;/ h2 &gt; &lt; div class= "stats" &gt; &nbsp; &nbsp; &lt; span &gt; Exp &lt;/ span &gt; &nbsp; &nbsp; &lt; input type="number" name= "attr_exp" class= "exp" /&gt; &nbsp; &nbsp; &lt; span &gt; Level &lt;/ span &gt; &nbsp; &nbsp; &lt; input type="number" name= "attr_level" class= "level" &gt; &nbsp; &nbsp; &lt; span &gt; Classes &lt;/ span &gt; &nbsp; &nbsp; &lt; input type="text" name= "attr_classes" class= "classes" &gt; &nbsp; &nbsp; &lt; span &gt; Demon &lt;/ span &gt; &nbsp; &nbsp; &lt; input type= "checkbox" class= "isDemon" name= "attr_isDemon" value= "1" /&gt; &nbsp; &nbsp; &lt; span &gt; ST &lt;/ span &gt; &nbsp; &nbsp; &lt; input type= "text" name= "attr_ST" class= "ST" /&gt;&lt;/ td &gt; &nbsp; &nbsp; &lt; span &gt; STTN &lt;/ span &gt; &nbsp; &nbsp; &lt; input readonly type="text" name= "attr_STTN" class= "STTN" /&gt; &lt;/ div &gt; The complete lack of table/tr/td etc makes this code easier to write. Then in your CSS tab, you'd have something like .charsheet .stats { &nbsp; &nbsp; display : grid ; &nbsp; &nbsp; grid-template-columns : 80px 50px 80px 50px ; &nbsp; &nbsp; column-gap : 5px ; } .charsheet .stats span { &nbsp; &nbsp; /* include whatever formatting you want those spans to have to look like headings */ &nbsp; &nbsp; font-weight : bold ; } The first part sets up a grid layout with 4 columns. You can set the width of each of the 4 columns exactly, and column-gap creates spacing between each column. Those 3 lines replace all of your table/tr/td/th statements. Regarding width: roll20 sometimes applies specific styling to elements like input that you have to override, and you might want need to add a witdh: auto or width: 100% to those items. Use div instead of table , give that div a class, and place the grid commands inside that class in CSS. Also put text inside spans or other HTML objects, so they can be properly detected by the grid.