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

Using Roll Tables through a Macro, and modify Roll table weight

May 15 (2 years ago)

Hi, me again !


I'm am once more looking for a bit of help for my Fallout game. I've just written a wall of text to explain my issue, and got an error when I posted, so I'm gonna try to make it shorter, this time \ô/


I'm trying to mess around with my critical rolls. Right now, when a critical hit happens, players roll a d100. The result of the dice will point to an outcome on this chart :


Why a d100 and not a d6, since there are only 6 outcomes per zone ? Well, that's because it lets us make the best outcomes a bit more rare, and also because the players can have perks that let them influence the result by adding a few points to it. Now, that is working pretty well for Critical Hits.


The part I'm struggling with is Critical Misses. Right now there isn't really a chart, and I'm trying to change that. What I want to do is to have that kind of chart :


Now, the outcomes in this chart will be a bit more generic, like "drop your weapon, lose your ammo, break a limb, hit an ally, lose your turn, fall on the ground", but I want to be able to combine a few effects together to make the outcomes a bit more unique, like "you drop your weapon, fall down, and are stunned for a turn". To do this, I can go like this :

- The one who gets a Critical Miss will roll a d100, the result of that d100 will tell them how many "outcomes" they'll accumulate. For example, rolling 1-30 will be 1 outcome, 30-45 will be 2 outcomes, and so on and so forth, up to 5 or maybe 6 outcomes if you roll a 100.

- They will then have to roll on a collumn, for each outcome. I'll make Roll Tables for each collumn, so that it's easier to roll.

- The macro will then grab the results from those Roll Tables and display them in a text box, in the chat.


I have two issues with this :

- I'll obviously have to use "weight" for the outcome in Roll Tables. For example, outcome 1 will pop up on a 1-20. So that'll be a weight of 20. But how do I slip the perks in here ? Some player perks let them raise or lower the result, but I don't think you can add a way to modify an outcome's weight in a Roll Table. is there a way to do that ?

- Is there a way to tell the macro "roll a random Roll Table, among those six, x times, with x being the result of a dice" ?


I don't think I can achieve what I want with just a macro and roll tables, but it's worth giving it a go. If anybody knows how to pull this off, or knows or a better way, I'd really appreciate it ! Thank you for reading, and thank you for your time !



The first of your two issues is the rollable table with modifier problem. Not natively supported however there is a suggestion for Rollable table with modifier support, consider adding your voice and vote for it. Until such time as that is implemented you'd have to rely on mods such as the Metascript suite or ScriptCards.

The second of your issues I see two native solutions. Either a two-click macro that determines how many of the x times rolls on each table and provides a button to then do the rolls or combining the six columns into a single rollable table that you could roll on immediately. The jumbo table solution would only work for an unmodified d100 roll as is; however with the suggestion of custom dice syntax and alongside the previously linked suggestion a modifiable jumbo table solution could work.

But since to get modifier support now you'd need mods you might as well use mods to handle both issues. I'm sure their respective proponents will be happy to help.

May 15 (2 years ago)

Thanks for your answer, chap.


After thinking about it for a while, I think that I'm going for something way to complex. Hell it's just meant to determine what happens when you fumble.

I think I'll just add all the possible outcomes in a single table, and have a macro that rolls it x times. The only issues that this would present are the possibility of a duplicate outcome. And also the fact that I won't be able to differentiate between "light" outcomes and "harsh" outcomes. The perk would not change the outcomes themselves, but the number of times they are rolled.


I suppose I might be able to create three tables : one for light outcomes, one for medium outcomes, and one for harsh outcomes, but then again... how would I tell the macro to roll that kind of table that many times ?


I might just.... keep it manual, and give up on doing it through macros and roll tables !

May 15 (2 years ago)
David M.
Pro
API Scripter

