I have an idea why it's not working. I on("change:calc-Stärke sheet:opened", function() { getAttrs(['calc-Stärke'], function(value) { I'm not sure how well javascript and roll20 handle non-English characters in attribute names. The on-change line must have all lower case letters, so the above should be on("change:calc-stärke sheet:opened", function() { getAttrs(['calc-Stärke'], function(value) { Give that a try. Note that roll20 recommends using all lower case for attribute names to avoid issues like this. If its still doesnt work, the issue might be the ä, but I think it should handle that. By the way, this is how I would rewrite that sheet worker: on("change:calc-stärke sheet:opened", function () { getAttrs(['calc-Stärke'], function (value) { const score = parseInt(value['calc-Stärke']) || 0; const mod = Math.max(0, Math.floor(score/3) -2); setAttrs({ 'mod-Stärke': mod }); }); }); Since the modifier goes up by 1 for every 3 stat points, we can calculate the modifier by simply dividing by 3. If you have a lot of stats you can handle them all in one go with a worker like this: const stats = ['Stärke']; stats.forEach(stat => { on(`change:calc-${stat.toLowerCase()} sheet:opened`, function () { getAttrs([`calc-${stat}`], function (value) { const score = parseInt(value[`calc-${stat}`]) || 0; const mod = Math.max(0, Math.floor(score/3) -2); setAttrs({ [`mod-${stat}`]: mod }); }); }); }); This assumes all stats have calc- at the start, and mod- at the start of their modifier name. You add extra stats my changing this line const stats = ['Stärke']; Just add the bit after calc- for each attribute in there, like const stats = ['Stärke', 'Dexterity', 'Intellect', 'Education'];