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

API for Pacesetter table results?

July 09 (3 years ago)

Edited July 09 (3 years ago)

Forgive me if this has been covered before. I know nothing about API, but is it possible to create something that would allow a GM to quickly calculate results from the Pacesetter action table?

Basically, for those that aren't familiar with this older system, each of these results is tied to specific outcomes relating to either Armed or Unarmed combat. I'm wondering if you could have a script that would be able to take the "Defense Column" value (those in blue here), and the "Attack Margin" and give you the corresponding letter determination, both armed and unarmed. 

So, an "L" tell you how much damage to calculate for either type of attack, an "M" result, etc. ("K" results refer to the victim being knocked down and back.)

July 09 (3 years ago)
timmaugh
Pro
API Scripter

Muler is a meta script that can handle static-access tables like this.

You could set up each column as a Mule table, and run the entries according to the ranges of the Attack Margins.

API scripts are a Pro perk, though. Do you have access to them?

If you do have access to install scripts and you want an example of this, I can help with the setup.

July 09 (3 years ago)

Edited July 09 (3 years ago)

I was going to get a pro subscription if I could make sure that this would work. How hard would something like this be to set up?

For the Defense Column, would it be possible to enter either a raw score number (like 62) and have it calculate which column result that corresponds with, OR just input the column number (1-10)? I would prefer if it could do both.

My last question: If I were to install this in the game, would I be the only one who could use it, or could players use it as well?

July 09 (3 years ago)
GiGs
Pro
Sheet Author
API Scripter

If you're Pro, and create a game, everyone in that game has access to all the pro features. Only you will be able to create and add scripts, but once you do, players can use them.

I don't know how to use Muler, but a dedicated script to generate and return table entries for that chart would be fairly straightforward. You'd need to explain how it works though (and what those blue numbers across the top are - looks like some small numbers under the big ones but I cant make them out).

Though if Tim shows us how to do it with Muler, that may be even better :)

July 09 (3 years ago)

Edited July 09 (3 years ago)

Here's a clearer version of the chart:

As you can see, I just need to be able to enter the Attack Margin score, and either the Defense Column number (1-10) or a score that would correspond to that number. Then, I just need it to spit out whatever the Armed and Unarmed Combat results are for that "Code" letter (along with the "K" result, when needed). 

Needless-to-say, if anyone would be willing to do this for me, that would be immensely awesome! But I may need to hold off an upgrading to a pro account until next week, if that would be ok.

(P.S. If I upgrade to pro, do I have to re-create the game I'm currently running under the free membership?)


July 09 (3 years ago)

Edited July 09 (3 years ago)

Very doable with the API script called ScriptCards.  Do you have an excel version of the mechanics or something that lays out the roll mechanics sequencing and any mods or adders to the the rolls?

I don't have this in Excel, no. Modifiers to the rolls would already essentially be applied prior. All the chart really does is communicate the outcomes after the roll, with whatever modifiers, has been made. 

Are you suggesting that the script could also handle rolls and calculate the Attack Margin by just entering a roll number? Like, if I need a 42, after modifiers, to succeed in a hit, I could just enter 42, click/type roll 1d10 or 2d10 or whatever, and the script would take it from there? Again, I know nothing about this process so forgive my ignorance.

July 09 (3 years ago)
GiGs
Pro
Sheet Author
API Scripter

In short, yes. A script could, given the target number, the defence column to use, whether its an armed or unarmed attack, give you the level of wound, roll the stun, and tell you the wound boxes to mark.

If you choose a target token linked to a character that has a DEX score, it could also roll the DEX for Knockdown effects, and report whether the target drops their items.

Pretty awesome. (And you just reminded me that I keep forgetting Dexterity checks with K results! Truthfully, the Pacesetter chart is a lot to take in, especially when you're trying to GM in chat only and you don't want to leave players waiting forever for a response.)

July 09 (3 years ago)
GiGs
Pro
Sheet Author
API Scripter

That's where scripts come in handy :)

July 09 (3 years ago)

I'm not up on Muler, but I do know you have a couple options:

1) Dive into API scripts (Javascript).  There is a bit of a learning curve if you've never programmed before.  

