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

Any Way to Turn Drop Down into a Usable Variable?

1693963598
Essen
Pro
Marketplace Creator
I want to make a macro where the player picks a dice, d4, d6, etc, then it rolls a bunch of that dice, one at a time. So it would need to take the drop-down result and use it over and over. Any way to do that?
1693973952

Edited 1694051010
timmaugh
Pro
API Scripter
Every time you reference the same query dropdown, it will return the same value: You chose ?{Choose a color|red|blue|green|purple}. And later I can tell you, you chose ?{Choose a color} You don't have to include any of the options except for the first time the query is in the command line.  Or, an example closer to your situation: &{template:default}{{name=Proof of Concept}}{{Dice=You chose ?{Dice|d4|d6|d8|d10|d12|d20} }}{{Roll 1=[[?{Dice}]]}} {{Roll 2=[[?{Dice}]]}} {{Roll 3=[[?{Dice}]]}} Now, if you want to use one choice to drive a bunch of different meanings, or if you want to have an arbitrary number of rolls in your output, you can do that with metascripts. Multiple Meanings Use Muler to build multiple output tables (or mules... basically abilities on a mule character). I'll put them on a character called PublicTables: NAME: DragonAttackDice CONTENT: Acid=2d20 Fire=1d12+3 NAME: DragonAC CONTENT: Acid=13 Fire=11 Now, when  you pick what kind of dragon you want, you can get the attack dice and AC in one message: !You chose ?{Dragon type|Acid|Fire}, which has an attack of get.PublicTables.DragonAttackDice.?{Dragon type}/get, and an AC of get.PublicTables.DragonAC.?{Dragon type}/get. {&simple} You can roll the attack in an inline roll by slowing down the roll by one deferral (to give Muler time to work): !You chose ?{Dragon type|Acid|Fire}, which attacks for  [\][\] get.PublicTables.DragonAttackDice.?{Dragon type}/get\]\] points.{&simple} Arbitrary Rolls in Output On the other hand, if you want to pick the dice type and produce a certain number of 1-die versions of a roll where you don't know in advance the number of dice, you can do that with Muler, too. The process is very similar to this example from a few months back. On my PublicTables character, I'll create 2 abilities (mules): DieRoller dietype=d10 rollcounter=0 rollsneeded=0 templateline={\&if get.PublicTables.DieRoller.rollcounter/get <= get.PublicTables.DieRoller.rollsneeded/get }{{Roll get.PublicTables.DieRoller.rollcounter/get=[\\][\\]get.PublicTables.DieRoller.dietype/get\\]\\] }} set\.PublicTables.DieRoller.rollcounter = {\&math get.PublicTables.DieRoller.rollcounter/get +1}/set get\\.PublicTables.DieRoller.templateline/get {&end} LaunchDieRoll !&{template:default} ?{Type|d4|d6|d8|d10|d12|d20} ?{Rolls|5} {{name=?{Rolls} Rolls of 1?{Type}}} get\.PublicTables.DieRoller.templateline/get set.PublicTables.DieRoller.rollcounter = 1/set set.PublicTables.DieRoller.rollsneeded = ?{Rolls}/set set.PublicTables.DieRoller.dietype = ?{Type}/set {&simple} Run LaunchDieRoll and answer the queries. Here are two runs where I asked for 5 rolls of 1d8, then 18 rolls of 1d10. I can explain what's going on in those command lines if you want, but it's late and this post is already long. Let me know!
1694032901
Essen
Pro
Marketplace Creator
That is all excellent! I plan to do a lot with the info you gave me, lol. For now, I'm trying to make a series of dice minigames. I got the most basic one made, but I want to be able to do math with the roll results.  Basic:   &{template:default}{{name=Dice Roulette 1v1}}{{Dice=You chose ?{Dice|4|6|8|10|12|20} sided dice.}}{{Red=[[d?{Dice}]]}} {{Blue=[[d?{Dice}]]}} {{Odds=[[?{Dice}]]:1}} The next one, I want to roll 2 Red, and find the difference between them. So if they're D6, and I roll a 2 and a 4, the range is 4 values. 6-4=2, so the payout is 2:1. How do I do that math with the roll results? Or is it simply impossible?
1694033627

