To define just those fields (without going into layout, and labels), there are two main ways. the first is using an autocalc field, like so: <input type="number" name="attr_agility_base" value="5"> <input type="number" name="attr_agility_modifier" value="0"> <input type="number" name="attr_agility" value="@{agility_base}+@{agility_modifier}" disabled> Here I've named the total field just agility, so it can be used in macros with a simple call of @{agility} - easier to type than, say, @{agility_total}. The agility field is a disabled input, which means roll20 will treat it as an autocalc field. That allows you to place a formula or macro in the value, and it willbe automatically calculated (hence the name). The second method is more complicated, but is better if you start adding a lot more automation to your sheet. This is to use a sheet worker. the htm would look almost the same: <input type="number" name="attr_agility_base" value="5"> <input type="number" name="attr_agility_modifier" value="0"> <input type="number" name="attr_agility" value="0" readonly> Note that the agility input has value of 0 and set to readonly. This means that players cant alter it, but scripts can. Then you need to add a scary looking section to the bottom of your html sheet like this: <script type="text/worker"> on("change:agility_base change:agility_modifier sheet:opened", function() { getAttrs(["agility_base","agility_modifier"], function(values) { let base = parseInt(values.agility_base, 10)||0; let mod = parseInt(values.agility_modifier, 10)||0; setAttrs({ agility:base + mod }); }); }); </script> That will set up a hidden function of the sheet that autocalculates the stat total from the base and modifier. That looks like a lot of work to do the same as the autocalc, and indeed it is, especially since you need to repeat it for each of your stats. But there are two advantages: 1) if your sheet gets more complex, and you end up having multiple scores based on other scores, (like a lot of skills and saving throws that are based on values of stats and other stuff), the sheet worker approach is more efficient and less prone to error. Also as sheets get bloated, they can lag, and this cuts down on that. 2) You can streamline the process of adding extra stats. Here's a version of the above sheet worker, that will work for ALL of your stats (assuming they each work the same with a base + mod = total). You only need to create it once, and forget about it: <script type="text/worker">
const stats = ['agility','anotherstat','anotherstat'];
stats.forEach(stat => {
on(`change:${stat}_base change:${stat}_modified sheet:opened`, () => {
getAttrs([`${stat}_base`,`${stat}_modified`], values => {
const score = parseInt(values[`${stat}_base`], 10)||0;
const mod = parseInt(values[`${stat}_modified`], 10)||0;
setAttrs({
[stat]: score + mod
});
});
});
});
</script> The only thing you need to change is line 2: const stats = ['agility','anotherstat','anotherstat']; Just list the various stats in your game here in the same format, so if your stats were strength, agility, intellect, and charisma, it would look like: const stats = ['agility','strength','intellect','charisma']; You can learn more at the wiki: Building Character Sheets Additional Tips on Sheet Workers Using One Sheet Worker For Multiple Stats