Iain, I see you are adding an update to the second wind sheet worker, but the code contains the same error that prompted me to make my original bug fix. Here's how to fix it. You have this line: if ( hp <= ( hp_max * 0.5 ) && sw_current > 0 ) { hp_value = Second_Wind + hp ; sw_current_value = sw_current - 1 ; } else { return } The problem with this code is better illustrated if the code is expanded: if ( hp <= ( hp_max * 0.5 ) && sw_current > 0 ) { hp_value = Second_Wind + hp ; sw_current_value = sw_current - 1 ; } else { return } The main problem is any section inside a { } is in its own scope, and is in a way separate from the rest of the script. If you refer to variables there and don't initialise them first, they only exist in that scope, and stop existing as soon as the code moves on past that block. The fix for this is declaring hp_value before the first curly bracket { I would suggest something like this (from getAttrs down): getAttrs ([ "hp_max" , "hp" , "Second_Wind" , "sw_current" ], function ( values ) { // get the hp, hp_max, second wind stat, and coerce into a numerical values. let hp_max = + values . hp_max || 0 ; let hp = + values . hp || 0 ; let sw_current = + values . sw_current || 0 ; let Second_Wind = + values . Second_Wind || 0 ; let hp_value = hp ; // If the character is equal or less than half health then add the value of second wind to current hit points if ( sw_current > 0 ) { // only do anything if SW is over 0 - otherwise second wind isn't applied if ( hp <= ( hp_max * 0.5 )) { hp_value = Math . min ( hp_max , Second_Wind + hp_value ); sw_current = sw_current - 1 ; // you don't need to use a separate variable for sw_current. Technically you don't need hp_value - // you could just modify hp instead of creating hp_value. } else { hp_value = hp_max ; } setAttrs ({ "hp" : hp_value , "sw_current" : sw_current }); // put your startRoll and finishRoll here, so they only run if sw_current is over 0. } }) The main changes: I created let hp_value before the if statement, so it will continue to exist by the time you reach the setAttrs Reorganised the if statement, so the code after that only runs when sw_current is over 0 Put the setAttrs and the starRoll inside this branch of the if statement, for the same reason. If you want to have startRoll run to send some chat message like "no SW left", the best way is to create an else branch for the first if statement, and put a new startRoll there. Note 1: the code assumes second wind's cant raise HP above maximum. That's what this does: Math.min(hp_max, Second_Wind + hp_value); Note 2: you need to edit the other sheet worker, to just add let Second_Wind; before the if statement, otherwise it'll be undefined when setAttrs runs, too.