Advertisement Create a free account

[Script] Easy Experience

1461881858

Edited 1475602526
Scott C.
Forum Champion
Sheet Author
API Scripter
EasyExperience (Gist updated 5/2/16 1611 CST): This is an experience tracker and updater. The script will keep track of party experience gains throughout the session and then apportion them out to the party when you tell it the session is over. It will also alert the table when someone levels up. Thanks to The Aaron for lots of help over the last couple weeks as I've been wading through it. Version 1.04 : Actual fix for the state corruption is put in along with logic that will hopefully automatically clean it up when it happens. Version 1.03: Some users experienced a difficulty with the state that was only fixable by a complete wipe of the state. A new command has been added to the script: !xp reset . This command will wipe all user settings from the state and will restore the default values, and will re-lookup player characters. This should fix this error if you encounter it. Version 1.02: Applying XP now rounds down to the nearest whole number rather than having huge decimals. Version 1.01: Numerous bug fixes from Version 1.0. Also added the ability to set what name the script uses when looking for the experience attribute. Version 1.0: Can now directly add xp to a specific character(s). Can now set what experience progression the script uses. options are Pathfinder: slow, medium, fast, and pfs; and D&D5e. Version 0.0.5: Discovered a problem with !xp session. This has now been fixed. Version 0.0.4: Fixed the error that was being thrown by undefined experience|max values. If the script can't handle your experience attribute for some reason, it should generate an error message in a gm whisper instead of crashing the API. You can now specify how many times to record an entered xp amount. No more having to click the macro 15 times for that big fight where a bunch of mooks were knocked about, now you just enter !xp challenge @{target/selected|token_id} 15 or !xp miscXP 200 15 if it was some sort of challenge that you don't have a npc-xp value for. The script should now generate gm whispers when xp is recorded in Session XP. There is also a global chat message when !xp session is triggered notifying all players of their xp gains in addition to any level up notices they may have received. Version 0.0.2: Fixed an issue where if a character's level was changed from a positive value (1+) to 0, the script would throw a Reference Error and shut down all scripts. The gist in the link is updated. Can't replicate issues with 5e OGL sheet. Please let me know if they are still occuring. Issue with the 5e sheet described by Loren is actually a problem with the code where it incorrectly handles experience|max being 0 or undefined. I will work on getting the script to handle this correctly (setting max to the proper value for the character's current level, but in the meantime the work-a-round is to change the character's current level back and forth to trigger the scripts built in function for handling a level change. Note about a possible TypeError: It is possible for the script to throw a TypeError if there is a PC that has never had any experience added to it. This is because the character sheets do not generate these attributes until they have some value in them. Please make sure to enter a value in the experience field of every PC (even if it is just a zero) to get the character sheet to generate the experience attribute. You only need to do this for PC's (characters with something in the player-name attribute). Version 0.0.1: EDIT: Designed with Pathfinder sheet in mind, known issues with 5e sheet. Easy Experience Script: This script will create a character called ExperienceThresholds that it uses for most of its functionality. If there is already an ExperienceThresholds character present, it will not make one; please make sure that you do not have a self-made ExperienceThresholds character. (highly unlikely I would think ;) ) ExperienceThresholds is created with the following attributes: Session XP: current value is updated whenever a challenge is completed. The max value stores the xp earned in the previous session in case you need it for something else. 2, 3, 4,...: these attributes' current values are the thresholds at which characters level up to this level. The default values are from the Pathfinder medium progression path. If your game uses a different XP progression, simply change the values as needed; the script only looks at these values, it does not change them. ---------------------------------------------------------------------------------------- Use the following chat commands to utilize this script: !xp challenge @{token_id/character_id}: Adds a character's npc-xp attribute value to the Session XP tally in the ExperienceThresholds character. !xp miscXP ###: Adds a manually entered XP value to the Session XP tally in ExperienceThresholds. !xp session: Divides the Session XP by the number of PCs (defined as characters that have a player-name entry), adds that xp to each PC's current experience, and then sets the Session XP max field to the current field before resetting the current field to 0. Will also send a chat message congratulating the character on leveling up if this causes that character's current experience to be above or equal to the experience|max value. When a character's level changes, the script will automatically set the experience|max value to the next level's threshold based on the values in ExperienceThresholds. ---------------------------------------------------------------------------------------- Planned features/fixes: √Fix the incorrect handling of unpopulated experience|max values √Add the ability to enter a number after !xp challenge @{token_id/characterid} to specify how many of the targeted challenge were completed √Add gm whispers on each trigger so that you know the script is doing something Add handling for player specific XP gains Any other requests?
1461887611
Silvyre
Forum Champion
Awesome, just today I was wondering if there was a script like this out there!
1461888861
The Aaron
Forum Champion
API Scripter
Cool!  Nice addition!
1461938665