Tracyn, since you've poked around a little bit with Scriptcards already, I'll point out that it has a function that can build an array from rollable tables, allowing you to "roll" with modifiers (create a roll variable based on the array size, add modifiers, and return that array value by index), and then based on conditionals/logic you could roll on subordinate tables. Just search for "rollable table" on the wiki to find the syntax.

May 15 (2 years ago)
timmaugh
Forum Champion
API Scripter


Tracyn said:

- I'll obviously have to use "weight" for the outcome in Roll Tables. For example, outcome 1 will pop up on a 1-20. So that'll be a weight of 20. But how do I slip the perks in here ? Some player perks let them raise or lower the result, but I don't think you can add a way to modify an outcome's weight in a Roll Table. is there a way to do that ?

- Is there a way to tell the macro "roll a random Roll Table, among those six, x times, with x being the result of a dice" ?


I don't think I can achieve what I want with just a macro and roll tables, but it's worth giving it a go. If anybody knows how to pull this off, or knows or a better way, I'd really appreciate it ! Thank you for reading, and thank you for your time !




Hey, Tracyn... you're right that standard rolls against rollable tables do not let you roll with modifiers, but Muler (a metascript) does. It builds an open-ended range of values for your table weights so that you can use a normal roll (incorporating whatever modifiers you require) and get the result. For a table named FumbleTable where you have a total weight of 100 for all of the entries, and where you would want to include the selected token/character's attribute named OffsetPerk to reduce the roll (higher values would be worse, lower values better), that might look like:

get.table.FumbleTable.[[1d100-@{selected.OffsetPerk}]].value/get

As for which table to roll among the six... getting a random table name can be as simple as another rollable table with the table names as options (Weapon, StrayHit, SelfWound, etc). I'll call it CriticalMissTables. Then just use a roll against this table within the Muler get statement, but use the ZeroFrame .value syntax to extract the result so it can be used:

get.table.[[1t[CriticalMissTables]]].value.[[1d100-@{selected|OffsetPerk}]].value/get

To get the right number of these returns, I would set a value (representing the number I wanted) using Muler, then I would retrieve the above formation but within a test whether a Counter variable was equal to the number required or not. I can provide an example of that, if this is the direction you want to go.

May 15 (2 years ago)
timmaugh
Forum Champion
API Scripter

Here is the solution as I implemented your setup, in case anyone else wants to go this route. I only mocked up half of the Critical Miss tables -- just enough to demonstrate the method.

I created tables of Weapon, StrayHit, and SelfWound (you'd create the other 3, as well). They had values and weights like this:

You'd obviously have all 6 tables, and with the actual color text you required.

Then I created a rollable table called CriticalMissTables listing the names of those tables:

And, finally, I created a rollable table called CriticalMissCount that had the relative probabilities of having 1, 2, 3, or even up to 6 adverse effects as a consequence of this critical miss:

I could have done these with Mule abilities, but this is about showing how to roll against rollable tables with modifiers.

After the rollable tables, I created a couple of abilities on a character named TableMule. The first I called CriticalMissEngine:

needed=1
counter=1
templateline={{Outcome get.TableMule.CriticalMissEngine.counter/get =get\.table.[[1t[CriticalMissTables]]].value.[\][\]1d100-@(selected.OffsetPerk)\]\].value/get }} {\&if get.TableMule.CriticalMissEngine.counter/get < get.TableMule.CriticalMissEngine.needed/get }get\.TableMule.CriticalMissEngine.templateline/get set\.TableMule.CriticalMissEngine.counter = {\&math get.TableMule.CriticalMissEngine.counter/get + 1}/set{\&end}

The needed variable will represent how many events I need to generate. The counter variable will track how many we've already produced. And the templateline variable is the actual line that we'll use in a templated output. The templateline variable also has the conditional check to see if the counter is greater than the needed (at which point we should stop producing adverse results), as well as the set command that increments the counter. You can see, too, that I went to a Fetch construction for the OffsetPerk since during the loop there will be no selected token during the Roll20 portion of the parsing; only after SelectManager restores the token can we get info from it as a selected token, so that necessitates a retrieval method that would follow SelectManager (like Fetch).

