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

[Script Release] MagicalSurges

1531884446

Edited 1532150915
Hi all, recently compiled a small script to make sure a wild magic sorcerer in my 5e game didn't forget to roll for their surges. Any ideas or feedback would be appreciated! As of right now I only know it works with the 5eOGL character sheet, others may be something to look at in the future if there is enough interest. Github: <a href="https://github.com/nmrcarroll/MagicalSurges" rel="nofollow">https://github.com/nmrcarroll/MagicalSurges</a> Usage This script should automatically roll a d20 after any spell is cast and if needed generate a surge. However there are still commands for manually generating a surge if needed. !MagicalSurge - Manually roll on the surge table and output to chat. !MagicalSurge gm - Manually roll on the surge table and send only to GM. !MagicalSurge add charactername = Adds charactername to the list of monitored characters to automatically roll wild magic when spells are cast. GM only. !MagicalSurge remove charactername = Removes charactername from the list of monitored characters. GM only. Setup Install the script manually for your game as normal. Once the script is installed it will create a rollable table for you named "MagicalSurges" fill that table up with all the possible magic surges you want to be able to roll from. An example sheet has been provided to use in conjunction with The Aarons TableExport script to allow you to quickly fill in the surge table with your own custom one. Once that is done if you want to enable automatic rolling you will need to add players to be monitored with the command "!MagicalSurge add charactername" command.
1531893730
The Aaron
Pro
API Scripter
Cute! &nbsp;We just started a new campaign with a wild mage in the group. This might come in handy!
1531924161
The Aaron
Pro
API Scripter
I do have a few suggestions. Since all API scripts are concatenated, each script should be "namespaced" so as not to pollute the global scope.&nbsp; Right now, if there is another script that defines a variable in the global scope named CHARACTER, the API will halt.&nbsp; There are a few ways of doing that, either create a closure with an IIFE (Likely, the Revealing Module Pattern), or wrap the whole thing in an on('ready',...) event handler.&nbsp; Since you're not exposing a public interface, the on('ready',...) event handler is probably the way to go, and is very easy. on('ready', () =&gt; { &nbsp;&nbsp;&nbsp;&nbsp;/* YOUR CODE HERE */ }); Doing this is a good idea in general, as the API isn't in a usable state until that event occurs.&nbsp; If you later add event handlers for other things, you would start to get a bunch of strange behavior as create events are sent for every object in the game as the game loads up.&nbsp; Delaying execution until 'ready' has been sent lets you avoid that. The other suggestion I have is to change things so that users don't need to edit your script to use it.&nbsp; Most people aren't overly technical, so editing code is daunting.&nbsp; It also gets you in prime territory for releasing your script as a 1-click, where editing isn't possible. I'd suggest having your script check for a RollableTable named "MagicalSurges", and then pull in all the TableItems for that table as your surges.&nbsp; If you store them in an Array, you can index with a randomInteger() based on it's length.&nbsp; Then users can just modify the table.&nbsp; Ideally, you would then catch the 'add:rollitem', 'change:rollitem', and 'destroy:rollitem' events for their changes and rebuild your internal table, but you could just reload it at restart and tell them to restart the API.&nbsp; You would probably ignore the weight, but you could take it into account with a more complex rolling system. For the list of Sorcerer Characters, I'd recommend storing that in the state and providing a command to add or remove a character, probably by running it on a token that represents them.&nbsp; Just be sure to follow the guidelines to playing nice with the shared state object here:&nbsp; <a href="https://wiki.roll20.net/API:Objects#state" rel="nofollow">https://wiki.roll20.net/API:Objects#state</a> Anyway, that's it for now.&nbsp; If any of that doesn't make sense, let me know.&nbsp; Cheers!
1531925911
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
The Aaron said: For the list of Sorcerer Characters, I'd recommend storing that in the state and providing a command to add or remove a character, probably by running it on a token that represents them.&nbsp; Just be sure to follow the guidelines to playing nice with the shared state object here:&nbsp; <a href="https://wiki.roll20.net/API:Objects#state" rel="nofollow">https://wiki.roll20.net/API:Objects#state</a> This also sounds like a perfect use case for your APISelection script Aaron.
1531926537
The Aaron
Pro
API Scripter
Very possibly. =D&nbsp; I wasn't gonna bring it up JUST yet, but it would work there.
1531933372
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
This whole idea sounds like it could be expanded into a table manager script, one that not only gives random results, but can pull a result from a title or position on the table, giving people the ability to do tables that shift ("roll on Table X at +10") or (insert the 4th value from Table X here")
The Aaron said: I do have a few suggestions. The other suggestion I have is to change things so that users don't need to edit your script to use it.&nbsp; Most people aren't overly technical, so editing code is daunting.&nbsp; It also gets you in prime territory for releasing your script as a 1-click, where editing isn't possible. I'd suggest having your script check for a RollableTable named "MagicalSurges", and then pull in all the TableItems for that table as your surges.&nbsp; For the list of Sorcerer Characters, I'd recommend storing that in the state and providing a command to add or remove a character Thanks for the feedback Aaron, I have already implemented the on('ready') wrap you suggested to play nice with other scripts. The other two suggestions were definitely something on my mind to implement for the future but as originally the script was just for my campaign I went the easy route. Will be starting right away to make it as user friendly as reasonably possible. keithcurtis said: This whole idea sounds like it could be expanded into a table manager script, one that not only gives random results, but can pull a result from a title or position on the table, giving people the ability to do tables that shift ("roll on Table X at +10") or (insert the 4th value from Table X here") Sounds interesting, but I think it might be more appropriate to be a separate script of it's own. The main purpose behind this script is to have wild surges and the 1d20 rolled automatically for a player after each spell. It sounds more like it could support this script with the other proposed changes though. I'd be curious to hear more use cases for something like that if you had any, personally we don't use tables very often in my games so I'm a bit at a loss here.
1531951806
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Nic said: I'd be curious to hear more use cases for something like that if you had any, personally we don't use tables very often in my games so I'm a bit at a loss here. There was a request recently where someone wanted to handle a table somewhat in the manner I described, referencing specific items from the table or specific ranges rather than a strict random generation. I'll see if I can dig it up, but I don't want to dilute your thread.
Updated to version 0.0.3 A nearly complete rewrite has been done to account for suggested changes from Aaron. Can now control all functions from within your own game through&nbsp; the use of api commands and a rollable table to store the possible wild magic surges that you want to use. Documentation provided in original post.
1532187691
The Aaron
Pro
API Scripter
Nice!&nbsp; That's looking really good!&nbsp; Next stop, the 1-click install! I do see one minor, potential bug.&nbsp; If a player has a character with more than one space in their name: Bob the SLAYER You won't be able to find them.&nbsp; Similarly, if they change their name, they will loose their registration. You can fix both of those by switching to storing character ids.&nbsp; Users of the script can get the character id from a token with: @{selected|character_id} or you can use a less rigid matching mechanism to find the character and use it's ID.&nbsp; Or both! This is how I'd probably do it:&nbsp; <a href="https://gist.github.com/shdwjk/193ec6a479f296c5ee2102638b7a3016" rel="nofollow">https://gist.github.com/shdwjk/193ec6a479f296c5ee2102638b7a3016</a> (Annoying that the Roll Template doesn't include the character id!!)
The Aaron said: This is how I'd probably do it:&nbsp; <a href="https://gist.github.com/shdwjk/193ec6a479f296c5ee2102638b7a3016" rel="nofollow">https://gist.github.com/shdwjk/193ec6a479f296c5ee2102638b7a3016</a> (Annoying that the Roll Template doesn't include the character id!!) Wow at first this was all way over my head and took me a bit to figure out what was going on. The -- for character name instead of ID had me pulling my hair out for a bit. If you don't mind, I'd love to use your code in the script. If you're alright with that I think I will probably go and split it out from handleInput as the function is getting a bit large at this point though. Also I think you still run into the same space issues with this version if the multi space occurs after the first two words in the name. Correct me if I'm wrong here as I'm still new to both JS and regular expressions, but I think const keyFormat = (n) =&gt; (n||'').toLowerCase().replace(/\s+/,''); Should instead be: const keyFormat = (n) =&gt; (n||'').toLowerCase().replace(/\s+/g,'');
1532295170

Edited 1532295386
The Aaron
Pro
API Scripter
Ah, that's a great catch on the regexp!&nbsp; Wonder if the script I copied that from is similarly broken... (yup, fixed it in the 9/12 places it was missing, thanks for that!) Yup, use that example however you like. =D
&nbsp;i just created a roll table with wildmagic surges and cal to it when surge is needed.