Edited 1461938758
I love the idea of this, it seems very helpful. Before I ask my question, I just want to say thanks to you, The Aaron, and everyone else who has contributed scripts that makes my games better. I'm not a programmer, so the work you do helps me be a better GM . . . so many thanks! My question: any time I go to divide the XP, it always gives the Congratulations! Level Up! message for every player (assuming there is XP to be divided - when there is none, it gives the correct no XP response). I'm using the 5e OGL sheet. I added a player_name attribute for each character, so XP is getting added to each character sheet correctly. But it somehow seems to not be calculating player level correctly, so always reporting a level up. Any ideas?
1461940227

Edited 1461940312
Scott C.
Forum Champion
Sheet Author
API Scripter
hmmm, I'll have to take a look at that. I should have specified in the original post that this script was designed with the Pathfinder sheet in mind. I'll take a look at the 5e sheet though and see what's messing up/if I just didn't notice it was always doing this.
1461942544

Edited 1461946675
Scott C.
Forum Champion
Sheet Author
API Scripter
Hmmm, ok, well I see a couple problems with using the script with the 5e OGL sheet: As you noted, it doesn't have player-name as an attribute. This one is easy to fix as you noted, but make sure that your attribute is called 'player-name' and not 'player_name'. The script looks for the former, it shouldn't be able to find the second one. The sheet doesn't generate an attribute called level. I can't explain how the script is properly updating the maximum XP when you change a class level unless it has a hidden attribute called level. The Aaron may have something to say on this, and I'd like to figure it out so that I know how it's working so that I can fix it if it stops working this way in the future.  The sheet apparently just hadn't populated the level attribute yet as I hadn't changed the class from being Barbarian. Still not sure why it was working, but I can now confirm that it does work (at least in my test game) with the fully populated attributes. One thing to check would be that your 'level|max' field is updating correctly. I can't get my test game to cause the incorrect leveling, but I just made a minor change to the levelUP function before trying to replicate your issue, and even though I doubt that it was affecting your issue, you never know. Could you potentially make a copy of your live game and invite me to gm it (invite me to a copy if you already have one) so I can see what's going on in your game? The change that I implemented was because, while working on figuring out your problem Loren, I also noticed that I had programmed in a case where the script would crash if someone accidentally set their level to 0. I've now fixed this so that won't happen anymore; don't think it was causing your problem, but who knows.
1461991172
Scott C.
Forum Champion
Sheet Author
API Scripter
Found the cause of Loren's issue, working on a fix
1462117657
Wes
Pro
Sheet Author
If I remember correctly the 5e OGL sheet has a hidden attribute @{level} which is the sum of @{base_level}, @{multiclass1_level},  @{multiclass2_level}, etc...
1462159505
Scott C.
Forum Champion
Sheet Author
API Scripter
Yep, it apparently becomes unhidden at some point, because my test characters started showing it.
1465603031
Scott C.
Forum Champion
Sheet Author
API Scripter
EasyExperience updated. See OP for updated details.
Hmmm... I get an error with the update: TypeError: Cannot read property 'configButton' of undefined TypeError: Cannot read property 'configButton' of undefined     at Object.checkInstall (apiscript.js:8098:32)     at apiscript.js:8755:20     at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:105:34), <anonymous>:65:16)     at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:105:34), <anonymous>:70:8)     at checkForReady (/home/node/d20-api-server/api.js:1013:12)     at /home/node/d20-api-server/api.js:1092:9     at c (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:14:64)     at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560     at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147)     at Kd (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:546)
1465612687