2) Leverage a prewritten API script like Scriptcards which is it's own procedural language with conditionals, loops, dice rolling, and token/character sheet and table access.  You could even potentially read the modifiers from the character sheet, roll the dice, get results and apply damage and conditions right back to a character sheet with tools like Token-Mod and ChatSetAttr.  

3) Leverage an API script like Muler.  

July 09 (3 years ago)

Edited July 09 (3 years ago)
timmaugh
Pro
API Scripter

OK, here is a proof of concept with Muler and ZeroFrame. I'll explain what is going on after the setup and usage.

Setup

  • Add a character to hold your Mules, I'll name mine TableMule
  • Create a new Ability on TableMule called ActionTable1; paste the following into the text of the ability (then save/close that ability):
0=get.L/get get.K/get
1-4=get.M/get
5-9=get.H/get
10-29=get.C/get
30-49=get.C/get
50-69=get.C/get get.K/get
70-89=get.C/get get.K/get
90-94=get.C/get get.K/get
95-99=get.C/get get.K/get
>=100=get.C/get get.K/get
  • Replicate this pattern for Abilities named ActionTable2 through 10, populating with "get" statements of the letters (so a K becomes get.K/get); separate the "get" statements for two letters with a space, as above
  • Create a new Ability on TableMule called ArmedResult; paste the following into the text of the ability (save/close):
S={{Scratch=Lose [[1d2]] points, and mark one wound box.}}
L={{Light Wound=Lose [[1d10*2]] points (1d10x2), and mark two wound boxes.}}
M={{Medium Wound=Lose [[2d10*2]] points (2d10x2), and mark three wound boxes.}}
H={{Heavy Wound=Lose [[3d10*2]] points (3d10x2), and mark four wound boxes.}}
C={{Crippling Wound=Lose [[3d10*2]] points (3d10x2), and mark five wound boxes.}}
K={{Knockdown=Defender knocked down and back}}
  • Create a new Ability on TableMule called UnarmedResult; paste the following (save/close):
S={{Scant Damage=Lose [[1d2]] points (roll 1d10, 1-5 = 1, 6-10 = 2).}}
L={{Light Damage=Lose [[1d10*2]] points (1d10x2).}}
M={{Medium Damage=Lose [[2d10*2]] points (2d10x2).}}
H={{Harsh Damage=Lose [[3d10*2]] points (3d10x2), and mark one wound box.}}
C={{Crushing Damage=Lose [[3d10*2]] points (3d10x2), and mark two wound boxes (or called shot, if specified otherwise).}}
K={{Knockdown=Defender knocked down and back 5 feet; all uncompleted actions this round are cancelled.}}

Usage