The other ability I called CriticalMissGenerator. This is the one you would call to generate the template output:

!&{template:default}{{name=Critical Miss}}get\.TableMule.CriticalMissEngine.templateline/get set.TableMule.CriticalMissEngine.needed = [[1t[CriticalMissCount]]].value/set set.TableMule.CriticalMissEngine.counter = 1/set {&simple}

Running the CriticalMissGenerator would generate a random number of adverse results it needs to create, then it would set about filling the lines of the template output with the results, once created. Here are 4 results run back to back:


May 16 (2 years ago)


David M. said:

Tracyn, since you've poked around a little bit with Scriptcards already, I'll point out that it has a function that can build an array from rollable tables, allowing you to "roll" with modifiers (create a roll variable based on the array size, add modifiers, and return that array value by index), and then based on conditionals/logic you could roll on subordinate tables. Just search for "rollable table" on the wiki to find the syntax.


I've been playing around with them to create a couple more useful cards, indeed. They're fun to poke around with !


And timmaugh, mate... my goodness. This looks amazing. I reckon it's gonna do the job, and I might start to get a liking to fumbles \ô/


I'm at work right now but I've read through your post a couple of times, and I do have a couple of questions :

- Do you think replacing the OffsetPerk character attribute with a query would work ? I reckon it would, and since some player perks enable them to add different values to the rolls, it'd be easier to use a query.

So, it might look something like this ?

get.table.FumbleTable.[[1d100-?{Modifier}]].value/get

I suppose that, since Roll20 lets you input one query and will use it through the whole thing if it is called several times in a macro, that could work with the templateline on the bottom ?


- If I understand everything correctly, the CriticalMissGenerator will call the CriticalMissEngine, which will in turn call the abilities of a character, which you named TableMule. Does this mean that I need to create a character, and that the generator will go through it to call upon all the ressources needed to roll everything and output the final results ?


Thanks for your answers, lads. It's really fun to see all the ways people come up with to find solutions to a problem !

May 16 (2 years ago)
timmaugh
Forum Champion
API Scripter


Tracyn said:

I'm at work right now but I've read through your post a couple of times, and I do have a couple of questions :

- Do you think replacing the OffsetPerk character attribute with a query would work ? I reckon it would, and since some player perks enable them to add different values to the rolls, it'd be easier to use a query.

So, it might look something like this ?

get.table.FumbleTable.[[1d100-?{Modifier}]].value/get

I suppose that, since Roll20 lets you input one query and will use it through the whole thing if it is called several times in a macro, that could work with the templateline on the bottom ?

That idea would generally work -- roll queries resolve before inline rolls. However, we are building the command line dynamically, in cycles. Each cycle is a new message. So this portion of the command line doesn't appear until we've retrieved the info from the CriticalMissEngine. More importantly, it isn't there when the query is processed and resolved.

Doesn't mean it's impossible; it just means we have to do more hand-holding to keep the query resolution around from one message cycle to the next. We'll do that with a ZeroFrame {&global} tag in the CriticalMissGenerator (the message we run where we will have a chance to respond to a roll query):

{&global ([fumbleMod] ?{Modifier|0})}

Now that will stick around as we add more pieces. Every time we loop through another cycle, ZeroFrame will run a text replacement for that variable name (fumbleMod) and insert the results of the query.

Since we will use it in a roll and since ZeroFrame can only get involved in the message after Roll20 parsing (including processing inline rolls), we have to make sure the roll is deferred (or slowed down) so that we give ZF a chance to make the text replacement changes we're looking for. The good news is that the roll was already deferred in my working example with the setup and images. (The post you copied to insert the query was more a "this is what the base syntax looks like" rather than all of the tweaks and deferrals required to make it work.) So all we need to do is replace the Fetch construction getting the attribute, inserting the variable fumbleMod in its place.