Edited 1465612702
Scott C.
Forum Champion
Sheet Author
API Scripter
Doh, thanks for letting me know SeanOG. I apparently typed in state.PAGENAVIGATOR.configButton instead of state.EASYEXPERIENCE.configButton. I didn't catch it since I was working on my page navigator script in my sandbox game before updating EasyExperience, and so there was a state.PAGENAVIGATOR in the game for things to be defined in. I've replaced all of these calls with the correct ones. It should now work correctly. And has loaded and run for me on a brand spanking new game without any previous API's installed. Sorry for that. The gist on my branch of the Roll20 repository is updated and it is in the pull queue. I did not change the version number.
No worries. I'll give the new version a try to see if I can break it.
Let me make your life even more awesome... SyntaxError: Unexpected token { And I disabled every single script except that one. As soon as it's enabled, crash booma.
1465614762
Scott C.
Forum Champion
Sheet Author
API Scripter
Please. I hate working with the state because it's hard to make sure you don't just have it working because of a previous iteration. On the other hand, it allows awesome things.
LOL! I hear you on that.
1465615933
Scott C.
Forum Champion
Sheet Author
API Scripter
hrmmm, ok, that one sounds like a copy paste error, because I know that would have triggered on mine. gimme a sec
1465616096
Scott C.
Forum Champion
Sheet Author
API Scripter
ok, was a copy paste error on my end. should now be fixed. Not sure how I accidentally deleted that one parentheses while copying, but somehow I managed it.
Yeppers, no error. Now to see if I can break it.
Whoot! Broke it! LOL Okay, I did !xp config, and got the wonderful new buttons. I can switch players from Active to MIA with no problems. If I change the XP progression to 5e, I get: TypeError: Cannot read property 'configButton' of undefined TypeError: Cannot read property 'configButton' of undefined at choice (apiscript.js:7095:109) at configProgression (apiscript.js:7110:9) at _.chain.filterObjs.reduce.map._.chain.filterObjs.reduce.map.HandleInput (apiscript.js:7648:29) at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:105:34), <anonymous>:65:16) at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:105:34), <anonymous>:70:8) at /home/node/d20-api-server/api.js:1197:12 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147) at Kd (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:546) at Id.Mb (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:489) at Ld.Mb (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:94:425) at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:111:400 I love my job...
In fact, if I change it to anything, it breaks it.
1465618897

Edited 1465619590
Not sure what happened with it, but here's what I did to "fix" it. I manually entered !xp-config progression fifth  and it told me (in essence), "Hey dummy... you've already got yourself a wonderfully created character named ExperienceThreshold. Stop being stupid." After that, using the config menu allowed me to do what I needed to do without any errors. If I may make a request (though I know you're busting your butt working on the other problems I've managed to cause), is there a way to make it easier to change the name of the XP field for players? For example, for my character sheet, the field name is xp, not experience. As such, anytime I attempt to end the session for adding XP, it tells me the players don't have any experience attribute. I just need to figure out where I need to make the changes to allow me to us xp instead of experience in this version. I've changed everything I could find, but it still tells me no one has any experience attribute... Edit: Come to find out... even if I manually add an experience attribute field with a number and a max, it still gives me that error. Looooooove it. ;)
1465619344

Edited 1465619579
Scott C.
Forum Champion
Sheet Author
API Scripter
Hmm, I've been trying to get that configButton error to happen, and even in a new game (never had an API loaded) it doesn't happen, so I'm not sure what's happening there. Nvm, there it went; no to find out what's going wrong. As for the experience attribute problem. I'll look into that for the next update. In the meantime, you can simply create an attribute on your player's characters called "experience" and the script will work with it. It doesn't have to be a sheet created attribute, and as long as your sheet isn't creating an attribute with the same name, it should be fine.
I was in the process of manually adding and testing when you replied. :)
1465619760
Scott C.
Forum Champion
Sheet Author
API Scripter
Ok, that type error with the configButton is now fixed. had one PAGENAVIGATOR that didn't get replaced last time somehow.
Oh, and line 577 says: +'Page Navigator v'+version+'<b> Options</b>' It only matters for the menu, obviously, but I wanted to let you know.
1465619905
Scott C.
Forum Champion
Sheet Author
API Scripter
ah, great. Also, if you wanted to adjust what experience attribute the script works with, change 'experience' on lines 388 and 499 to whatever your sheet's experience attribute is.
Awesome! We caught that last bugger then. Now, I just need to get this experience part to work. Even adding an attribute manually, I am getting the error. I feel like I'm monopolizing your time. Hehe.
1465620069
Scott C.
Forum Champion
Sheet Author
API Scripter
Yeah, thanks. That's what I get for reusing sendChats instead of retyping the formatting, That's been corrected.
1465620099
Scott C.
Forum Champion
Sheet Author
API Scripter
what error are you getting?
Thanks for all of your work on this! I'm loving how this is shaping up. I'm testing the most recent version (the config menu is sweet!), but am getting the same error SeanOG mentions: Error MSG: CharacterPerrin Turnwheel does not have an experience attribute, please set that character's experience to some value (even if it is 0). No experience was awarded to any character. I'm using the OGL sheet, and my characters do have a field called experience.
Oddly enough, I changed those to  name: 'xp',  and I still got the error. I then reverted back to the original code and manually added experience as an attribute, put in the amount of XP a character is at, and still received the error. I'm going to refresh the page and API sandbox to see if it clears anything out.
There's the error. I'll go in and manually edit the code to add the space between Character and Marcus, but it definitely gives the error even though the attribute is there.
1465622406