Edited 1694033760
Essen
Pro
Marketplace Creator
The "obvious" math isn't working, so I assume I'm doing something wrong.
1694048786
timmaugh
Pro
API Scripter
Essen said: That is all excellent! I plan to do a lot with the info you gave me, lol. For now, I'm trying to make a series of dice minigames. I got the most basic one made, but I want to be able to do math with the roll results.  Basic:   &{template:default}{{name=Dice Roulette 1v1}}{{Dice=You chose ?{Dice|4|6|8|10|12|20} sided dice.}}{{Red=[[d?{Dice}]]}} {{Blue=[[d?{Dice}]]}} {{Odds=[[?{Dice}]]:1}} The next one, I want to roll 2 Red, and find the difference between them. So if they're D6, and I roll a 2 and a 4, the range is 4 values. 6-4=2, so the payout is 2:1. How do I do that math with the roll results? Or is it simply impossible? We can absolutely do the kind of math you're looking for, I just need to understand what the numbers mean. When you say you want to take the difference of the 2 dice, and you roll a 2 and a 4, I see the difference as 2... but you said that made 4 "values". What do you mean, "values" and how did you get 4? Then you subtracted 4 from 6. The 6 I understand as the number of sides of the due, but was the 4 from the greater of the 2 dice, or from the "values" that I don't understand? If you help clarify these, I can show the rest of the math. In fact, in a minute I can show the syntax of working with the roll values so you might be able to take it across the finish line, yourself. Let me get back to my laptop and cook up some meta magic for you. =D
1694056231
timmaugh
Pro
API Scripter
OK, I think I get it. The "value" is the range that the numbers can be apart and still constitute a "winning" throw. The greater the range, the smaller the odds/payout, since it's easier. So you'd have to first pick the dice type, then supply a "range" (I call it "spread" in this example). That would look like this: !&{template:default} [[ abs([[1d ?{Dice|4|6|8|10|12|20} ]] - [[1d ?{Dice} ]]) ]]{{name=Dice Difference}} {{Dice=You chose ?{Dice} sided dice.}} {{Red 1=$[[0]]}} {{Red 2=$[[1]]}} {{Difference=$[[2]]}} {{Spread=?{Spread|4}}} {{Result=***{&if $[[2]] <= ?{Spread} }Winner!{&else}Not a winner{&end}*** }} {&if $[[2]] <= ?{Spread}}{{Payout= [[?{Dice} - ?{Spread}]].value:1}}{&end}{&simple} REQUIRED SCRIPTS: ZeroFrame, APILogic Example output: As an added bonus, it only includes a "Payout" line if the throw is a winner. This example leans on Roll20 roll management and constructing the rolls first so they can be extracted later (rolls $0 and $1 are inside $2, so we can pull them out separately later, as we need them). If structuring the roll like this is not possible (there are many reasons why this could be), you can still re-use the roll values with the metascripts. Again, you don't NEED to with this roll, but to show you the options that are available in case you need to do it later... here is the same output rewritten to use SEPARATE Red 1 and Red 2 rolls... !&{template:default} {{name=Dice Difference}} {{Dice=You chose ?{Dice|4|6|8|10|12|20} sided dice.}} {{Red 1=[[1d?{Dice}]]}} {{Red 2=[[1d?{Dice}]]}} {{Difference=[\][\] abs($[[0]] - $[[1]]) \]\]}} {{Spread=?{Spread|4}}} {{Result=***{\&if $[[3]].value <= ?{Spread} }Winner!{\&else}Not a winner{\&end}*** }} {\&if $[[3]].value <= ?{Spread}}{{Payout= [[?{Dice} - ?{Spread}]].value:1}}{\&end}{&simple} For that one, we have to manually extract the value of the die roll in the IF blocks... not for any good reason, but just a quirk of how the code is written when the IF is deferred (and it has to be deferred to wait until roll $3 is finally rolled, which is itself deferred because it is waiting on the values to be extracted from other rolls). I should get in to APILogic and clean that up, but for now, this works as an alternate construction to show you how to work with separate dice rolls and extract their value.
1694083155

