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] DiscreteWhisper -- multi-recipient whispers with asides and buttons

1604608090

Edited 1644849468
timmaugh
Pro
API Scripter
DiscreteWhisper Current Version (and link): 1.1.0   and in the Roll20 One-Click install Concept Abstract : DiscreteWhisper is a way to send a single whispered message to multiple recipients while simultaneously giving groups of recipients more or less of that message. Buttons (referencing api script command lines, character abilities, or macros) can also be included, and can also be limited to some/all of the recipients. Example Use Case : Larry, Moe, and Curly failed to detect an illusion trap and now need to make a perception check. Larry was the most affected by the trap's illusion spell. The GM wants to send a whispered message to all while giving a slightly altered version to Larry. Moe and Curly should receive the message: "There are five jewels on the table. You find it hard to focus on them." At the same time, Larry should receive the message: "There are five jewels on the table. A small child holds a sixth jewel near the far wall." The player who is playing Larry should not know that s/he has received a different message from the other characters. The GM would enter: !w --Larry|Curly|Moe --There are five jewels on the table. {{aside|Moe|Curly}}You find it hard to focus on them.{{aside|Larry}}A small child holds a sixth jewel near the far wall. Command Line and Syntax The following represent the designations of the various parts of a DiscreteWhisper command line: !apihandle --characters --message --title (optional) --buttons (optional, requires a title argument) API Handle Out of the box, the DiscreteWhisper script will answer to any of the following handles: !w !discrete !discretewhisper I say "out of the box" because there is a way to alter what handles the script will listen for (see the section, below, "Altering the API Handles"). Characters Include a pipe-separated list of Character identifiers (name, ID, or token-id representing a character) that will comprise the list of characters receiving a whispered message. This list represents the characters receiving anything designated to go to "all" characters. The designation "GM" (any case) can be used to include the GM in the list of recipients. --Larry|Moe|Curly Any character can be pre-pended with an {{as}} to designate that you wish to whisper as that character. Designating the character as the source of the whisper in this fashion overrides the inclusion of the character as a recipient, so if for some reason you wish to both whisper AS a character and you wish to have that character also receive a whisper, you must include the character twice in the list: once prepended with {{as}} , and once straight. --{{as}}Larry|Moe|Curly ...would have Moe and Curly receiving a message from Larry. If no {{as}} designation is made, the script uses the chat speaker who entered the API command. Message The message of a whisper can be just straight text. It begins defaulted to be a whisper to all recipients listed in the Characters argument. Asides to characters can be handled with either of the following text patterns inserted into your message: {{aside}} {{Aside}} The difference being that the lowercase 'a' version does not announce that the character is receiving an aside, while the uppercase 'A' version does announce it. Each of these formations also take list of pipe-separated characters (much like the Characters argument) of those characters who should receive this aside. Separate the list of characters from the 'aside' by use of a pipe: {{aside|Character 1 |Character 2 |...Character n }} To return from an aside to all characters again receiving the next portion of the message, use the pattern: {{all}} 'All' does not take a list of characters. Title If you wish to have a flat-text whisper (much like if you typed '/w gm This is the message' into the chat box), then skip this argument and the next. By including a Title argument, you instruct the script to use a "message box" formatted output instead of the flat-text output. For instance, this line: !w --{{as}}GM|Prism --You see something shiny on the floor. --PERCEPTION Produces the following output for the character named Prism: Buttons If you have included a Title (and are therefore using the templated "message box" style output), you can also feed an API button into the output. These can be in the form of: Label|!apiscript (with any arguments as designated/required by the command line) Label|Character|Ability Label|Macro Like the Message argument, buttons can be individually granted by use of the {{aside}} , {{Aside}} , or {{all}} markers. In fact, to separate multiple buttons to be received by all characters, you MUST separate each by use of {{all}} , otherwise DiscreteWhisper will not know where to separate the buttons. Note : Yes, this does produce a problem for including script command lines that, themselves, make use of the {{all}} syntax. I am not aware of any (except DiscreteWhisper), though nesting a call to a DiscreteWhisper in the Button argument of another DiscreteWhisper call could trigger this issue. In those sort of cases, consider putting the nested language into a macro or ability and referencing that location as the source for the button, instead. Here is an example of including a button: !w --{{as}}GM|Prism --You see something shiny on the floor. Do you pick it up? --PERCEPTION --Yes|!w --GM --Yes, I pick it up. Prism receives: Clicking the button would send a flat-text whisper to the GM: Yes, I pick it up. Reporting Whispers and Undeliverable Messages Because API generated whispers do not show in the sender's chat log, and because the output of the given messages are parsed together and potentially numerous, when DiscreteWhisper finishes sending all of the requested messages, it reports back to the sender with a "Delivered Whispers" digest. For the example immediately above, the sender would receive: Similarly, if the API cannot find a character listed in either the Character argument or an aside, DiscreteWhisper will deliver a second report announcing this to the sender: If there is no specific message included for the character, the character was included in the Characters argument and received none of the whisper intended for "all" characters. If the un-findable character had been included in an aside, the aside text would have been included to alert you what portion of the message went undelivered. Altering the API Handles This script includes a beta method to remap the API handles to which this script responds. As mentioned above, a GM might want to reserve this sort of whispering to themselves. Another need for this is that the DiscreteWhisper script parks itself on what might be a very desirable API handle: 'w'. Should there be another script that uses this handle and the developer of that script is unavailable or unwilling to change it, you can instruct DiscreteWhisper to no longer listen to API calls that begin with '!w'. There are three command structures to handle this: addapi remapi getapi Invoke these utilizing an EXISTING API handle for the script, followed by a # , followed by the above command. For addapi or remapi , you must also include a pipe, followed by the API handle you wish to affect (or pipe-separated list of handles). !w#addapi|CarelessWhisper ...would add the text 'CarelessWhisper' to the set of API handles this script would answer. !CarelessWhisper#remapi|CarelessWhisper ...would remove the same API handle. Note, at that point, the above line would no longer be caught by this script (it wouldn't listen for the CarelessWhisper handle). Do not worry about removing your access to the script by virtue of disallowing all API handles. You cannot remove the API handle for the overall project: DiscreteWhisper. This is the script-level object that occupies that address in the javascript namespace -- meaning the only way to have a collision on this API handle is if someone else ALSO named a script/object "DiscreteWhisper" or manually told their script to catch that API handle. In either case, you've got larger issues, and I need to have a conversation with the other developer. =D So, to say it again, you will ALWAYS have access to the script at the API handle of "DiscreteWhisper", even if you remove all other API handles available to you. The last API Handle command is the getapi, which will give you a simple read-out of the handles to which this script will listen. Change Log: Version 1.1.0 ( details ) - Fix bad buttons breaking sandbox; adds attribute buttons; adds local buttons  Version 1.0 - Initial Release
1604615115
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Oooh. Must experiment!
1604631457
timmaugh
Pro
API Scripter
Me, when someone is going to play with something I've made:
You must have designed this while at McDonalds… Cuz I’m Love’n It…. Bravo. Thief & Thief/MU casing a gem case in a Jewelry store…
1604678485
Andreas J.
Forum Champion
Sheet Author
Translator
Very nice.
1604683278
timmaugh
Pro
API Scripter
BilBo 2 said: You must have designed this while at McDonalds… Cuz I’m Love’n It…. Haha... you had me going there for a minute! Seriously, thanks, all. Let me know if you run into problems or could use other features.
1605219117
timmaugh
Pro
API Scripter
Version 1.1.0 November 12, 2020 Fixes This update fixes malformed buttons that had previously broken the sandbox (for instance, if you forgot the label portion of the button syntax). Those buttons simply never make it to the whispered output, now. Features Attribute Buttons - You can now use an attribute as the source for a button (handy if it has a roll formula in it). To do that, prepend the attribute name with @: label|character| @ attribute_name Local Buttons - You can now use the 'local' keyword in place of a character to have the button rendered using the recipient character's sheet. This formation would look like: label| local |ability_name label| local |@attribute_name Example: The character sheet in use in the game has a designated "Perception" attribute (called 'perception_roll_formula'). When the party stumbles from a rainy night into a dimly lit tavern, the GM wants to ask 2 of the characters, Heron and Prism, for perception rolls. The GM sends this message: !w --{{as}}GM|Heron|Prism --You think you see... something. --ROLL PERCEPTION --Perception|local|@perception_roll_formula Both of those characters will receive a message like the below: The button will refer to that individual character's Perception attribute. Example 2 : In a game where the character sheet didn't have a pre-built Perception attribute, (like WoD), the GM made sure that every character had a "Perception" ability, instead. In that case, the syntax is nearly the same, using the ability 'Perception' (and without the '@' of an attribute: !w --{{as}}GM|Heron|Prism --You think you see... something. --ROLL PERCEPTION --Perception|local|Perception The result will appear the same as in the image, above, to the receiving characters, except that the button will trigger the Perception ability for that character. Button Formations (Recap) As of this update, the following button formations are allowed (syntax): {{all / aside}}label|!script <<args>> {{all / aside}}label|local|ability {{all / aside}}label|local|@attribute {{all / aside}}label|character|ability {{all / aside}}label|character|@attribute {{all / aside}}label|macro
Oh this is cool thanks for poiting me here from my thread :))  - can you send whispers based on character perception or some kind of hidden check rolls? 
1607014029
timmaugh
Pro
API Scripter
This script isn't currently set up to handle conditionals or cases, so you might have to fudge/manual-ize that portion for now. I could see about working something like that in for the next update... something like entering an aside that is keyed to a local character roll and comparison check (rolling over X, etc.). The character is presented a button to trigger the roll, which is fed back to the script to process against the stored aside. If the roll passes the comparison check, then the extra information is sent. Probably would need the opportunity to provide "missed roll" text, too... Is that the kind of thing you were looking for?
Yeah something like that - or that it will whisper just to characters that they notice something if they have passive perception X+ etc.. 
1607026670
timmaugh
Pro
API Scripter
Almost like you would have a trigger zone on the map, and if the token crossed into that space, activate the effect. The effect could be "If XXXX attribute [passes some comparison], reveal this information...", or it could request a roll... 1) send a message requesting a particular roll (supplying the button for them) 2) their roll would feed back to the script  3) script evaluates what level of info to reveal It would take a bit of setup to configure the triggers, but you wouldn't have to use the script that way. You could still use it as you would today. Let me think on it...
I was trying to incorporate the API call in Power Cards...couldn't get it to work. Didn't try that hard though.. a few expirements... they all failed.. Cant remember the error generated. Or if Sandbox crashed... Cant even find the macro that I was testing it in... my bad I know that PC does have some conflicts with other API's... so gave up on the expirement... Wasn't that important anyway.. did it the old fashioned way... chat buttons... But this could be an improvement... will await your agmentation.... :)
1607058024

