Ok, so, there's something I see in your html that won't work the way you think it will. All input elements (including textareas) must be named, otherwise their data is not saved to firebase and will disappear as soon as you close the sheet or exit the game (might just be exit the game, can't remember for sure). This name must be in the format attr_attribute_name_here . Your curr_Defense input does not have a valid name and so doesn't really do anything. If you need to differentiate between a current value and a max value, just append _max to the end of the attribute name (e.g. attr_defense and attr_defense_max ) For what's going on in the script, this is where logging comes in. You want to log at each important point in your script to figure out what is going on. Something like this: <script type="text/worker"> on("sheet:opened change:reflexes", function() { getAttrs(["reflexes","size"], function(value)) {
console.log(`======== getAttrs entered and value returned ===========`);
console.log(value); let ref = parseInt(value.reflexes,0)||0, siz = parseInt(value.size,0)||4, defrating; //Note that I removed the multiple let declarations here, you can chain them together with commas, and you had forgotten to add a let to defrating, which was then throwing the same error as last time because it wasn't defined.
console.log(`ref=${ref} | siz=${siz}`);
if (ref < 3) { let defrating = 2*(10-siz) } else { let defrating = 2*((10-siz)+ref) }
console.log(`defrating=${defrating}`); setAttrs({ defense: defrating }) } }) </script> You can see the logged results in the developer console of your browser (ctrl-shift-i in chrome pc). The reason I added all those equal signs bracketing the first log was to make it easier to find in the very crowded developer console.