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

Wildsea Dice Template

Not sure if this goes here, but here goes: I want to play Wildsea with some friends over Roll20, and the current sheet available is based on a previous playtest iteration of the game. I've updated it a bit in my Custom Sheet Sandbox to the final version of the rules, but the output from rolling from the sheet is still just the basic /roll output. I'd like to make a simple template for the rolls that displays the name of the skill being used, as well as two other pieces of information: 1. The highest die roll among the pool of dice rolled, and 2. whether there were any multiples of the same value in the rolled dice (called a Twist in Wildsea). Could anybody potentially help me out with this? I fully intend to submit the result to be updated in the sheet repository and I'm not super up on how to build dice templates.
1665207241
GiGs
Pro
Sheet Author
API Scripter
There's not enough information here to fully help you. We'd need to see a complete roll macro, and know attribute names involved. However, I can tell you that you that you'll have to use Custom Roll Parsing , because you can't do both of these in a single roll: The highest die roll among the pool of dice rolled, and whether there were any multiples of the same value in the rolled dice With a normal macro you can only do one or the other, not both at the same time, so you'll have to use CRP to generate those values.
Currently, rolling a skill does this: /roll {?{Edge?|None,0|Grace,1|Iron,1|Instinct,1|Sharps,1|Teeth,1|Tides,1|Veils,1}d6 + @{brace}d6 + ?{Advantage? (up to 2d6)|0}d6}dh?{Cut?|0} The system forms a pool of d6s from Edges - If you have an Edge appropriate to the action, you get 1d6 for the roll. Only 1 Edge may be applied to an action. Skills - You get the rating of the skill in d6s if you have it. Skills are rated 1-3 Advantages - If you have an advantage from any number of sources, you can get up to 2 extra d6 in your pool. You roll the dice and then the following happens: You remove the highest X dice from your results, where X is the Cut value assigned by the GM. You look at the highest remaining dice in your results, and that is your final success (or failure) level. If you have matching dice in your results, you get a Twist, which is basically a plot twist added into the normal results of the roll. I hope that helps. I'm not quite sure what else you would need.
1665262451

