When pasting code to the forums, its easier to read if you format it as a code block. In the edit window, at the top there's a row of buttons - B, I, U, etc. At the very left is something that looks like a torch. It's a drop down, and Code is in there. Your code would look like on("change:athletics_max", function() { getAttrs(["Athletics_max", "Burglary_max"], function(values){ let unspent = Math.sum(values.Athletics_max, values.Burglary_max); console.log('unspent =' + unspent); setAttrs({ unspent_points: Math.sum(values.Athletics_max, values.Burglary_max) }); }); }); Three things: I dont think Math.sum is valid. At least, I've never seen it. For two numbers, its easier just adding them anyway. Attributes are stored as text, and javascript is very finicky about this - you need to convert the values into a number to perform math. Finally, since you adding burglary_max, you might want to add that to the change line. Putting that together on("change:athletics_max change:burglary_max", function() { getAttrs(["Athletics_max", "Burglary_max"], function(values){
let athletics = +values.Athletics_max || 0;
let burglary = +values.Burglary_max || 0; let unspent = athletics + burglary; console.log('unspent =' + unspent); setAttrs({ unspent_points: unspent }); }); }); A couple of things here: I defined each value separately. This is better for error checking - you can check the value of each attribute if you need to. This is more typing, but is very important especially when you are new and still figuring things out. You need to be able to look at each element of the script and figure out where the problems are occurring. It also makes it easier when you are doing something to this attributes: in this case I've use this expression: + stat ||0; to convert the value into a number. the + at the start turns it into a number, if it is possible . The ||0 at the end says OR ZERO - and returns a value of 0 when it is not possible. So if someone somehow entered the value "six", which is a word, that cant be converted directly to a number, so it becomes zero. This avoids the script breaking, and also can be handy to spot errors when you look at the character sheet and can see an attribute isnt being added properly. You can have issues with empty cells, so even with number inputs, if someone deleted the contents, that might cause an error depending on how you use it, since '' isnt a number. For this reason I always put some error handling (like ||0), even when I cant imagine how an input error can happen. Users will find a way! The only time i dont use error handling is when i am testing a script and want to see the error being created - that's useful information when chasing a problem.