Edited 1465622580
Scott C.
Forum Champion
Sheet Author
API Scripter
Ok, apparently I had somehow stored the info in the state correctly back at the start of working on this overhaul, but the finished product no longer collected the correct values (and for new characters or games it wouldn't work). I believe I've fixed it, but let's see what you guys can do to break it again. Just to make sure everything gets reset, use the "update" button in config before trying it, although I don't actually think that is necessary. Sean, there's going to be some more places to replace 'experience' with 'xp' for you, but I'll worry about that once I'm sure it's working.
LOL -- no worries Scott. I appreciate all the work you're doing on it.
Good news: no more attribute error. Bad news: TypeError: xp.set is not a function TypeError: xp.set is not a function at apiscript.js:8525:20 at Function._.each._.forEach (/home/node/d20-api-server/node_modules/underscore/underscore.js:153:9) at _.chain.filterObjs.reduce.map._.chain.filterObjs.reduce.map.applyXP (apiscript.js:8511:15) at _.chain.filterObjs.reduce.map._.chain.filterObjs.reduce.map.HandleInput (apiscript.js:8739:29) at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:105:34), <anonymous>:65:16) at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:105:34), <anonymous>:70:8) at /home/node/d20-api-server/api.js:1197:12 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147) at Kd (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:546) I'm looking through it now to see if there is something I choked on.
I think I'm getting the same error with the edited code: TypeError: xp.set is not a function TypeError: xp.set is not a function at apiscript.js:17998:20 at Function._.each._.forEach (/home/node/d20-api-server/node_modules/underscore/underscore.js:153:9) at _.chain.filterObjs.reduce.map._.chain.filterObjs.reduce.map.applyXP (apiscript.js:17984:15) at _.chain.filterObjs.reduce.map._.chain.filterObjs.reduce.map.HandleInput (apiscript.js:18212:29) at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:105:34), <anonymous>:65:16) at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:105:34), <anonymous>:70:8) at /home/node/d20-api-server/api.js:1197:12 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147) at Kd (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:546)
1465624462

Edited 1465625569
Oh, and to make it easier on me, after line 40: PCs, I added: XPField = 'xp', Then, I changed every instance of name: 'experience', to: name: XPField, It works like that fine with: !xp challenge @{target|target 1|xp} 1 @{target|target 2|character_id} Once the other part is working perfectly, I'll test it like that.
I think I may have figured it out... At line 479, change xp.set('current', parseInt(xp[0].get('current')) + (sessionXP/numPCs)); to xp[0].set('current', parseInt(xp[0].get('current')) + (sessionXP/numPCs)); I'll test it some more, but that seemed to work.
Thanks SeanOG! That seems to have worked for me as well!
1465658169
Scott C.
Forum Champion
Sheet Author
API Scripter
I apologize for all these errors. I didn't realize how tired I was last night. I've run back through the script and corrected these issues. I've also added the ability to set what the name of your sheet's experience attribute is. Script is now in version 1.01. I'll have the OP updated in a few minutes, but the code is up on my branch of the repository.
No worries! Thanks for developing such a useful script! I appreciate all the effort you put in.
Yeah, no worries. I just have incurable insomnia and had a game today, so I was working on it for the hell of it. :)
Thanks for the changes! One more suggestion, and it's only because I ran into it today when awarding XP: making the calculation for the session be a floor math calculation: Math.floor(award/numChr)) I hated seeing .33333333333335 added to characters. ;)
1465673841
Scott C.
Forum Champion
Sheet Author
API Scripter
ah, that shouldn't be a problem. I had left it that way because I wasn't sure what the behavior should be for handling the excess XP. Does it just evaporate? Should there be a prompt for awarding a bonus xp to characters?
1465679039
Scott C.
Forum Champion
Sheet Author
API Scripter
V1.02 with no more decimals is live.
You know, I don't know what it would do. I always rounded down myself. It may be a ceiling, I can't recall.
1465681312
Scott C.
Forum Champion
Sheet Author
API Scripter
Oh, I went with floor (which rounds down) as that most accurately represents how pathfinder (and I think 5e) treat numbers. But I know some people like to use those extra not easily divisible points as bonus MVP or RP xp. I think you're right though that having the xp be in whole numbers just looks cleaner.
I think the biggest reason I went rounded down was because I my players were trained to have one of their bars be XP when they were entering them manually. The decimal for miles turned the number into a blank bubble. Meh. Anyhow, thanks for the rounding down and the ability to change the attribute to something else! That was greatly appreciated!
1467244758
Scott C.
Forum Champion
Sheet Author
API Scripter
Version 1.03 with new command for resetting the script's options released. Currently waiting on merge day to go live on one-click.