Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Build lookup table into a character sheet

I'm wanting to include into my character sheet lookups so that when for example a race is picked - all race bonuses are automatically populated, or once the stats have been entered any bonuses based on these stats are also automatically populated (I have other examples as well where I would like to use similar functionality). In the case of race bonuses it will be a direct Race = these bonuses, for the stats there are bands for the bonuses (for example 75-89 = +5 bonus) Is it possible for someone to advise (or direct me to a URL which explains the process and what I need to do for this? Thanks
1542149648

Edited 1542150018
Diana P
Pro
Sheet Author
The full-calc version of the RMSS sheet has sheet workers which do its version of that.&nbsp; Github for it is <a href="https://github.com/Roll20/roll20-character-sheets/tree/master/Rolemaster-Standard-System" rel="nofollow">https://github.com/Roll20/roll20-character-sheets/tree/master/Rolemaster-Standard-System</a> use the charsheet_RMSS_fullcalcs_RollTemplates.html file (along with the translation.json and charsheet_RMSS.css files) if you want to see it in action, but part of the relevant code is in the sheet worker section and looks like: // &lt;!-- Race Fixed Info (Stat, RR bonuses + Soul Departure/Recovery Multiplier) Setup --&gt; function RaceFixedInfoSetup(racialindex, index, currentval) { mod = 0; // console.log('/* ----------inside RaceFixedInfoSetup rank:'+racialindex+'------------ */'); if (racialindex == 10) { //-------Common Man------- if (index == 1) {mod = 0;} //Ag else if (index == 2) {mod = 0;} //Co else if (index == 3) {mod = 0;} //Me else if (index == 4) {mod = 0;} //Re else if (index == 5) {mod = 2;} //SD else if (index == 6) {mod = 0;} //Em else if (index == 7) {mod = 0;} //In else if (index == 8) {mod = 0;} //Pr else if (index == 9) {mod = 0;} //Qu else if (index == 10) {mod = 2;} //St else if (index == 11) {mod = 0;} //Ess else if (index == 12) {mod = 0;} //Chan else if (index == 13) {mod = 0;} //Ment else if (index == 14) {mod = 0;} //Poison else if (index == 15) {mod = 0;} //Disease else if (index == 16) {mod = 12;} //Soul Departure else if (index == 17) {mod = 1;} //Recovery Multiplier else if (index == 18) {mod = 2;} //Race Type for Stat Loss else if (index == 19) {mod = 0;} //Bonus Exhaustion Points } else if (racialindex == 11) { //-------Mixed Man------- if (index == 1) {mod = 0;} //Ag else if (index == 2) {mod = 2;} //Co else if (index == 3) {mod = 0;} //Me else if (index == 4) {mod = 0;} //Re else if (index == 5) {mod = 2;} //SD else if (index == 6) {mod = 2;} //Em else if (index == 7) {mod = 0;} //In else if (index == 8) {mod = 2;} //Pr else if (index == 9) {mod = 0;} //Qu else if (index == 10) {mod = 2;} //St else if (index == 11) {mod = 0;} //Ess else if (index == 12) {mod = 0;} //Chan else if (index == 13) {mod = 0;} //Ment else if (index == 14) {mod = 0;} //Poison else if (index == 15) {mod = 0;} //Disease else if (index == 16) {mod = 11;} //Soul Departure else if (index == 17) {mod = 0.9;} //Recovery Multiplier else if (index == 18) {mod = 2;} //Race Type for Stat Loss else if (index == 19) {mod = 0;} //Bonus Exhaustion Points } else if (racialindex == 12) { //-------High Man------- if (index == 1) {mod = -2;} //Ag else if (index == 2) {mod = 4;} //Co else if (index == 3) {mod = 0;} //Me else if (index == 4) {mod = 0;} //Re else if (index == 5) {mod = 0;} //SD else if (index == 6) {mod = 0;} //Em else if (index == 7) {mod = 0;} //In else if (index == 8) {mod = 4;} //Pr else if (index == 9) {mod = -2;} //Qu else if (index == 10) {mod = 4;} //St else if (index == 11) {mod = -5;} //Ess else if (index == 12) {mod = -5;} //Chan else if (index == 13) {mod = -5;} //Ment else if (index == 14) {mod = 0;} //Poison else if (index == 15) {mod = 0;} //Disease else if (index == 16) {mod = 10;} //Soul Departure else if (index == 17) {mod = 0.75;} //Recovery Multiplier else if (index == 18) {mod = 2;} //Race Type for Stat Loss else if (index == 19) {mod = 0;} //Bonus Exhaustion Points // ******* additional Code Snipped for length.... ******** } else if (racialindex == 52) { //-------None; Reset to zero------- if (index == 1) {mod = 0;} //Ag else if (index == 2) {mod = 0;} //Co else if (index == 3) {mod = 0;} //Me else if (index == 4) {mod = 0;} //Re else if (index == 5) {mod = 0;} //SD else if (index == 6) {mod = 0;} //Em else if (index == 7) {mod = 0;} //In else if (index == 8) {mod = 0;} //Pr else if (index == 9) {mod = 0;} //Qu else if (index == 10) {mod = 0;} //St else if (index == 11) {mod = 0;} //Ess else if (index == 12) {mod = 0;} //Chan else if (index == 13) {mod = 0;} //Ment else if (index == 14) {mod = 0;} //Poison else if (index == 15) {mod = 0;} //Disease else if (index == 16) {mod = 0;} //Soul Departure else if (index == 17) {mod = 0;} //Recovery Multiplier else if (index == 18) {mod = 0;} //Race Type for Stat Loss else if (index == 19) {mod = 0;} //Bonus Exhaustion Points } else if (racialindex == 1) {mod = currentval;} //------Custom------ // console.log('/* ----------leaving RaceFixedInfoSetup mod:'+mod+'------------ */'); return mod; } it is called further down by: // &lt;!---- Update Body Dev progression,Racial bonuses for RR's and Stats etc when racialindex changes.----&gt; on("change:racialindex change:racialcalc", function() { getAttrs(["racialindex", "bodydevprog0", "bodydevprog10", "bodydevprog20", "bodydevprog30", "bodydevprog31", "agracial", "coracial", "meracial", "reracial", "sdracial", "emracial", "inracial", "prracial", "quracial", "stracial", "esssaverace", "chansaverace", "mentsaverace", "poisonsaverace", "diseasesaverace", "souldepart", "recoverymult", "racialnotes", "racialcalc", "racetypeforstatloss", "exhaustmiscbonus"], function(values) { // console.log('/* ---------- can we set up racial bonuses?------------ */'); if (parseInt(values.racialcalc) == 1){ // console.log('/* ---------- racial calc is 1; setup racialbonuses etc!------------ */'); setAttrs({ bodydevprog0: BodyDevProgMod(parseInt(values.racialindex,10), 0, parseInt(values.bodydevprog0,10)), bodydevprog10: BodyDevProgMod(parseInt(values.racialindex,10), 10, parseInt(values.bodydevprog10,10)), bodydevprog20: BodyDevProgMod(parseInt(values.racialindex,10), 20, parseInt(values.bodydevprog20,10)), bodydevprog30: BodyDevProgMod(parseInt(values.racialindex,10), 30, parseInt(values.bodydevprog30,10)), bodydevprog31: BodyDevProgMod(parseInt(values.racialindex,10), 31, parseInt(values.bodydevprog31,10)), agracial: RaceFixedInfoSetup(parseInt(values.racialindex,10), 1, parseInt(values.agracial,10)), coracial: RaceFixedInfoSetup(parseInt(values.racialindex,10), 2, parseInt(values.coracial,10)), meracial: RaceFixedInfoSetup(parseInt(values.racialindex,10), 3, parseInt(values.meracial,10)), reracial: RaceFixedInfoSetup(parseInt(values.racialindex,10), 4, parseInt(values.reracial,10)), sdracial: RaceFixedInfoSetup(parseInt(values.racialindex,10), 5, parseInt(values.sdracial,10)), emracial: RaceFixedInfoSetup(parseInt(values.racialindex,10), 6, parseInt(values.emracial,10)), inracial: RaceFixedInfoSetup(parseInt(values.racialindex,10), 7, parseInt(values.inracial,10)), prracial: RaceFixedInfoSetup(parseInt(values.racialindex,10), 8, parseInt(values.prracial,10)), quracial: RaceFixedInfoSetup(parseInt(values.racialindex,10), 9, parseInt(values.quracial,10)), stracial: RaceFixedInfoSetup(parseInt(values.racialindex,10), 10, parseInt(values.stracial,10)), esssaverace: RaceFixedInfoSetup(parseInt(values.racialindex,10), 11, parseInt(values.esssaverace,10)), chansaverace: RaceFixedInfoSetup(parseInt(values.racialindex,10), 12, parseInt(values.chansaverace,10)), mentsaverace: RaceFixedInfoSetup(parseInt(values.racialindex,10), 13, parseInt(values.mentsaverace,10)), poisonsaverace: RaceFixedInfoSetup(parseInt(values.racialindex,10), 14, parseInt(values.poisonsaverace,10)), diseasesaverace: RaceFixedInfoSetup(parseInt(values.racialindex,10), 15, parseInt(values.diseasesaverace,10)), souldepart: RaceFixedInfoSetup(parseInt(values.racialindex,10), 16, parseInt(values.souldepart,10)), recoverymult: RaceFixedInfoSetup(parseInt(values.racialindex,10), 17, parseInt(values.recoverymult,10)), racetypeforstatloss: RaceFixedInfoSetup(parseInt(values.racialindex,10), 18, parseInt(values.racetypeforstatloss,10)), exhaustmiscbonus: RaceFixedInfoSetup(parseInt(values.racialindex,10), 19, parseInt(values.exhaustmiscbonus,10)) }); } }); // console.log('/* ---------- exiting set up racial bonuses call------------ */'); }); There may be more efficient ways of doing this (I am not the best programmer) but it does work. Basically in this I am changing which racial bonuses are applied to a variety of sections when the race changes. edit: some wording.
1542149859