For this example, I am making a couple of assumptions/shortcuts...

  • the defensive value (the column to access in your chart -- or, for us, the Mule to read from) is coming from an attribute on the character. I created one called "PacesetterDefAttr" and gave it a non-zero value
  • the "Attack Margin" would for you (I'm sure) be a combination of attack attribute, modifier, and roll.... I'm just going with a 1d100 to generate a random result

The command line to use in a macro:

!&{template:default} {{name=@{target|token_name} is Attacked!}} get.[[1d100]].value/get{& mule ActionTable[[{[[ceil(@{target|PacesetterDefAttr}/15)]],10}kl1]].value ?{Type|Armed|Unarmed}Result} {&simple}

Example output:

Kokoro has a PacesetterDefAttr of 13; Armed combat

Igtharian has a PacesetterDefAttr of 87; Unarmed combat

Explanation

We are using the default roll template, and feeding the component rows based on what we return from the table lookups (what we find on our Mules).

To start this as an API-message, we prepend the statement with an exclamation point; to output the roll template at the end, we use the {& simple} tag (from ZeroFrame), which turns the command line into a standard message (no longer an API message). By the time it hits the chat, it will be populated with the roll template parts.

We need to know which ActionTable Mule to look on (1 through 10), as well as whether to look on the ArmedResult or UnarmedResult Mule. We do that with a {& mule ...} statement. {& mule...} statements load those Mules to make the table entries available. Our {& mule...} statement looks like this:

{& mule ActionTable[[{[[ceil(@{target|PacesetterDefAttr}/15)]],10}kl1]].value ?{Type|Armed|Unarmed}Result}

Ultimately, this will say something like:

{& mule ActionTable6 ArmedResult}
  • The inline roll takes the PacesetterDefAttr of a targeted token and converts it to a value between 1 and 10. The .value construct extracts the value of the roll (that's a ZeroFrame construct). When that is appended to "ActionTable", you get something like "ActionTable6". Now we know to load "ActionTable6".
  • The roll query just asks whether this is "Armed" or "Unarmed". The answer gets prepended to "Result", giving us something like "ArmedResult". Now we know to load the "ArmedResult" Mule.

Finally, the actual variable of the Attack Margin is retrieved from the loaded Mules. Like I said, I'm just generating the margin with a 1d100; you will probably have a larger set of modifiers:

get.[[1d100]].value/get

Since we've only loaded one Mule with numerical values, we get the appropriate result from the ActionTable Mule we loaded. Since that result is further get statements (i.e., get.M/get), we still have work to do.

But we can do ju-jitsu.

ZeroFrame operates on a loop, so the next time it turns to Muler, Muler recognizes that there are new "get" statements it needs to process. This time, we're looking for letter values, which we find in either the Armed or UnarmedResult Mule (whichever we loaded). This time, we load in the roll template parts, which might include new inline rolls:

M={{Medium Wound=Lose [[2d10*2]] points (2d10x2), and mark three wound boxes.}}

...so ZeroFrame rolls those.

Our work is done, so the {& simple} tag instructs ZeroFrame to output the finalized/reconstructed command line as a simple chat message, including the roll tips for the rolls it just processed.

Shabam.

Again, not sure I understand this or would have any idea how to do it myself. But it's at least comforting to know that it could be done. Thank you.

July 10 (3 years ago)
GiGs
Pro
Sheet Author
API Scripter


Yeti Spaghetti said:

(P.S. If I upgrade to pro, do I have to re-create the game I'm currently running under the free membership?)

No you dont - all your campaigns will become Pro automatically.


Sounds good. I'm just not sure I can do the scripting, so I'm probably staying with the free membership for now.

July 11 (3 years ago)

Edited July 11 (3 years ago)
GiGs
Pro
Sheet Author
API Scripter

I have made a basic script that will do what you need. Here's some sample output:

The top line shows Name, whether its armed or unarmed, and ability score. The rest should be self-explanatory.

With the script installed, you can create macros that will run it:

If everything's defined:

!pace --type:unarmed --score:75 --defense:2 --name:Bilbo

If you want include character attributes, something like

!pace --name:@{selected|token_name} --type:armed --score:@{selected|sword} --defense:2

If you want to use queries to find out the values to use (this will prompt you for everything that starts ?{

!pace --name:?{Enter Name?|Bilbo} --type:?{Attack Type?|Armed|Unarmed} --score:?{Ability Score?|0} --Defense:?{Defence?|3} --?{Defence Column or Score?|Column,0|Score,1}


You can enter defence as a column or an attribute - if using an attribute, you need to add on --scale:1 to get it calculate properly.

If you want to give it a try, let us know when you've got Pro, and I'll post the script code.


Wow, thanks so much! That looks great. So after installed, either the players or I just type out (or paste) those instructions into the chat, with the correct numbers filled in and either armed or unarmed specified? That seems pretty straight-forward enough. 



July 11 (3 years ago)
GiGs
Pro
Sheet Author
API Scripter

Yes, the lines of text I posted are examples.You don't have to manually type them each time - you can create macros and just press a button to trigger them.

The lines of text I posted are examples of macros which include or gather the information you need - the only required infos are type (armed/unarmed), score (the target to roll against), and defense (the column to use, or score from which to calculate a column).

Perfect. I'll be in touch soon, and thanks again!

July 11 (3 years ago)
GiGs
Pro
Sheet Author
API Scripter

Just post here when you need it :)

July 16 (3 years ago)

Edited July 16 (3 years ago)

GiGs, one more question: When you say the macro would "gather" the information you need about type of attack, roll score, and defense column, how does that work? When you click on the macro bar on the table would it pop up a window asking for that information? 

July 16 (3 years ago)

Edited July 16 (3 years ago)
GiGs
Pro
Sheet Author
API Scripter

See my earlier post with some examples. You'd create a macro containing text like one of these:

!pace --type:unarmed --score:75 --defense:35 --name:Bilbo
!pace --name:@{selected|token_name} --type:armed --score:@{selected|sword} --defense:@{target|agility}
!pace --name:?{Enter Name?|Bilbo} --type:?{Attack Type?|Armed|Unarmed} --score:?{Ability Score?|0} --defensecolumn:?{Defence?|3}

You could hardcode specific values like the first one, you could use attributes to get the values like the second one, or you could use queries to collect the needed values. Queries will give you popups to enter information, while attribute calls will grab the attribute value straight from a character sheet. And you can mix and match methods in the same macro.

Great, thanks again! Looking forward to experimenting with this later this month. I'll post again when I'm ready to add your script.

I think I'm ready to install the script now. Is there any way you can PM me to walk me through the process?

August 04 (3 years ago)

Edited August 04 (3 years ago)
GiGs
Pro
Sheet Author
API Scripter

The script is here: https://gist.github.com/birdbrainiac/4e92f46651b3d8cf8db917e4f7b09a7c

Click the RAW button on that page, and copy the text, then paste it into your campaign's API settings page (this is found on the Settings button on your campaign's launch page).

See the example macros from 3 posts up, as examples of using the script once it's installed.

Let me know how you get on :)

August 04 (3 years ago)
keithcurtis
Forum Champion
Marketplace Creator
API Scripter

Here's a helpful video:

How to Install Roll20 API Scripts

Everything seems to be working well! It did give me a response once that said "(From Pacesetter): Error in Script Values" but it still gave me a result for the roll.

I sort of wish it didn't ask for a name each time, since whoever is clicking the macro will have the result tied to their token. But it's not that cumbersome. I'll just tell everyone to skip that step. And instead of "Stun" it should say "Stamina," but again, not a big deal.

This is great! Can't wait to try it in game. Thanks again GiGs and everyone at Roll20!

August 04 (3 years ago)
GiGs
Pro
Sheet Author
API Scripter

It doesnt have to ask you for the name each time. You can use

--name:@{selected|token_name}

and that will use the token name. Look up at that earlier post for examples: https://app.roll20.net/forum/permalink/10251296/

I'll change the stun to stamina later.

Ah got it. I'll edit that into the macro for the roll prompt.

One more question: If I wanted to make a macro for an automatic burst attack with just one attack score, but with 10 separate results aimed at a selected number of defenders (1 or more) where each defender is randomly assigned a different defense column, what would that look like?

Sorry if this is a curveball but if it would require more scripting, then no need bothering. 

August 05 (3 years ago)
GiGs
Pro
Sheet Author
API Scripter

That would require at present a different macro line for each target.

If I have time over the weekend I'll see about adding the ability for multiple attacks - though roll20 itself is a bit clunky about managing things like this even with a script.

No worries. It doesn't come up often enough to put you through the bother. I just wasn't sure if you could have the script do that.

If I were to change line 104 myself (below), where in place of "Stun=" I were to write "STA=" for Stamina, would that work? I'm getting curious now about installing separate versions of the script to show different results from the table for different kinds of rolls, but I obviously don't want to mess anything up.

output.template += `{{Result=${table.type} (${output.damageresult}) }} {{Stun=[[${table.stun}]]}}`



August 05 (3 years ago)
GiGs
Pro
Sheet Author
API Scripter

Yes, that should do it. I forgot to update that myself.


If you have plans for different versions, if you describe them I may be able to modify the script to do each of them. If you just need to change the labels that are displayed on output, that would be easy to do.

Ok, thanks again.

Basically, it would be great to have a script for Fear Checks in the game, using the same table. Only these are the only results: