Before I give a sample streamlined way to write the code, I'm going to explain my reasoning. The first thing to understand about if statements in javascript: JS stops working through the code the instant it finds a true result. To explain what this means. Your if statement is structured like this: if (dex === 5) { } if (dex === 4) { } if (dex <= 3) { } We aren't concerned about what's inside each code block, just the overall structure. In the above code, that is three completely separate if statements. lets say that dex is in fact 5. It will look in the if statement, find a matching result, run that code. And then it will go to the next if statement, and test if dex is 4. And then it will go to the next statement, and check if it is below or equal to 3. Now look at this code: if (dex === 5) { } else if (dex === 4) { } else if (dex <= 3) { } This is in fact one if statement. If dex is 5, it will look at the first one, find a match, then completely skip over the rest. There's another benefit to doing it this way. Your other dex tests are like this: if (dex === 16) { } if (dex === 17) { } if (dex >= 18 && dex <= 20) { } if (dex >= 21 && dex <= 23) { } if (dex >= 24) { } There's some complex logic in there like if (dex >= 21 && dex <= 23), that you don't need if you use else, and restructure the code. For instance, you could do this: if (dex >= 24) { } else if (dex >= 21) { } else if (dex >= 18) { } else if (dex === 17) { } else if (dex === 16) { } Remember that the if statement stops when it finds a matchign result, and skips the rest. So you can use if (dex >= 21) - if the if statement reaches that test, it must be below 24, because it didnt stop at the first test. So you don't need the complex logic. When building if statements like this, you do have to be careful to build the tests in the correct order. That's why I reversed the order - you need to test for 24+ before 21+ and before 18+. Those are the benefits of using else. There's another thing to do: analyse the actual numbers. Let's look at the first steps: if (dex >= 24) { dexMod = 5; } else if (dex >= 21) { dexMod = 4; } else if (dex >= 18) { dexMod = 3 } Here, we can see every 3 points of dex gives a +1 bonus up to a max of 5. That is the same as Math.floor(dex / 3) - 3. If we want to limit it to a max of 5, we can use Math.min(). So we can write that as if (dex >= 18) { dexMod = Math.min(5, Math.floor(dex / 3) - 3); } else if (dex > 15) { dexMod = dex-15; } In the above statement we take advantage that dex 16 gives +1, and dex 17 gives +2. In other words, we don't need to include every single dex step: we look at what patterns the system uses, and identify rules for them. Your complete dex statement would then look like this: if ( dex < 6 ) { dexMod = Math . max (- 3 , dex - 6 ); clog ( `low dex penalty: ${ dexMod } ` ); } else if ( dex > 15 ) { if ( dex >= 18 ) { dexMod = Math . min ( 5 , Math . floor ( dex / 3 ) - 3 ); } else { dexMod = dex - 15 ; } clog ( `high dex penalty: ${ dexMod } ` ); } Notice there are a few tweaks here. First the dex scores below 6 all follow the same rule: modifier is [dex -6] (5 = -1, 4 - 2, 3 - 3), to a max of -3. Second there are only two rules for dex scores above 15, and since the branch already checks if dex > 15, you don't need to check for that again - a simple else suffices since everything inside that branch must already by > 15. Honestly that second branch having a nested if statement looks ungainly to me. I might write it more like this: if ( dex < 6 ) { dexMod = Math . max (- 3 , dex - 6 ); clog ( `low dex penalty: ${ dexMod } ` ); } else if ( dex >= 18 ) { dexMod = Math . min ( 5 , Math . floor ( dex / 3 ) - 3 ); clog ( `very high dex penalty: ${ dexMod } ` ); } else if ( dex > 15 ) { dexMod = dex - 15 ; clog ( `high dex penalty: ${ dexMod } ` ); } It's the use of else that allows streamlined if statements like this. That last one is dex >15, but dex 18 never reaches it because the if statement stops at dex >=18. If you didn't need the clog function calls there, I'd go further and use a ternary operator like: const dex_mod = ( dex < 6 ) ? Math . max (- 3 , dex - 6 ) : ( dex >= 18 ) ? Math . min ( 5 , Math . floor ( dex / 3 ) - 3 ) : ( dex > 15 ) ? ( dex - 15 ) : 0 ; That way you don't need a separate let dex_mod = 0; initialisation. Though that's not as easily readable, especially if you aren't very comfortable with ternary operators. Now, another inefficiency in the code is the dexMod calculation is inside the forEach loop. Once the sheet worker has started, dex doesn't change, so that really should be outside of the loop. You only need to calculate it once, not for every row of the section. If you want some output in each row, you could put a command in the forEach loop for that, but the dex calculation itself should be done at the start. Then you have this structure: if (thisflagStr !== '') { /* some stuff */ } if (thisflagStr === 'Primary') { thisflag = +-2; } if (thisflagStr === 'Secondary') { thisflag = +-4; } You already know how to use ternary operators - you have one in
your worker - so you can rewrite those three if statements as a single
statement like so: if (thisflagStr !== '') { thisflag = (thisflagStr === 'Primary') ? -2 : -4; /* some stuff */ } This is because thisflagStr can only have three results: '', 'Primary', and 'Secondary'. So to get inside that if code block, it must be either primary or secondary. When we check for primary, the other one must be the secondary result. Here's a javascript tip, to make that look neater: if (thisflagStr.length) { thisflag = (thisflagStr === 'Primary') ? -2 : -4; /* some stuff */ } This checks how long thisflagStr is, and returns true for any result longer than 0. This works because in javascript, if statements look for truthy or falsy values - these are special javascript properties. Falsy is anything that calculates to false , zero , an empty string (''), null , or undefined . Everything else is truthy. So thisflagStr is truthy if the string contains anythign at all, but if its empty, its falsy. So in our case, where three entries are possible, the if resolves as truthy only if thisflagStr is primary or secondary. So, overall, I'd rewrite the worker something like this (there's one line my tendancy towards compactifying might have gone too far...): on ( 'change:repeating_weapon:weapon_dual change:dexterity' , ( eventInfo ) => { clog ( `Change Detected: ${ eventInfo . sourceAttribute } ` ); getSectionIDs ( 'repeating_weapon' , ( idArray ) => { const fieldnames = idArray . reduce (( fields , id ) => [... fields , `repeating_weapon_ ${ id } _weapon_dual` ], []); getAttrs ([ 'dexterity' , ... fieldnames ], ( v ) => { clog ( 'Weapon Attack Type has been re-calculated' ); const output = {}; const dex = + v . dexterity || 0 ; // dex doesn't change within the loop, so should calculate it first. const dex_mod = ( dex < 6 ) ? Math . max (- 3 , dex - 6 ) : ( dex >= 18 ) ? Math . min ( 5 , Math . floor ( dex / 3 ) - 3 ) : ( dex > 15 ) ? ( dex - 15 ) : 0 ; if ( dex_mod ) { clog ( ` ${ dex_mod > 0 ? 'high' : 'low' } dex penalty: ${ dex_mod } ` ) } // a function to calculate the total bonus. This could be inside the loop, it just makes things easier to read like this (IMO). const handed_mod = ( attack_type , dex_mod ) => attack_type . length ? dex_mod + ( attack_type === 'Primary' ? - 2 : - 4 ) : 0 ; idArray . forEach (( id ) => { const attack_type = v [ `repeating_weapon_ ${ id } _weapon_dual` ]; const thispenalty = Math . min ( 0 , handed_mod ( attack_type , dex_mod )); output [ `repeating_weapon_ ${ id } _weapon_dual_pen` ] = thispenalty ; }); setAttrs ( output , { silent : true }); }); }); }); Feel free to ask questions :)