Edited 1607058041
timmaugh said: Almost like you would have a trigger zone on the map, and if the token crossed into that space, activate the effect. The effect could be "If XXXX attribute [passes some comparison], reveal this information...", or it could request a roll... 1) send a message requesting a particular roll (supplying the button for them) 2) their roll would feed back to the script  3) script evaluates what level of info to reveal It would take a bit of setup to configure the triggers, but you wouldn't have to use the script that way. You could still use it as you would today. Let me think on it... Well map trigger - area/token would be of course cool - but having it manually triggered (from info token for example) would be viable too
1607058302

Edited 1607058331
Pat
Pro
API Scripter
Maybe check out the It's A Trap code to see if that might be able to trigger the api? Not sure if it can, but that has a lot of the detection that you might be looking for, as well as perception-based triggers.
Can you do two buttons? :) (if yes - cant figure out how)
1608298118
timmaugh
Pro
API Scripter
You mean like this? ;-) Remember, each button has to be in a recognized form: {{all / aside}}label|!script <<args>> {{all / aside}}label|local|ability {{all / aside}}label|local|@attribute {{all / aside}}label|character|ability {{all / aside}}label|character|@attribute {{all / aside}}label|macro The trick is to use the {{all}} keyword to differentiate the buttons from each other (otherwise the parser doesn't know where to stop giving text to the former button and start looking for a new button). The very first button defaults to be "all" unless you tell it differently. To get the above effect, I used this command line (line breaks added for readability -- remove these): !w --Heir --Do you click on the first button? Or do you click on the second? Can you even resist? How diabolical of me... --YOU FACE A CHOICE --First|!w --GM --The first button... definitely the first.{{all}}Second|!w --GM --The second... I couldn't... I couldn't resist. Those buttons are set up to whisper back to the GM the results of the roll... which is cool but it does get to the one collision of API lines and the script parsing... namely that if the DiscreteWhisper command line you feed to a button you want to send to a player ALREADY INCLUDES the {{all}}  keyword (even as a differentiator for part of the return chat message), that will bet parsed on the first go and DiscreteWhisper will think it has found another button. (The above embedded DiscreteWhisper lines don't include these -- they only whisper to the GM -- so they will be just fine.) I'll add to that the list of items to improve for v2!
This isn't working when loaded from the script library. I get the following error" No such file or directory @ rb_sysopen - /home/symbly/www/d20-app/apiscripts/DiscreteWhisper/1.1.0/DiscreteWhisper.js
1613345347
timmaugh
Pro
API Scripter
Thanks for letting me know. I just tried both the 1-click version and the version on my repo (linked in the original post of this thread). The version in my repo works... but the 1-click is not. I'm not seeing the same error you describe, but something is clearly wrong with that version. I will resubmit this week to see if we can get it corrected.
1613588213

Edited 1644851056
timmaugh
Pro
API Scripter
I think I have corrected the problem (a mis-match between the script.JSON and the directory structure of the source files), and have resubmitted this for the 1-click. It should be corrected next week. Thread 2 This thread has been closed due to inactivity, but I opened another thread beginning with the 1.1.1 Update to Discrete Whisper. Continue reading on that thread!