Edited 1694083299
Essen
Pro
Marketplace Creator
Awesome! Thank you! I did make a quick image to explain the concept. You're absolutely right, where the bigger the window, the smaller the payout, equal to the inverse of the spread. Red 2-5 is 4 values. So 6 sides - 4 spread = 2 payout multiplier. The smaller the window, the bigger the payout, with more dice faces having more room to fail, and thus a larger payout. The extra addition was to account for other things. I think a +1 is all that's needed. A roll of 1-6 would have an odds of 1:1, not 0:1. So the payout gets an extra +1 to account for this. D6 would pay 1:1 if Red is 1-6, and pay 7:1 if both Red dice are the same number. Alright, so. Just by doing rolls, Roll20 automatically makes $[[0]] and $[[1]]? I don't see them defined specifically, so I'll assume that's how the roll works. So the win payout would best be worked as: ?{Dice} - Red High + Difference + 1, 6 - 5 + 3 + 1 = 5:1 or ?{Dice} - Red Low + 1, 6 - 2 + 1 = 5:1 or ?{Dice} - Difference + 2, 6 - 3 + 2 = 5:1 Is there a way to compare the two values to determine which is higher than the other?  I added one using just Difference that got the same payout value.  We play these dice games in person in my other campaign, so I'm trying not to just define a range and roll the range, since we don't do that math for the other. We just define the roll values and try to get between them. I'm not too worried about it telling the player if they win or not, I think them watching the numbers and determining if they are within the range is a fun bit of tension. But I would like to figure out how to get the payout automatic so I'm not doing extra math while DMing.
1694084577
Essen
Pro
Marketplace Creator
I installed the API's andtried this.... !&{template:default} {{name=Dice Roulette: Straight}} {{Dice=You chose ?{Dice|6|8|10|12|20} sided dice.}} {{Red 1=[[1d?{Dice}]]}} {{Red 2=[[1d?{Dice}]]}} {{Difference=[\][\] abs($[[0]] - $[[1]]) \]\]}} {{Payout= [[?{Dice} - abs$[[2]]) + 2]].value:1}}} and it would prompt me to tell it what the Dice value is, and then output nothing to the chat, but I got a strong API error. TypeError: Cannot read properties of undefined (reading 'value') TypeError: Cannot read properties of undefined (reading 'value') at nestedInline (apiscript.js:7976:124) at runLoop (apiscript.js:8206:17) at handleInput (apiscript.js:8411:29) at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:168:1), <anonymous>:65:16) at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:168:1), <anonymous>:70:8) at /home/node/d20-api-server/api.js:1762: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) Here are the API's I have altogether:
1694102637