Edited 1542150184
Diana P
Pro
Sheet Author
I calculate the rest of it with the sections that look like: // &lt;!---- Update bonus on current stat change. Do this for each stat ----&gt; on("change:agility change:statcalc", function() { getAttrs(["agility", "agbasebonus", "statcalc"], function(values) { if (parseInt(values.statcalc) == 1){ setAttrs({ agbasebonus: StatMod(parseInt(values.agility,10)) }); } }); }); on("sheet:opened change:agbasebonus change:agracial change:agspecial", function() { getAttrs(["agbasebonus", "agracial", "agspecial", "agbonus"], function(values) { setAttrs({ agbonus: StatCalc(parseInt(values.agbasebonus,10), parseInt(values.agracial,10), parseInt(values.agspecial,10)) }); }); }); which calls // &lt;!-- Stat Mod Calculation --&gt; function StatMod(stat) { let mod = 0; if (stat &lt; 11) { mod = Math.round((stat - 21) / 2); } else if (stat &lt; 31) { mod = Math.round((stat - 33) / 5); } else if (stat &lt; 70) { mod = 0; } else if (stat &lt; 90) { mod = Math.round((stat - 67) / 5); } else if (stat &lt; 101) { mod = Math.round((stat - 81) / 2); } else if (stat &gt; 100) { mod = Math.round((stat - 95) * 2); } return mod; } // &lt;!-- Stat Calculation --&gt; function StatCalc(base, racial, special) { mod = base + racial + special; return mod; } These sections calculate the stat bonuses and then the totals when any part of the stat bonus calculation changes (or if you turn on using calculations). Hope that helps. edit:&nbsp; more wording.
1542173198