The two reworked abilities would look like:

CriticalMissGenerator

!&{template:default}{{name= Critical Miss}}get\.TableMule.CriticalMissEngine.templateline/get set.TableMule.CriticalMissEngine.needed = [[1t[CriticalMissCount]]].value/set set.TableMule.CriticalMissEngine.counter = 1/set {&simple} {&global ([fumbleMod] ?{Modifier|0})}

CriticalMissEngine

needed=1
counter=1
templateline={{Outcome get.TableMule.CriticalMissEngine.counter/get =get\.table.[[1t[CriticalMissTables]]].value.[\][\]1d100 - fumbleMod\]\].value/get }} {\&if get.TableMule.CriticalMissEngine.counter/get < get.TableMule.CriticalMissEngine.needed/get }get\.TableMule.CriticalMissEngine.templateline/get set\.TableMule.CriticalMissEngine.counter = {\&math get.TableMule.CriticalMissEngine.counter/get + 1}/set{\&end}


Tracyn said:

- If I understand everything correctly, the CriticalMissGenerator will call the CriticalMissEngine, which will in turn call the abilities of a character, which you named TableMule. Does this mean that I need to create a character, and that the generator will go through it to call upon all the ressources needed to roll everything and output the final results ?

Both the CriticalMissGenerator and CriticalMissEngine are abilities on the TableMule character. You can see that they refer to TableMule when they execute their get or set statements. The character they reside on isn't important except that anyone who would need to perform this Critical Miss Check would need controlling rights to the character (adding "All Players" to the "Can be controlled by" field should do the trick).

Since the abilities are generic (they don't really refer to a specific character, and even before this most recent change they only referred to a "selected" character token), I put them on a mule to let any/all players to roll against them.

Also, the name of the character they are housed on isn't important; but if you named your character something different you will need to chase that change through the 2 abilities so that they continue to refer to the proper mule character.







May 17 (2 years ago)

Edited May 17 (2 years ago)

Oh, I got it. Those abilities, right. I haven't used them once since I started using Roll 20 so they completely slipped out of my mind !


So, I set up a character named TableMule (might rename it and change it in the formulas later but right now I'm trying it out.à

It has those two abilities :

https://i.imgur.com/RTMu1ma.png

https://i.imgur.com/webzydV.png


I've copied and pasted the ones you posted, I don't think I've missed anything. The needed field shows a small formula instead of a 1 like in your post but I suppose it's normal, the one in your post must already have gone through the macro.

I created those rolltables :

https://i.imgur.com/wMxhJtm.png


I did input the names "crittestx" 1 to 6 in the "CriticalMissTables" rolltable. I think everything is set up as it should be. Muler, libTable, and Messenger are added to the game and running. I'm trying to run the "CriticalMissGenerator" from the TableMule character, that I've placed on the board, and the "Modifier" query pops up. After inputting a value (in this case I kept the default 0), nothing else happens. Have I missed something ?



Thank you for the time you're spending on this, its really kind of you !


Edit : Apologies, the image upload got a bit wonky, had to upload them to Imgur.

May 17 (2 years ago)
timmaugh
Forum Champion
API Scripter

Ah, that's my fault. I typically list the scripts you need when I show a solution like this. In addition to Muler, Messenger, and libTable (the last 2 install automatically with Muler from the one-click), you will also need APILogic (for the IF conditional), MathOps (for the ... uh... math operations), and ZeroFrame (to establish the metascript loop and output the template at the end). ZeroFrame will also require libInline (installed automatically from the one-click).

Then... THEN... my friend... the circle will be complete...

All too easy.

May 18 (2 years ago)

Oh yeah, it's all coming toghether. It's working like a charm, now.


Thanks a bunch, mate, you're awesome. It's gonna make critical failures so much more interesting !

May 18 (2 years ago)
timmaugh
Forum Champion
API Scripter

w00t!

Glad it's working!