Edited 1694103160
timmaugh
Pro
API Scripter
OK... couple of things... It looks like you want the house to roll 2 Red dice, and the player to roll 1 blue. The difference in the Red dice is the range that the blue die has to be between for the player to win... is that correct? And for a winning throw, any of your odds equations will work, but the Difference equation is definitely the easiest. If that is all correct, let me quickly answer your questions (and what was going wrong in that roll) before I give the working version: Roll20 takes an inline roll like this: [[1d20]] ...and parses it to derive the value (and some other data) which gets added to the message object in code. In place of this verbiage in the command line, Roll20 leaves behind a "roll marker" -- which is just a new index number in a formation like: $[[0]] or $[[1]] or $[[2]] etc. Rolls are (roughly) resolved left to right, inside to out. RainbowEncoder has a fuller write-up on their understanding of how indices are assigned, but if you think about a parser operating left to right and look for which set of closing double brackets is encountered first, you'll be able to figure out which roll is referenced by which index. That means that a roll like this: [[ [[1d6]] - [[1d6]] ]] Has indices like this: 0 1 2 [[ [[1d6]] - [[1d6]] ]] When that is parsed out of the command line, what will be left behind is the OUTER-MOST roll, or $[[2]]. The other two rolls ( $[[0]] and $[[1]] ) are available, as well, but the roll markers for those are not left behind. Once you get past assigning the roll indices, you can't (natively) do math with the rolls. That is, you can't use a roll marker like $[[0]] within another inline roll: ... THIS DOESN'T WORK ... [[1d20]] [[ $[[0]] + 1d10]] The parser doesn't know where to go to get the information for that roll's value. The roll marker is really there for formatting purposes (when a message hits the chat window and gets the hover roll tip), and for mod scripts to know where to get the value for the roll. ZeroFrame uses some tricks to repeatedly engage the Roll20 parser. It's basically a loop: Roll20 detects rolls and creates roll markers ZeroFrame detects "deferral" characters and removes one level of them, exposing NEW roll constructions, and sends the message back to Roll20 Roll20 detects new rolls and creates roll markers etc. The deferral character is a backslash, or (for the opening double brackets of an inline roll, specifically), a right-bracket following all of the deferring backslashes. One backslash = one pass of the loop. This means that new constructions can be delayed a precise number of loops, depending on how long we have to wait. For the above example (the one that didn't work): [[1d20]] [[ $[[0]] + 1d10]] ...the second roll only has to wait for ZeroFrame to be able to find the value of the roll. That means we have a loop where Roll20 parses the rolls it sees to arrive at the roll markers. During that loop, ZeroFrame has a chance to get the value of the $[[0]] roll and supply it. That means the second roll could be evaluated during the second loop, so we only need 1 level of deferral: [[1d20]] [\][\] $[[0]] + 1d10 \] \] Of course, to engage the metascripts, it has to be part of a bangsy message (starting with a ! ). To see the results in the game, you'll need to include a {&simple} tag: ! [[1d20]] [\][\] $[[0]] + 1d10 \] \] {&simple} If you were to add another roll (a third roll) that required the results of that second roll, that would require 2 levels of deferral, since it has to wait until the value of the second loop rolls becomes available. !No deferral: [[1d20]] Single Deferral: [\][\] $[[0]] + 1d10 \]\] Double Deferral: [\\][\\]$[\\][\\]2\\]\\] + [[1d10]] \\]\\]{&simple} ZeroFrame will auto-replace the roll marker with the roll value if it detects that it is about to send a roll equation to Roll20 which includes a roll marker as part of a new inline roll... that's why the above will now work. In any case, this complicates roll index assignment. Here is the same command line with indices attached to the rolls: 0 2 * 1 3 !No deferral: [[1d20]] Single Deferral: [\][\] $[[0]] + 1d10 \]\] Double Deferral: [\\][\\]$[\\][\\]2\\]\\] + [[1d10]] \\]\\]{&simple} Roll indices are assigned as Roll20 encounters the closing double brackets, so rolls that are deferred for a future loop ARE NOT ENCOUNTERED immediately. Each loop continues to count up. Two rolls are found in the first pass, getting indices 0 and 1. During the second loop, one level of deferrals  have been removed, exposing a new roll that gets index 2. During the third loop, a new roll is exposed, getting the index of 3. Note that the special closure marked with an asterisk is not a new roll, and so does not get a new index. When the deferral characters are finally removed and the core syntax is exposed, it is an existing roll marker: $[[2]] TL;DR Solution With all of that explanation, here is the version that will work for you: !&{template:default} {{name=Dice Roulette: Straight}} {{Dice=You chose ?{Dice|6|8|10|12|20} sided dice.}} {{Red 1=[[1d?{Dice}]]}} {{Red 2=[[1d?{Dice}]]}} {{Difference=[\][\] abs($[[0]] - $[[1]]) \]\]}} {{Payout= [\\][\\]?{Dice} - $[\\][\\]2\\]\\] + 1\\]\\].value:1}} {&simple} You didn't need the abs() function in the last roll since you were referring to a roll where that had already been applied. You needed to double-defer the last roll since it was waiting on the Difference roll which was, itself, already deferred once. Your payout formula for using the Difference equation was incorrect -- it was wanting to pay 8:1 for situations where the Red Dice were equal, and an extra +1 for all other cases. I reduced it from +2 in the equation to +1, and things work. Here are a couple example outputs: My understanding is that you want this in the chat output, and then the player can roll their die on the VTT and read the number and manually compare to the data in the panel. If you instead want the player's die to be included in the output panel, you can add it, of course. =D
1694112295
Essen
Pro
Marketplace Creator
Real quick, is this all standard Javascript? Or is the Roll20 stuff proprietary? Your output is perfect, thank you. I really appreciate your help, and I'm gonna do what I can to learn all this for future use. 
1694112806