Edited 1542173756
GiGs
Pro
Sheet Author
API Scripter
For calculating the bonuses from stats, the if else method Diana showcases works fine. Something like: if (stat &gt; 99) bonus = (stat-95) *5; else if (stat &gt; 97) bonus = 20; else if (stat &gt; 94) bonus = 15; else if (stat &gt;89) bonus = 10; //and so on down to the minimum, For the racial bonuses, there is a better way to do this.&nbsp; In your race sheetworker, have a variable that stores all the race stats in this format: const races = { &nbsp; &nbsp; &nbsp;human: {strength: 0, dexterity: 0, constitution: 0, intelligence: 0, wisdom: 0, charisma: 0}, &nbsp; &nbsp; &nbsp;elf: {strength: 0, dexterity: 2, constitution: 0, intelligence: 0, wisdom: 0, charisma: 0}, &nbsp; &nbsp; &nbsp;dwarf: {strength: 0, dexterity: 0, constitution: 2, intelligence: 0, wisdom: 0, charisma: 0} }; This is your races data object . Pay careful attention to the position of commas, colons, brackets, and the final semi-colon. The basic structure is const data = { &nbsp; &nbsp; &nbsp; &nbsp;item: {subitem1 name: subitem1 value, subitem2 name: subitem2 value, subitem3 name, subitem3 value}, &nbsp; &nbsp; &nbsp; &nbsp;anotherItem: {subitem1 name: subitem1 value, subitem2 name: subitem2 value, subitem3 name, subitem3 value} }; Then later in your script, you can call them like this: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let strMod = races[race].strength; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let dexMod = races[race].dexterity; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let wisMod = races[race].wisdom; Note that race &nbsp;here is your input from the character sheet. You might need to test it the race exists within the races data object, which you can do using hasOwnProperty, like this: if (races. hasOwnProperty ( race )) { &nbsp; &nbsp; &nbsp;// do stuff here } else { &nbsp; &nbsp; // handle what happens if the item doesnt exist - send an error report? &nbsp; &nbsp; &nbsp;console.log("Error: The item " + race + " is not found within the race Object."); &nbsp; &nbsp; &nbsp;return; } Though this isnt strictly necessary if you have hardcoded all races and made sure players cant enter their own values.&nbsp; So the whole thing would look something like: on("change:race", function () { getAttrs(['race'], function(values) { const races = { &nbsp; &nbsp; &nbsp; human: {strength: 0, dexterity: 0, constitution: 0, intelligence: 0, wisdom: 0, charisma: 0}, &nbsp; &nbsp; &nbsp; elf: {strength: 0, dexterity: 0, constitution: 0, intelligence: 0, wisdom: 0, charisma: 0}, &nbsp; &nbsp; &nbsp; dwarf: {strength: 0, dexterity: 0, constitution: 0, intelligence: 0, wisdom: 0, charisma: 0} }; let race = values.race;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!races. hasOwnProperty ( race )) { &nbsp; &nbsp; &nbsp;// I reversed the order from the example above for simplicity &nbsp; &nbsp; &nbsp; console.log("Error: The item " + race + " is not found within the race Object."); &nbsp; &nbsp; &nbsp; return; }&nbsp; setAttrs({ &nbsp;&nbsp;&nbsp;&nbsp; "strMod": races[race].strength, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"dexMod": races[race].dexterity, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"conMod": races[race].constitution // etc, fill the extra stats in. }); }); }); This method is much more compact than using if else or switch structures, and is much more easily expandable later. PS: if you need to know more, google Javascript Object Literal , and that should give you plenty of links.
1542207290
Pat S.
Forum Champion
Sheet Author
This thread is interesting. I have debating on setting up the Basic Fantasy RPG sheet in this manner but it would be input the races and class then the sheet would autopopulate saving throws, and some other fields.
Thanks for the replies. I will test this out and let you know - especially Pat S how easy this is to implement.
So my field in the html has name="attr_character_race" I have adapted the script above to be: &lt;script&gt; &nbsp; &nbsp; on("change:character_race", function () { &nbsp; &nbsp; &nbsp; &nbsp; getAttrs(['character_race'], function(values) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const races = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Dwarf: {strength: 5, agility: -5, constitution: 15, intelligence: 0, intuition: -5, presence: -5} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let character_race= values.character_race;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!races.hasOwnProperty( character_race )) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// I reversed the order from the example above for simplicity &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;console.log("Error: The item " + character_race + " is not found within the race Object."); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setAttrs({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "char_str_race": races[character_race].strength, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "char_agi_race": races[character_race].agility, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "char_con_race": races[character_race].constitution, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "char_int_race": races[character_race].intelligence, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "char_itn_race": races[character_race].intuition, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "char_pre_race": races[character_race].presence &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; }); &lt;/script&gt; and I have placed this at the bottom of the html file when I save this and test it on my character sheet in game mode - the values of the race bonuses are not changing (the race bonuses have a name of char_&lt;type&gt;_race) Please can you advise where I am going wrong?
Just as a little more info My select statement for the race is as follows: &lt;td class="sheet-table-data-left"&gt;&lt;select name="attr_character_race" style="width: 100px"&gt; &lt;option value="HalfElf"&gt;Half-Elf&lt;/option&gt; &lt;option value="NoldoElf"&gt;Noldo Elf&lt;/option&gt; &lt;option value="SindaElf"&gt;Sinda Elf&lt;/option&gt; &lt;option value="SilvanElf"&gt;Silvan Elf&lt;/option&gt; &lt;option value="Hobbit"&gt;Hobbit&lt;/option&gt; &lt;option value="Dwarf"&gt;Dwarf&lt;/option&gt; &lt;option value="Beorning"&gt;Beorning&lt;/option&gt; &lt;option value="Dunlending"&gt;Dunlending&lt;/option&gt; &lt;option value="Dunedain"&gt;Dunedain&lt;/option&gt; &lt;option value="Eriadoan"&gt;Eriadoran&lt;/option&gt; &lt;option value="Gondorian"&gt;Gondorian&lt;/option&gt; &lt;option value="Rohirrim"&gt;Rohirrim&lt;/option&gt; &lt;option value="Woodmen"&gt;Woodmen&lt;/option&gt; &lt;/select&gt; &lt;/td&gt;
For the Stat bonus I have tried this. After changing the value of: attr_char_agi_val the bonus field (attr_char_agi_norm) does not get populated. &lt;script type="text/worker"&gt; // &lt;!-- Stat Mod Calculation --&gt; function StatMod(stat) { &nbsp; let mod = 0; &nbsp; if (stat &lt; 11) { &nbsp; mod = 1; &nbsp; } else if (stat &lt; 31) { &nbsp; mod = 2; &nbsp; } else if (stat &lt; 70) { &nbsp; mod = 0; &nbsp; } else if (stat &lt; 90) { &nbsp; mod = 3; &nbsp; } else if (stat &lt; 101) { &nbsp; mod = 4; &nbsp; } else if (stat &gt; 100) { &nbsp; mod = 5; &nbsp; } &nbsp; return mod; &nbsp;&nbsp; on("change:char_agi_val", function() { getAttrs(["char_agi_val", "char_agi_norm"], function(values) { setAttrs({ &nbsp; char_agi_norm: StatMod(values.char_agi_val) }); } }); &lt;/script&gt;
1542233880
GiGs
Pro
Sheet Author
API Scripter
I'll check this out a little bit later. But first, make sure you only have one script block like this &lt;script type="text/worker"&gt; &lt;/script&gt; And put all your sheetworkers and functions inside that single script block. Also can you post the html for the stat section where these values are to be output to? For formatting it to look like code when writing to the forums, when youre writing a post notice the bar of buttons across the top of the chat box. Click the left most button that has a dropdown, and select code. If you have a section of code selected, this will format it properly.
1542234315
GiGs
Pro
Sheet Author
API Scripter
For the second part, the function looks like its missing a closure. You have this: function StatMod(stat) { &nbsp; let mod = 0; &nbsp; if (stat &lt; 11) { &nbsp; mod = 1; &nbsp; } else if (stat &lt; 31) { &nbsp; mod = 2; &nbsp; } else if (stat &lt; 70) { &nbsp; mod = 0; &nbsp; } else if (stat &lt; 90) { &nbsp; mod = 3; &nbsp; } else if (stat &lt; 101) { &nbsp; mod = 4; &nbsp; } else if (stat &gt; 100) { &nbsp; mod = 5; &nbsp; } &nbsp; return mod; It should be function StatMod(stat) { &nbsp; let mod = 0; &nbsp; if (stat &lt; 11) { &nbsp; mod = 1; &nbsp; } else if (stat &lt; 31) { &nbsp; mod = 2; &nbsp; } else if (stat &lt; 70) { &nbsp; mod = 0; &nbsp; } else if (stat &lt; 90) { &nbsp; mod = 3; &nbsp; } else if (stat &lt; 101) { &nbsp; mod = 4; &nbsp; } else if (stat &gt; 100) { &nbsp; mod = 5; &nbsp; } &nbsp; return mod; } Notice the bracket at the end. Also the following function is missing some closure at the end. This: on("change:char_agi_val", function() { getAttrs(["char_agi_val", "char_agi_norm"], function(values) { setAttrs({ &nbsp; char_agi_norm: StatMod(values.char_agi_val) }); } }); should be on("change:char_agi_val", function() { getAttrs(["char_agi_val", "char_agi_norm"], function(values) { setAttrs({ &nbsp; char_agi_norm: StatMod(values.char_agi_val) }); }); }); Notice the last 3 lines all should have same brackets and semicolons.
1542237921

Edited 1542241659
GiGs
Pro
Sheet Author
API Scripter
I tested the race script, and it worked for me. I set up a basic character sheet using the select you pasted above, and quickly adding 6 stats, like so: &lt;select name="attr_character_race" style="width: 100px"&gt; &lt;option value="HalfElf"&gt;Half-Elf&lt;/option&gt; &lt;option value="NoldoElf"&gt;Noldo Elf&lt;/option&gt; &lt;option value="SindaElf"&gt;Sinda Elf&lt;/option&gt; &lt;option value="SilvanElf"&gt;Silvan Elf&lt;/option&gt; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&lt;option value="Hobbit"&gt;Hobbit&lt;/option&gt; &lt;option value="Dwarf"&gt;Dwarf&lt;/option&gt; &lt;option value="Beorning"&gt;Beorning&lt;/option&gt; &lt;option value="Dunlending"&gt;Dunlending&lt;/option&gt; &lt;option value="Dunedain"&gt;Dunedain&lt;/option&gt; &lt;option value="Eriadoan"&gt;Eriadoran&lt;/option&gt; &lt;option value="Gondorian"&gt;Gondorian&lt;/option&gt; &lt;option value="Rohirrim"&gt;Rohirrim&lt;/option&gt; &lt;option value="Woodmen"&gt;Woodmen&lt;/option&gt; &lt;/select&gt; &lt;br/&gt; &lt;label&gt;STR&lt;/label&gt; &lt;input type="number" class="sheet-open" name="attr_char_str_race" /&gt; &lt;br/&gt; &lt;label&gt;AGL&lt;/label&gt; &lt;input type="number" class="sheet-open" name="attr_char_agi_race" /&gt; &lt;br/&gt; &lt;label&gt;CON&lt;/label&gt; &lt;input type="number" class="sheet-open" name="attr_char_con_race" /&gt; &lt;br/&gt; &lt;label&gt;intelligence&lt;/label&gt; &lt;input type="number" class="sheet-open" name="attr_char_int_race" /&gt; &lt;br/&gt; &lt;label&gt;Intuition&lt;/label&gt; &lt;input type="number" class="sheet-open" name="attr_char_itn_race" /&gt; &lt;br/&gt; &lt;label&gt;Presence&lt;/label&gt; &lt;input type="number" class="sheet-open" name="attr_char_pre_race" /&gt; &lt;br/&gt; I then added the script you pasted earlier in its script block &nbsp;on("change:character_race", function () { &nbsp; &nbsp; &nbsp; &nbsp; getAttrs(['character_race'], function(values) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const races = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Dwarf: {strength: 5, agility: -5, constitution: 15, intelligence: 0, intuition: -5, presence: -5} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let character_race= values.character_race;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!races.hasOwnProperty( character_race )) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// I reversed the order from the example above for simplicity &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;console.log("Error: The item " + character_race + " is not found within the race Object."); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setAttrs({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "char_str_race": races[character_race].strength, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "char_agi_race": races[character_race].agility, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "char_con_race": races[character_race].constitution, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "char_int_race": races[character_race].intelligence, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "char_itn_race": races[character_race].intuition, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "char_pre_race": races[character_race].presence &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; }); And it worked perfectly. Notice when you change to Dwarf, it'll set the race values correctly. When you change to any other race, it wont change the stats, because those other races don't exist in the races object, so the script ends before making any changes.&nbsp;
1542242011
GiGs
Pro
Sheet Author
API Scripter
I suggest the following tweaks: change the first line of the script from on("change:character_race", function () { to on("change:character_race sheet:opened", function () { And in your race dropdown, put "selected" next to which one should be default, like so: &nbsp;&lt;option value="Hobbit" selected&gt;Hobbit&lt;/option&gt; This means when you create a new character and open the character sheet, those default values will be set properly.
Thanks GG ... I'll try and find some time today to test this on my character sheet.
Working perfectly - thanks for your assistance
1542328038
GiGs
Pro
Sheet Author
API Scripter
You're welcome :)