Edited 1665262518
GiGs
Pro
Sheet Author
API Scripter
I don't understand this part: You remove the highest X dice from your results, where X is the Cut value assigned by the GM. Is this a single value or a die type? Does it mean to remove a number of dice or a single die that is of a certain die type, or does it just mean remove the highest die (up a certain value?)? Also does the GM declare what the Cut value is before the roll? Does the player know what it is before they roll or does it apply to the dice after they have been rolled (that will cause problems for any automated generation, given the limitations of the roll20 interface).
I'll walk through an example roll to hopefully help clear up the confusion. Sam wants to cook up a meal for his crew, trying to make something they'll all enjoy. They build a pool of dice as follows: The GM declares that cooking to everyone's tastes requires some logic and wits. They decide that the Sharps Edge is the appropriate Edge for the roll. Sam notes they have this Edge on their sheet, and add 1d6 to the pool. Sam has a rating of 3 in Cook, so they get 3d6 in the pool for the roll. Sam has a brand new set of chef's knives that give an Advantage of +1d6, which adds into the roll. The GM decides that the ship's pantry is on the lean side, and so the Cut for the roll will be 2. Sam rolls 5d6, getting a 1,3,4,5,6 on the roll. Because the Cut is 2, the 5 & 6 are removed from the result. The final results are 1,3,4. As 4 is the highest single die remaining, it nets a Conflict result (which is basically a success + some other complications happen). Since no matching dice remain in the results, no Twist occurs. The Cut is specifically announced by the GM prior to the roll, and removes dice regardless of type, so it doesn't have to target die types in the pool.
1665287351
GiGs
Pro
Sheet Author
API Scripter
That's an illuminating example. So the Cut is the number of highest dice removed?
Correct. The Cut is simply the number of highest dice removed.
1665455363
GiGs
Pro
Sheet Author
API Scripter
Do you only get 1 Twist, regardless of the number of matches? What do you want to be shown in the output? By the way, the Cut will have a severe reduction on success probabilities.
Yes, you can only get 1 Twist regardless of the number of Matches. I would like the output to show the names of the Edge and Skill used, the highest remaining die after the Cut, and whether there was a Twist or not. I understand the Cut having a reduction on success probabilities. That's what the Cut is meant to do.
1665516135
GiGs
Pro
Sheet Author
API Scripter
Last question (because CRPs are cpmplicated): will you be using this for just the brace button, or do you want to be able to use the same method with multiple attribute screens and buttons?
There's a button for each skill, of which there are 18 in total. Brace is the name of just one of the skills. I should be able to replace "brace" with any of the other buttons to get a roll for that skill.
Also, before I forget, thank you so much for all the help! You are awesome!
1665528698
GiGs
Pro
Sheet Author
API Scripter
MrWagenbach said: I understand the Cut having a reduction on success probabilities. That's what the Cut is meant to do. I'd missed that was looking for the highest die, and was soemhow thinking it was sum. Taking the highest die makes more sense and looks less problematic there. A hopefully final question just occurred to me: what happens if the Cut leads to rolling 0 or fewer dice?
The rules don't specify what happens if the Cut would lead you to 0 or fewer dice, but if you don't have any dice for an action, you can't attempt it. So my guess is that if the Cut would reduce you to 0 dice, you don't get to attempt it, it's beyond your character's capabilities at that time. I hadn't noticed that it isn't specified in the Wildsea rulebook, so I will probably shoot the creator of the game a message to see what should happen in those cases.
So after reaching out to the author of the game, it turns out there is a specific rule for a situation where a Cut reduces a dice pool to zero dice. In those situations, you roll a single d6 and if you roll a Triumph (a 6), it instead counts as a Conflict (normally a 4-5).
1665692552
GiGs
Pro
Sheet Author
API Scripter
I assume that doesn't make a difference in the way you want things displayed? I'd have posted a solution last night but one of things I was thinking of displaying (each individual die rolled) was having issues when there was a Cut, and I couldnt figure out what was going on there. I may skip that part - you can still see the dice rolled when hovering over the final result.
You are correct.
1669707044
GiGs
Pro
Sheet Author
API Scripter
I've been offline for the last month. Do you still need a solution for this?
I do kind of want one, but at the same time, my plans to run the game have been scrapped because of work. So I'm not in any sort of rush to get one working now.
1669951982
GiGs
Pro
Sheet Author
API Scripter
I think I had gathered all the information needed to put this together in the thread (and had a solution almost completed). I'll read through it and see what I can do.
1670055517

