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

Simple script to get started

1706746619

Edited 1706746694
Erickson
KS Backer
Hey all, I've been a user of mods forever, write macros all the time, and I've got a fair amount of experience with JavaScript (though its been a few years), but I've never actually written a mod before. I've got a very simple function I need to perform and it seemed like a great task to teach myself how to code for the API. I've read over the documentation, but I'm finding it a little lacking in examples, especially related to reading and writing to the character sheet. So that said, here's what I'm trying to figure out how to do: I have a specific character sheet with a value in other_resource that I want to monitor, and onChange, I want to run a simple bit of conditional logic, then adjust the value of a handful of attributes based on that value. IE, something like: on("change:attribute:other_resource", function() {   var pc = getCharacter("My PC");     switch (true) {     case  pc.attributes.other_resource < 5:       pc.attributes.dexterity = 16;       pc.attributes.constitution = 14;       pc.attributes.wisdom = 15;       pc.attributes.charisma = 9;       break;     case pc.attributes.other_resource > 20:       pc.attributes.dexterity = 15;       pc.attributes.constitution = 15;       pc.attributes.wisdom = 16;       pc.attributes.charisma = 9;       break;     default:       pc.attributes.dexterity = 17;       pc.attributes.constitution = 14;       pc.attributes.wisdom = 16;       pc.attributes.charisma = 10;   } } But I don't even honestly know where to begin when it comes to putting that into code that the API sandbox will understand. Can anyone point me in the right direction? Or send me toward some examples or more robust tutorials than are in the documentation that I could take a look at? I've been putting off learning the API forever, and this seems like about the simplest possible task I could think of to get started with. Thanks!
1706748266
The Aaron
Roll20 Production Team
API Scripter
Here are the links I like to give people starting out with the API: <a href="https://app.roll20.net/forum/post/6605115/namespaces-novice-seeks-help-exploring-the-revealing-module-pattern" rel="nofollow">https://app.roll20.net/forum/post/6605115/namespaces-novice-seeks-help-exploring-the-revealing-module-pattern</a> <a href="https://app.roll20.net/forum/post/6584105/creating-an-object-that-holds-specific-character-dot-id-and-character-name/?pagenum=1" rel="nofollow">https://app.roll20.net/forum/post/6584105/creating-an-object-that-holds-specific-character-dot-id-and-character-name/?pagenum=1</a> <a href="https://app.roll20.net/forum/post/6237754/slug%7D" rel="nofollow">https://app.roll20.net/forum/post/6237754/slug%7D</a> Here's how the above would likely look for the API: // when an attribute changes, call this function with the changed attribute (obj) and it's original state (prev) on("change:attribute", (obj,prev) =&gt; { // is this the attribute named "other_resource" ? if("other_resource" === obj.get('name')) { // grab the associated character let character = getObj('character',obj.get('character_id')); // did we get a valid character and is it named "My PC" if(character &amp;&amp; "My PC" ===character.get('name')){ // load each of the attributes you want to change. let dex = findObjs({name:"dexterity", character_id: character.id})[0]; let con = findObjs({name:"constitition", character_id: character.id})[0]; let wis = findObjs({name:"wisdom", character_id: character.id})[0]; let chr = findObjs({name:"charisma", character_id: character.id})[0]; if(! (dex &amp;&amp; con &amp;&amp; wis &amp;&amp; chr) ){ log(`ERROR: missing dependant attribute`); return; } // get the current value of other_resource as a floating point number let v = parseFloat(obj.get('current')); // set them based on value of v if( v &lt; 5 ) { dex.set('current',16); con.set('current',14); wis.set('current',15); chr.set('current',9); } else if (v &gt; 20) { dex.set('current',15); con.set('current',15); wis.set('current',16); chr.set('current',9); } else { dex.set('current',17); con.set('current',14); wis.set('current',16); chr.set('current',10); } } } }); Once you've read those threads, that will probably make sense, but definitely ask questions!
1706768815

Edited 1706769013
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Aaron is the one to trust on scripts. The only thing I'll add is since you mention other_resource , I'm guessing you are doing this with the 5e by Roll20 sheet. If that is true, the attributes you are setting are involved in sheetworker calculations behind the scene. To get the sheetworkers to fire, you'll want to use either attr.setWithWorker() &nbsp;or the setAttrs() &nbsp;function. I'd recommend the setAttrs() &nbsp;function as it's a little simpler to use, but I may be biased because it uses a similar syntax to the sheet function of the same name. Adapting Aaron's code to use setAttrs , it'd look like this: // when an attribute changes, call this function with the changed attribute (obj) and it's original state (prev) on("change:attribute", (obj,prev) =&gt; { // is this the attribute named "other_resource" ? if("other_resource" === obj.get('name')) { // grab the associated character let character = getObj('character',obj.get('character_id')); // did we get a valid character and is it named "My PC" if(character &amp;&amp; "My PC" ===character.get('name')){ // load each of the attributes you want to change. let dex = findObjs({name:"dexterity", character_id: character.id})[0]; let con = findObjs({name:"constitition", character_id: character.id})[0]; let wis = findObjs({name:"wisdom", character_id: character.id})[0]; let chr = findObjs({name:"charisma", character_id: character.id})[0]; if(! (dex &amp;&amp; con &amp;&amp; wis &amp;&amp; chr) ){ log(`ERROR: missing dependant attribute`); return; } // object to store our changes in. They'll be applied all at once at the end const setObj = {}; // get the current value of other_resource as a floating point number let v = parseFloat(obj.get('current')); // set them based on value of v if( v &lt; 5 ) { setObj.dexterity = 16; setObj.constitition = 14; setObj.wisdom = 15; setObj.charisma = 9; } else if (v &gt; 20) { setObj.dexterity = 15; setObj.constitition = 15; setObj.wisdom = 16; setObj.charisma = 9; } else { setObj.dexterity = 17; setObj.constitition = 14; setObj.wisdom = 16; setObj.charisma = 10; } // Apply changes. Using this function provided by Roll20 will ensure that the sheet's javascript listeners see the change and update the dependent attributes (e.g. dexterity_mod). setAttrs(character.id,setObj); } } });
Incredibly useful! The code alone already explains 90% of what I was struggling to understand, but the links are a great reference to help me get over the "just getting started" hump and keep learning. Thanks so much!
1707062787
The Aaron
Roll20 Production Team
API Scripter
Great catch Scott! Glad that helps, Erickson, definitely let us know if you run into any issues or just want to discuss some API things.&nbsp;