Edited 1694112842
timmaugh
Pro
API Scripter
The syntax you are seeing is not javascript. You are seeing a mix of Roll20 chat syntax and syntax to trigger metascript interaction. To be clear: Roll20 has a certain syntax that will trigger their parsers to do certain things. I wrote the metascripts (in javascript) to utilize *other* syntax to work in/around Roll20 formations and other scripts... but the triggering syntax we use in chat (or macros or ability macros) is not javascript. The tricks we're performing with metascripts will only work on Roll20 because they were built to work with the Roll20 process. =D
1694121178
Essen
Pro
Marketplace Creator
Is the Roll20 stuff unique, or does it have a general language/syntax name?
1694128374
timmaugh
Pro
API Scripter
The parser is certainly written in JavaScript or a server-side language. But the chat text keys that triggers the parsers to take action (stuff like double brackets for inline rolls, double braces for template parts, etc) were arbitrary choices by the devs. Similarly, my metascripts are written in JavaScript and they are set to recognize other arbitrary text formations I settled on (chosen so as to not interfere with Roll20 constructions. Does that make sense?
1694129307

Edited 1694130334
Essen
Pro
Marketplace Creator
That makes sense, but that doesn't mean I understand it to any degree of depth, lol. Coding is the one thing that I can't get to stick when I try to learn it. So I have a couple questions about the output. 1. I wanted to add in a Player Roll, just to simplify it for them, but adding one in, even at the end in front of &simple messed up the payout calculation. I set it to three delays, more delays than any of the other piece, and it still messed it up. Then I tried to make it 4 delays, and it crashed the API. I don't know how to make it work.  think I got this part working. 2. Is there a way to do all the Difference stuff, but not show it on the output? This is not at all a priority, I'm just curious. Here's what I have: !&{template:default} {{name=Dice Roulette: Arrowsnap}} {{Dice=You chose ?{Dice|6|8|10|12|20} sided dice.}} {{House 1=[[1d?{Dice}]]}} {{House 2=[[1d?{Dice}]]}} {{Difference=[\][\] abs($[[0]] - $[[1]]) \]\]}} {{Payout= [\\][\\]?{Dice} - $[\\][\\]2\\]\\] + 2\\]\\].value:1}} {{Player=[\\\][\\\]1d?{Dice}\\\]\\\]}} {&simple}
1694137112
timmaugh
Pro
API Scripter
Anything can be hidden in a template by putting it *between* the template parts... like this : &{template:default} This text won't show, nor this roll [[1d20]] ((name=Demo}}{{Refer to roll=We can still refer to the roll by the roll marker like this $[[0]] }} As for including a roll for the players, I know you have solved that, but it's a good chance to demonstrate roll indices. If you start with this command (hiding the Difference roll): !&{template:default} {{name=Dice Roulette: Arrowsnap}} {{Dice=You chose ?{Dice|6|8|10|12|20} sided dice.}} {{House 1=[[1d?{Dice}]]}} {{House 2=[[1d?{Dice}]]}} [\][\] abs($[[0]] - $[[1]]) \]\] {{Payout= [\\][\\]?{Dice} - $[\\][\\]2\\]\\] + 2\\]\\].value:1}} {&simple} And you want to add a Player roll component at the end: {{Player=[[1d?{Dice}]]}} ...it doesn't have to be deferred. You simply have to adjust your roll markers to make sure they still point at the correct roll. So, if that player role is included at the end of the template, it will be the third roll resolved in the first pass of Roll20 parsing. House 1 will be roll 0; House 2 will be roll 1; and the Player roll will be roll 2. The rest of the rolls are deferred until at least the next pass, so any roll marker that would have referenced roll $[[2]] or greater will need to be incremented by 1 to account for the new roll. That includes the deferred referral to roll $[\\][\\]2\\]\\] in the Payout section. That would look like: !&{template:default} {{name=Dice Roulette: Arrowsnap}} {{Dice=You chose ?{Dice|6|8|10|12|20} sided dice.}} {{House 1=[[1d?{Dice}]]}} {{House 2=[[1d?{Dice}]]}} [\][\] abs($[[0]] - $[[1]]) \]\] {{Payout= [\\][\\]?{Dice} - $[\\][\\]3\\]\\] + 2\\]\\].value:1}} {{Player=[[1d?{Dice}]]}} {&simple} I'm not at my computer, but that should work.
1694181569
Essen
Pro
Marketplace Creator
This clarifies a lot for me, but I'm having trouble explaining how I thought it was working. Thanks again!  I still plan to eventually try out that Roll=Text stuff from the start of the thread. I do that a lot in Excel for my loot tables, and it'll be good to use once I get some concrete use cases.