Edited 1670055636
GiGs
Pro
Sheet Author
API Scripter
How does this look? Here are two rolls - one with no modifiers to the roll, and one with Edge, Advantage, and Cut, and it did roll a Tiwst. Does that look okay? The way it's set up you can change up the roll template to make it appear how you like. The main thing is to check that all the information is accurate. I should have made another roll using Cut. That -2 means the 3rd highest roll is being taken. The fact that the top 3 are all 5's makes it less obvious!
1670058266
GiGs
Pro
Sheet Author
API Scripter
I tweaked the rolltemplate slightly to make it a little more compact. In this one the basic roll and any advantage dice are on the same line, and if there is an edge it shows (+1d6) as well. (This roll has no Cut applied since there's no change there).
I like that! Awesome work.
1670455144

Edited 1670559992
GiGs
Pro
Sheet Author
API Scripter
I'll post the code below. Don't be pout off because there is a lot of it. See the next post - it is pretty simple to just drop this code into your sheet. The next post tells you the small bits that you need to customise. First the CSS, which is in two parts. The layout of the buttons in sheet I used for testing - you can dispense with these because it won't be necessary for you: div.buttons {   display : grid ;   grid-template-columns : 50px 50px 60px ; } Now the rolltemplate CSS, which is very necessary (this is Jakob's Better Rolltemplate from the wiki, and could be swapped to a different rolltemplate if you know what youre doing) /* Smaller margins - remove these if you want the huge default left margin */ .sheet-rolltemplate-custom {   margin-left : -37px ; } .withoutavatars .sheet-rolltemplate-custom {   margin-left : -7px ; } .sheet-rolltemplate-custom .sheet-container {   border : 1px solid ;   /* by default, the border is the same color as the header. You can change this here, e.g. to black */   border-color : var ( --header-bg-color ); } /* Header formatting - title and subtitle */ .sheet-rolltemplate-custom .sheet-header {   background-color : var ( --header-bg-color );   /* change text-align to center to center the header text */   text-align : left ;   color : var ( --header-text-color );   padding : 5px ; } .sheet-rolltemplate-custom .sheet-title {   font-size : 1.1em ; } .sheet-rolltemplate-custom .sheet-subtitle {   font-size : .9em ; } /* example colors */ .sheet-rolltemplate-custom .sheet-container {   /* this is the default color */   --header-bg-color : rgba ( 112 , 32 , 130 , 1 );   --header-text-color : #FFF ; } .sheet-rolltemplate-custom .sheet-container.sheet-color-red {   --header-bg-color : #F00 ; } .sheet-rolltemplate-custom .sheet-container.sheet-color-green {   --header-bg-color : #0F0 ;   --header-text-color : #000 ; } /* Allprops part */ .sheet-rolltemplate-custom .sheet-content {   display : grid ;   background : #FFF ;   /* Header formatting - modify the column layout below */   grid-template-columns : auto auto ;   /* Line height to match default roll template */   line-height : 1.4em ; } .sheet-rolltemplate-custom .sheet-content > div {   padding : 5px ; } /* Left column */ .sheet-rolltemplate-custom .sheet-content .sheet-key {   font-weight : bold ;   padding-right : 10px ;   text-align : right ; } /* Empty rule, use this if you want to change the right column .sheet-rolltemplate-custom .sheet-value { } */ /* Make even-numbered rows grey */ .sheet-rolltemplate-custom .sheet-content :nth-child ( 4n+3 ), .sheet-rolltemplate-custom .sheet-content :nth-child ( 4n ) {   background : #EEE ; } /* Description field */ .sheet-rolltemplate-custom .sheet-desc {   grid-column : span 2 ;   padding : 5px ;   text-align : center ; } Then on to the stuff that goes in the HTML page First the test buttons I created. Most of this you can delete, it was for my test: < div class = "buttons" >     < span > Brace: </ span >     < input type = "number" name = "attr_brace" value = "2" >     < button type = "roll" name = "roll_brace" value = "@{brace_stat}" > Roll </ button >     < input type = "hidden" name = "attr_brace_stat" value = "" >     < button type = "action" name = "act_brace_button" class = "hidden" > Brace </ button >     < span > Fist: </ span >     < input type = "number" name = "attr_fist" value = "2" >     < button type = "roll" name = "roll_fist" value = "@{fist_stat}" > Roll </ button >     < input type = "hidden" name = "attr_fist_stat" value = "" >     < button type = "action" name = "act_fist_button" class = "hidden" > Fist </ button > </ div >   I'd recommend creating a blank sheet in the sandbox to test with this code so you can see how this part works. the first roll button in each group (roll_statname) is visible, and relies on the two hidden elements that follow (a hidden input and a hidden action button). These are used by the sheet worker below that makes everything work. Then the rolltemplate part, to layout the results (I always put rolltemplate code after the main html and just before the scipt block containing the sheet workers) < rolltemplate class = "sheet-rolltemplate-custom" >     < div class= "sheet-container sheet-color- {{ color }} " >       < div class= "sheet-header" >         {{#title}} < div class= "sheet-title" > {{ title }} </ div > {{/title}}         {{#subtitle}} < div class= "sheet-subtitle" > {{ subtitle }} </ div > {{/subtitle}}       </ div >       < div class= "sheet-content" >                 < div class= "sheet-key" > Roll </ div >         < div class= "sheet-value" >             {{ ability }}{{#rollGreater () advantage 0 }} **+** {{ advantage }}{{/rollGreater () advantage 0 }} **d6**         </ div >         {{#rollGreater () edge 0 }}         < div class= "sheet-key" > Edge </ div >         < div class= "sheet-value" > {{#rollTotal () edge 1 }} **Grace** {{/rollTotal () edge 1 }}             {{#rollTotal () edge 2 }} **Iron** {{/rollTotal () edge 2 }}             {{#rollTotal () edge 3 }} **Instinct** {{/rollTotal () edge 3 }}             {{#rollTotal () edge 4 }} **Sharps** {{/rollTotal () edge 4 }}             {{#rollTotal () edge 5 }} **Teeth** {{/rollTotal () edge 5 }}             {{#rollTotal () edge 6 }} **Tides** {{/rollTotal () edge 6 }}             {{#rollTotal () edge 7 }} **Veils** {{/rollTotal () edge 7 }} **(+1d6)** </ div >         {{/rollGreater () edge 0 }}                 {{#rollGreater () cut 0 }}         < div class= "sheet-key" > Cut </ div >         < div class= "sheet-value" > **-** {{ cut }} </ div >         {{/rollGreater () cut 0 }}                 < div class= "sheet-key" > Rolled </ div >         < div class= "sheet-value" > {{ computed ::ability }} **=** {{ computed ::roll }} </ div >                 {{#rollGreater () computed::twist 0 }}         < div class= "sheet-key" > Twist </ div >         < div class= "sheet-value" ></ div >         {{/rollGreater () computed::twist 0 }}                 {{#allprops () title subtitle desc color edge advantage cut roll twist ability }}         < div class= "sheet-key" > {{ key }} </ div >         < div class= "sheet-value" > {{ value }} </ div >         {{/allprops () title subtitle desc color edge advantage cut roll twist ability }}         {{#desc}} < div class= "sheet-desc" > {{ desc }} </ div > {{/desc}}       </ div >     </ div >   </ rolltemplate > Most of the sheet worker is the aforementioned Jakob's Better Rolltemplate, with some tweaks to accept the sheet worker output. Finally the sheet worker where the magic happens, inside its own script block. There two sheet workers here. The first populates the hidden input for each stat. The second does the actual roll. There's exactly one thing you have to change in this code, and I'll explain that after: < script type = "text/worker" >     /* this function uses a complex rolltemplate; every element can be displayed in the output         several items have information in the .computed element:         ability: the full set of starting dice are stored here         cut: the dice after some are cute are stored here         roll: the sum of the rolled and kept dice         twist: whether there is a twist value.     */     const roll_buttons = {         brace_button: "brace" ,         fist_button: "fist"     };     on ( "sheet:opened change:character_name" , function ( eventInfo ) {         getAttrs ([ "character_name" , ... Object . keys ( roll_buttons )], function ( v ) {             var attrsToChange = {};             Object . keys ( roll_buttons ). forEach ( button => {                 const stat = roll_buttons [ button ];                 attrsToChange [ stat + "_stat" ] = "%{" + v [ "character_name" ] + "|" + stat + "_button}" ;             });                         setAttrs ( attrsToChange );         });     });     Object . keys ( roll_buttons ). forEach ( function ( button ) {         on ( `clicked: ${ button } ` , () => {             let stat = roll_buttons [ button ];             let rolltext = `&{template:custom} {{title=@{character_name} makes a ${ stat [ 0 ]. toUpperCase ()+ stat . substring ( 1 ) } roll}} {{edge=[[?{Edge?|None,0|Grace,1|Iron,2|Instinct,3|Sharps,4|Teeth,5|Tides,6|Veils,7}]]}} {{ability=[[@{ ${ stat } }]]}} {{advantage=[[?{Advantage? (up to 2d6)|0|1|2} ]]}} {{cut=[[?{Cut?|0}]]}} {{roll=[[ @{ ${ stat } }d6 +[[{?{Edge?},1}dh1]]d6 +  ?{Advantage? (up to 2d6)}d6 ]]}} {{twist=[[0]]}}` ;             startRoll ( rolltext , ( output ) => {                 let dice_all = output . results . roll . rolls . reduce (( all , one ) => [... all , ... one . results ],[]). sort ();                 let cut = output . results . cut . result ;                                 dice_all . length = Math . max ( 0 , dice_all . length - cut );                 let uniqueDice = [... new Set ( dice_all )]                 let twist = ( dice_all . length === uniqueDice . length ) ? 0 : 1 ;                 let dice_ability =   output . results . roll . dice . sort ();                 let score = dice_all [ dice_all . length - 1 ] || 0 ;                                 let rollData = {};                 rollData . ability = dice_ability ,                 rollData . cut = dice_all ,                 rollData . roll = score ,                 rollData . twist = twist                 finishRoll ( output . rollId , rollData );             });         });     });     </ script > The only part of this that needs changing is this section: const roll_buttons = {         brace_button: "brace" ,         fist_button: "fist"     }; You need to add a line for each stat, with the name of the button (fist_button:) followed by the name fothe attribute). So most of this code can be used as is, I'll make another post describing exactly what you need to change for simplicity.
1670455829

Edited 1670559811
GiGs
Pro
Sheet Author
API Scripter
So, to make it easier to use the above code, here is a gist link which contains the complete html and css: <a href="https://gist.github.com/birdbrainiac/db507457c62095a781e0707135d76d5d" rel="nofollow">https://gist.github.com/birdbrainiac/db507457c62095a781e0707135d76d5d</a> You can use it all exactly as it is. Except, each stat needs some specific html, and for those stats you need to make one tweak to the sheet workers. The HTML for the stats must include: An Input showing the stat's current value, and setting the stat name A visible button, which the user clicks to trigger theroll - you can display this however you like, as long as its value is as shown. A hidden input: this will hold the actual text of the roll, and that is created by a sheet worker, so value="" is fine. A hidden action button, which the roll button above actually triggers. So the visible button's value must be "=%{this-button's-name} This could look like: &nbsp; &nbsp; &lt; span &gt; Fist: &lt;/ span &gt; &nbsp; &nbsp; &lt; input type = "number" name = "attr_fist" value = "2" &gt; &nbsp; &nbsp; &lt; button type = "roll" name = "roll_fist" value = "@{fist_stat}" &gt; Roll &lt;/ button &gt; &nbsp; &nbsp; &lt; input type = "hidden" name = "attr_fist_stat" value = "" &gt; &nbsp; &nbsp; &lt; button type = "action" name = "act_fist_button" class = "hidden" &gt; Fist &lt;/ button &gt; This has a span to set the visible label of the button. Note how everything is named. The stat is called fist, and the name of everything else is based on that. The only things you have to set are the attribute name (first input), and the names of each element and the value of the first button. Laying these out should be easy since two of the elements are hidden. Then in the sheet worker you have this bit: const roll_buttons = { &nbsp; fist_button: "fist" }; Notice how the names for each section (fist_button: "fist" ) are taken from the html above. Just put a comma between each entry if there are multiple stats. And there you are. Whew, that is why Custom Roll parsing solutions are pretty rare - you have to set up the base HTML, a roll template, and at least a sheet worker using the CRP which itself is not straightforward. I hope you can use this - as I say, most of the code can be just dropped into your sheet unchanged, it's only the code in this post that needs changes and those changes are straightforward. Have fun!
Thank you thank you thank you! I will work on getting this into my sheet over the weekend.
1670559771
GiGs
Pro
Sheet Author
API Scripter
Good luck! If you have any questions or problems setting it up, ask away.