UPDATE 1 SOURCES SCRIPTS: TokenMod This was the first piece of code that I looked at the learn 'API'. It was so large that it managed to touch on a lot of the questions you would typically ask when you first start. The only issue is that it's a large pill to swallow and you can end up with some serious indigestion. Regardless, I learned a ton from this code. From simple things, like how to create and reference objects and variables, to the more complex things graphic referencing and manipulation. MonsterHitDice Event listeners are the crux of this code. Learning how Roll20 deals with changes is paramount to building robust, dynamic scripts. The code was also short enough to be a good learning tool. Concentration and CarryTokens These scripts, along with some others I'll list right after, gave me the idea of an interface to track dynamic combat variables. StatusInfo , CombatTracker , LazyExperience , and DeathTracker Gave me the idea to write my own comprehensive combat script that: 1) associates conditions with temporary, dynamic buffs, 2) automates attacks/actions/spells launched from character sheet rolls, 3) updates target character tokens, and 4) stores data for combat for each token, rather than only updating character sheets - so dropped monsters can be tracked too! LazyCalendar This code gave me the idea to have specific conditions (ex. attack accuracy or spell availability) dependent on dynamic global variables (ex. weather or moon cycle). SpellMaster I could never get this to work but the way it stored its spell data gave me a novel idea for storing and referencing large amounts of functional data. (I will figure you out!!!) Learning Tools: wiki[dot]Roll20 [COMPLAINT] The first thing I realized is that Roll20 uses some bastardized, mutant language for script construction. 'Roll20 API' looks like JavaScript. (And I have to say it in quotes because the way 'API' is used challenges what I thought "API" meant when I learned it in high-school AP Comp Sci. To me an API was a reference tool that a programming language has that explains EVERY possible function, primative, object, etc. and all their inputs and outputs.) It's not - entirely - JavaScript, though. This became painfully apparent when there was no one-stop-shop reference tool for learning how to use API. Every learning step involved: 1) scouring the internet before, 2) returning to a forum post about a tangentially related topic before, 3) analyzing provided 'solution' code to then,4) extrapolate to understand the REASON and CONCEPTS behind that implementation so you can, 5) experiment until you understand a concept. Things have to proceed in that order, otherwise you end up chopping together code and crossing your fingers, praying that it works.The main roadblock is that Roll20 has a suite of functions and features reserved and black-boxed. The 3 weeks it took to study random github code was crushed by the single weekend it took to learn the HTML and CSS needed to make character sheets. [COMPLAINT] So for some unexamined reason, some of the links posted in the forums will link to a resource that has the same information as this link. The critical difference - which drove me crazy - is formatting. I personally think it's easier to digest data when it's easy to follow so having a strict formatting guideline means the world to me. ECMA International This was an invaluable resource that I stumbled across while I was flummoxed by my failed searching through Roll20 forums. Helped to clarify object and primitive types that were being used in other scripts and expected by Roll20 functions. w3schools.com This was the sole source I used to learn HTML and CSS this past weekend. "I'm not a fluent speaker but I can understand conversations." Graphics: Graphics are literally the only thing I knew how to do coming in. I can't make much from scratch because I only have a mouse, but I can edit the hell out of something! I primarily use GIMP and only recently got PS so I could automate edits without having to learn Script-Fu (a language GIMP uses for their automation). I have zero qualms about stripping anything I find appealing - copyright or no. (Which is why I'll have to curate before I can ever sell tokens or icons.) google Duh! pinterest Artistic Duh! This is my first stop for image sources. Type "fantasy" + whatever you want deviant art Underground Duh! This was the resource I most-heavily used when I first started using GIMP (making maps). They have a ton of items that can spark an idea and a decent amount of brush resources (in a convenient to download format) to get you started. game-icons.net Useful Ah-hah! The source of token markers and a resource you can use to make as many as you want! They are already the pixel dimensions required by Roll20 so you can edit and drop them into your library. TIP: TOKEN MARKER CREATION in GIMP This was literally my process to making a batch of token markers on the fly! They also look like the default game tokens. right-click on the layer that contains the image and add an alpha channel invert image color (Roll20's default tokens are a black png with white borders) make a selection by color --> white delete (now you have a png that you can export, but I personally don't like how this looks with possible image gaps) invert the selection (now you have the remaining black areas selected) make a path from the selection select your preferred brush (for edge texture reasons I add a bit of jitter) stroke a relatively thin white line along the path (this will give a white border that adds some depth to your token). If you want more depth, you can do this step on a separate layer and then add a drop shadow to your black layer. fill in the blanks needed to complete the image Progress SCRIPTS: CombatRoll So I've made a bit of progress with some of my own code. After seeing the way that DeathTracker gave feedback for damaging an enemy (gore effects and colored token tints) I wanted to make a fully automated attack script. There were already some sheet rolls that linked to the weapons (repeating items) on each character sheet. After dragging that to the macro bar as an attack macro, I wanted players to be able to: click attack choose targets watch them bleed/die/dodge/block/etc. have the target tokens' HP updated While working with that in mind, I hit a block: combat buffs and debuffs. How do I track and account for that? I looked at the StatusInfo and CombatTracker scripts and saw some examples of associating token markers with conditions (taking dmg, healing, dying) and updating them actively. After thinking about all that I realized that I wanted to incorporate that but with more variability. The attributes for those scripts were included in the character sheet, where they were stored, updated, and referenced. I could do something similar to LazyExp and make a sheet/handout to store all that data (which I'll probably end up doing to account disposable, dropped tokens; update the character sheets after combat and delete the temp data on the mobs afterwards) but I wanted to look at the character sheets anyway. So I shifted gears after tinkering with the idea for the CombatRoll code (the name CombatTracker was already taken!!) ... combatResults = []; //object array//each index will hold a 'outcome' object - the target token, its id, and the dmg it took
class outcome {
contructor(tar, lethdmg, nonlethdmg, dead, incap){
this.targetToken = tar||undefined;
this.lethalDamageTaken = lethdmg||0; //note: this value cannot exceed remaining target HP//deducted 1st
this.nonlethalDamageTaken = nonlethdmg||0; //note: this value cannot exceed remaining target HP//deducted 2nd
this.isDead = dead||false;
this.isIncap = incap||false;
}
}
class combatRoll {
targetIsDead = false, //type: 'boolean'//is target HP = 0
targetIsIncap = false, //type: 'boolean'//targetHP = 0, but was reduced to 0 by nonlethal damage
//let's a goooooooo rolling
attackRoll, //type: 'number'//calculated//send roll request from API); let's roll 1d20
attackBonus, //type: 'number'//referenced//should already be a value tracked and stored in a character sheet
attackResult, //type: 'number'//calculated//only added to track values from more than one attack roll (exploding 20s)
exploding20, //type: 'boolean'//logic for calculation//if attackRoll == 20, roll the mofo again and add the value to attack result//SRD//Barbarian Conquerors of Kanahu, page 14
//ok...wtf happened
attackThrow, //type: 'number'//referenced//strored in character sheet; attackResult must be greater than or equal to hit
ACHit, //type: 'number'//calculated//if we hit, the AC we can hurt with our attack; attackResult - attackThrow || 0 if it's negative
isHit, //type: 'boolean'//logic for calculation//is the attackResult >= attackThrow
isFumble //type: 'boolean'//logic for calculation//is the attackRoll == 1
targetAC, //type: 'number'//referenced//should already be a value tracked and stored in a character sheet
goodHit, //type: 'boolean'//logic for calculation//if ACHit >= targetAC, we can deal damage; else we missed or hit with no damage (weak as fuuuuuuuck!!!)
isCritical, //type: 'boolean'//logic for calculation//if ACHit >= [targetAC + 10]
isParalyzed, //type: 'boolean'//calculated (check against target saveParalysis)//if attack is critical, target must make save vs paralysis with size modifier
//if goodHit, let's do the deed - don't get ahead of yourself trying to do this step earlier
damageRoll, //type: 'number'//calculated (from weaponDamage)//double the number of die if isCritical
damageBonus, //type: 'number'//referenced//should already be a value tracked and stored in a character sheet
damageResult, //type: 'number'// [damageRoll + damageBonus]
//what are we taking out their HP?? subtract lethalDamage, then if they're still alive subtract nonlethal damage
lethalDamage, //type: 'number'//calculated//a summation of damage//floor for [HP - lethalDamage] is 0
nonlethalDamage; //type: 'number'//calculated//a summation of damage//floor for [HP - lethalDamage] is 0
constructor(attkr,tar){ //both inputs are type: graphic with subtype: token
this.attacker = attkr;
this.target = tar;
this.attackerID = attkr.id;
this.targetID = tar.id;
this.targetHP = tar.bar3_value;
}
///// combatRoll functions ////
checkBreathing(){
this.targetIsDead = (targetHP === 0 && !targetIsIncap);
}
incapacitate(){
if(!targetIsDead){
this.targetIsIncap = true;
}
}
static throwDice(){
checkBreathing();
if(!targetIsDead){
sendChat('CombatRoll', '/r 1d20', function (msg){
this.attackRoll = msg[0];
});
} else {
//target is dead. figure out return for mutilating a dead body like a psychopath
}
}
} ... CHARACTER SHEET: So since I was already using a character sheet, I decided that I would just try to modify what I already had. Since I knew the game system, this also made it a lot easier to learn: I knew the input and output, now to figure out the steps in between. I came up with a TOOON of ideas for interface and feedback! Thankfully, the layout is highly modular so most of this just involves editing the current layout by adding tabs. UPDATE IDEAS: [Status]: this tab would include a mannequin with overlain slots to signify equipped/worn items and free space. This tab would also have dropdown to choose equipped weapons and worn armor/clothing. It will also display active effects such as debuffs from permanent injuries or buffs from worn/time-sensitive effects. [Followers]:a rework on the hirelings page; I'll change the interface to be a repeating list of readonly items. This will become a reference location for the NPCs or players that have successfully been hired. The interactive elements will be the buttons for sheet rolls to [hire] followers or [tame]/[buy] pets and beasts tab. There will also be an alternate tab that will become more interactive for beasts with options to train, etc. [Party]: multi-windowed tab that displays all the NPCS, followers, vehicles, and mounts within the party. There will also be a dynamic display that uses box plots to reflect party formation - which members are in the front, middle, or rear or the pack [Inventory] and [Weapons]: these are already in existence but I'll be attempting to give them a makeover. I'll be adding a dynamic quiver/pouch graphic to the weapons tab & adding several attributes the repeatingitem code for the equipment and items (ownership, value, type, isSilver, isMagic, possession). I'll also be adding an attribute to track total wealth. The ownership and possession variables will allow for items to be given to others, left at home, stashed, etc. with varying effects to the player's total wealth. GRAPHICS: After the idea to update and track combat buffs and debuffs, I made a batch of token markers. I wanted to have unique markers for the types of degree of buff, with an exception for especially large buffs. With the tinkering I did with the character sheet graphic elements, this is the result of those man-hours: for the [Status] tab on the character sheet that will update show active effects and worn items. The image itself will be assembled into a table from image slices so that an overlain png can display changes in status. Making it overlain will also allow me to add a tooltip that will let people know what is wrong when they hover over it. This will actually be in the back of that area. In key regions, there will be small image fields (I can't think of a more descriptive name) that will reflect will whether or not an item is being worn/carried/held/equipped. (from pinterest ) for the ability to track combat buffs and debuffs I made a bunch of token markers that will be linked to specific buffs and debuffs and their effects on the player stats. Here are some of the tokens I made - these are for missile damage! Well....that's it for now!