Character Vault
Any Concept / Any System
Compendium
Your System Come To Life
Roll20 for Android
Streamlined for your Tablet
Roll20 for iPad
Streamlined for your Tablet

Personal tools

Difference between revisions of "Custom Roll Parsing"

From Roll20 Wiki

Jump to: navigation, search
m
m (link to gigs CRP guide)
 
(30 intermediate revisions by 6 users not shown)
Line 1: Line 1:
{{revdate}}{{pro only}}''Main Article:'' '''[[Building Character Sheets]]'''
+
{{revdate}}{{BCS}}
  
 +
{{NavSheetDoc}}'''Custom Roll Parsing''' ('''CRP''') is a new capability for character sheets can now combine the functionality of [[Button#Roll_Button|roll buttons]] and [[Button#Action_Button|action buttons]] to allow for a new custom roll parsing. It was release July 13th, 2021.{{source|https://help.roll20.net/hc/en-us/articles/360037772613-Change-Log#july-13-2021-0-21}}
  
'''Custom Roll Parsing''' ('''CRP''') is a new capability for character sheets can now combine the functionality of [[Button#Roll_Button|roll buttons]] and [[Button#Action_Button|action buttons]] to allow for a new custom roll parsing. It was release July 13th, 2021.{{source|https://help.roll20.net/hc/en-us/articles/360037772613-Change-Log#july-13-2021-0-21}}
+
* '''[https://cybersphere.me/guide-to-custom-roll-parsing/ Guide To Custom Roll Parsing]''' by [[GiGs]]
{{NavSheetDoc}}
+
 
* {{fpl|10296045/ Oosh's explanation of CRP}}
 
* {{fpl|10296045/ Oosh's explanation of CRP}}
 
* {{hc|articles/4403865972503-Custom-Roll-Parsing-for-Character-Sheets Custom Roll Parsing for Character Sheets}}
 
* {{hc|articles/4403865972503-Custom-Roll-Parsing-for-Character-Sheets Custom Roll Parsing for Character Sheets}}
 
  
 
'''Parts'''
 
'''Parts'''
Line 13: Line 12:
 
* Changes to [[BCS/Roll Templates|Roll Templates]] to display the roll
 
* Changes to [[BCS/Roll Templates|Roll Templates]] to display the roll
  
Currently you can only display computed values in the '''first 10 fields''' that are sent in the macro.
 
  
{{ex}}
+
[[File:Custom_Roll_Parsing.gif|thumb|Example of CRP in use|left|800px]]
 +
 
 +
The functions <code>startRoll</code> and <code>finishRoll</code> will allow sheet authors to access dice rolls and compute their own results for those rolls
 +
<br><br>
 +
 
 +
==Sheetworker Functions==
 +
{{main|Sheetworkers}}
 +
 
 +
<pre style="overflow:auto;white-space:pre-wrap;" data-language="javascript">startRoll( roll, callback? ) (asynchronous)</pre>
 +
 
 +
This function accepts a roll as a string (generally a roll template string). The function will initiate a roll to the roll server, the results for which will be returned to the callback. The roll will wait for a corresponding <code>finishRoll</code> function call before posting the results to chat, however if the <code>finishRoll</code> call is not made within 5 seconds, the roll will be posted automatically. The results from the roll server will be an object containing the following properties
 +
 
 +
<pre style="overflow:auto;white-space:pre-wrap;" data-language="javascript">rollId: (string)</pre>
 +
 
 +
A unique identifier for this roll, required to finish the roll
 +
 
 +
<pre style="overflow:auto;white-space:pre-wrap;" data-language="javascript">results: (object)</pre>
 +
 
 +
An object containing the roll information from the roll server, where the keys are roll names and the values are an object containing the roll information, for example:
 +
 
 +
<pre style="overflow:auto;white-space:pre-wrap;" data-language="javascript">
 +
results: {
 +
  roll1: {
 +
      // The result of the roll, as calculated by the roll server
 +
      result: 48,
 +
      // An ordered array of the results of all dice in this roll
 +
      dice: [9,9,20,4,4,1],
 +
      // The original expression for this roll
 +
      expression: ‘4d20+2d4’,
 +
      // A breakdown of each “sub-roll” (each part of an expression is rolled separately)
 +
      rolls: [
 +
          {
 +
              // The ‘4’ in ‘4d20’
 +
              dice: 4,
 +
              // The ‘20’ in ‘4d20’
 +
              sides: 20,
 +
              // Array of the results of each die
 +
              results: [9,9,20,4]
 +
          },
 +
          …
 +
      ]
 +
  },
 +
  …
 +
}</pre>
 +
 
 +
<pre style="overflow:auto;white-space:pre-wrap;" data-language="javascript">finishRoll( rollId, computedResults? )</pre>
 +
 
 +
This function will finish a roll initiated with the <code>startRoll</code> function, and allow for adding computed results to each roll. The function requires the <code>rollId</code> from the <code>startRoll</code> function, and can accept an object, where the keys are roll names and the values are the computed results for that roll, as a string or an integer.
 +
 
 +
 
 +
==Roll Template Changes==
 +
{{main|BCS/Roll Templates}}
 +
 
 +
To use the custom computed results in your roll templates, replace the roll names in the template with <code><nowiki>computed::<rollname></nowiki></code>:
 +
 
 +
<pre style="overflow:auto;white-space:pre-wrap;" data-language="html"><rolltemplate class="sheet-rolltemplate-test">
 +
    <div class="sheet-template-container">
 +
        <h1>{{name}}</h1>
 +
        <div class="sheet-results">
 +
            <h4>Result = {{roll1}}</h4>
 +
            <h4>Custom Result = {{computed::roll1}}</h4>
 +
        </div>
 +
    </div>
 +
</rolltemplate></pre>
 +
 
 +
When the roll is output to the chat, hovering the mouse over a custom result will display the [[Quantum|quantum roll]] symbol, and the original results of each die.
 +
 
 +
In addition, the roll template functions <code>rollTotal</code>, <code>rollGreater</code>, <code>rollLess</code>, and <code>rollBetween</code> can use the computed result of a roll:
 +
 
 +
<pre style="overflow:auto;white-space:pre-wrap;" data-language="html"><rolltemplate class="sheet-rolltemplate-test2">
 +
    <div class="sheet-template-container">
 +
        <h1>{{name}}</h1>
 +
        <div class="sheet-results">
 +
            <h4>Result = {{roll1}}</h4>
 +
            <h4>Custom Result = {{computed::roll1}}</h4>
 +
            {{#rollTotal() computed::roll1 0}}
 +
                <h5>Total 0!</h5>
 +
            {{/rollTotal() computed::roll1 0}}
 +
            {{#rollGreater() computed::roll1 1}}
 +
                <h5>Greater Than 1!</h5>
 +
            {{/rollGreater() computed::roll1 1}}
 +
            {{#rollLess() computed::roll1 2}}
 +
                <h5>Less Than 2</h5>
 +
            {{/rollLess() computed::roll1 2}}
 +
            {{#rollBetween() computed::roll1 1 3}}
 +
                <h5>Between 1 and 3</h5>
 +
            {{/rollBetween() computed::roll1 1 3}}
 +
        </div>
 +
    </div>
 +
</rolltemplate></pre>
 +
 
 +
Note that these roll template functions generally expect an integer value to compare, and attempting to use them to compare string values may not not work as expected.
 +
 
 +
==Limitations==
 +
* Computed roll functions([[CRP]] ) can now handle more than 10 rolls.{{source|https://app.roll20.net/forum/permalink/10507621/ Nov 18th}}
 +
* Computed values cannot be used as comparisons in roll template helpers
 +
* Only template properties that are rolls (i.e wrapped with {{c|[[ ]]}}) will be available in the results object.  [[Attributes]] containing text only and passed as a roll can cause the startRoll to fail.
 +
 
 +
==Example==
 +
Bringing all of these new elements together, here is an example of implementing this feature:
 
<pre style="overflow:auto;white-space:pre-wrap;" data-language="html">
 
<pre style="overflow:auto;white-space:pre-wrap;" data-language="html">
 
<button type="action" name="act_test">Click me</button>
 
<button type="action" name="act_test">Click me</button>
Line 44: Line 141:
 
     });
 
     });
 
</script></pre>
 
</script></pre>
 +
 +
===More Examples===
 +
# Using Custom Roll Parsing to pass data from one roll to another via action buttons inserted into roll templates using the originalRollId property. https://app.roll20.net/forum/permalink/10346884/
 +
# Make three dice appear in the roll template using a single roll. https://app.roll20.net/forum/permalink/11735213/
 +
 +
== Hints &amp; Tricks ==
 +
=== Roll Buttons with Custom Roll Parsing ===
 +
CRP requires action buttons, but action buttons cannot be dragged into the macro bar. This means that one cannot simply ''upgrade'' existing roll buttons to action buttons, because that would break the rolls players have dragged into their macro bars. The issue is as follows:
 +
 +
* [[Button#Roll_Button|Roll buttons]] can call abilities.
 +
* Action buttons provide abilities.
 +
* Ability calls require the character name (or target or selected).
 +
* [[Sheetworkers|Sheet worker scripts]] can help with getting the character name and generate the ability call.
 +
 +
In order to still achieve this, in its simplest form the following is required for a character named 'Roller' and a button for an athletics check:
 +
<pre data-language="html">
 +
<!-- The visible and draggable button for the macro bar -->
 +
<button type="roll" name="roll_athletics" value="%{Roller|athletics-action}">Athletics</button>
 +
 +
<!-- The invisible button allowing the use of custom roll parsing -->
 +
<button type="action" name="act_athletics-action" class="hidden"></button>
 +
</pre>
 +
 +
This would only work for characters with the exact same name, Roller. In order to fix this, we need to do two things: The roll button value gets replaced with an attribute call that is saved in a hidden input field:
 +
<pre data-language="html">
 +
<!-- The visible and draggable button for the macro bar -->
 +
<button type="roll" name="roll_athletics" value="@{athletics_action}">Athletics</button>
 +
 +
<!-- The invisible button allowing the use of custom roll parsing -->
 +
<button type="action" name="act_athletics-action" class="hidden"></button>
 +
 +
<!-- The invisible field for the attribute which contains the ability call -->
 +
<input type="hidden" name="attr_athletics_action" value="%{Roller|athletics-action}">
 +
</pre>
 +
 +
Then, the attribute must be generated using a sheet worker script which generates the correct ability call. To ensure that this works, the attribute must be set each time the character sheet is opened and when the character name changes. In this example, only a short version for easier comprehension is used:
 +
<pre data-language="html">
 +
<!-- The visible and draggable button for the macro bar -->
 +
<button type="roll" name="roll_athletics" value="@{athletics_action}">Athletics</button>
 +
 +
<!-- The invisible button allowing the use of custom roll parsing -->
 +
<button type="action" name="act_athletics-action" class="hidden"></button>
 +
 +
<!-- The invisible field for the attribute which contains the ability call -->
 +
<input type="hidden" name="attr_athletics_action" value="">
 +
 +
[...]
 +
<script type="text/worker">
 +
on("sheet:opened change:character_name", function(eventInfo) {
 +
getAttrs(["character_name", "athletics_action"], function(v) {
 +
var attrsToChange = {};
 +
attrsToChange["athletics_action"] = "%{" + v["character_name"] + "|athletics-action}";
 +
setAttrs(attrsToChange);
 +
});
 +
});
 +
</script>
 +
</pre>
 +
See the [https://app.roll20.net/forum/post/10534166/action-buttons-in-the-macro-bar corresponding forum thread] for a more thorough sheet worker script taking into account many different attributes and also [[BCS/Repeating Section|repeating sections]].
 +
 +
===Sheets using CRP===
 +
{{notebox|List very incomplete, there are tons of sheets using CRP [[User:1223200|1223200]] ([[User talk:1223200|talk]]) 15:51, 28 March 2022 (UTC)}}
 +
Character sheets using Custom Roll Parsing:
 +
* [https://github.com/Roll20/roll20-character-sheets/tree/master/Ratten Ratten] short & simple
 +
* [https://github.com/Roll20/roll20-character-sheets/tree/master/Supers-Revised-Edition Supers Revised Edition] fairly short
 +
* [https://github.com/Roll20/roll20-character-sheets/pull/9658 Agone v0.9]
 +
* [https://github.com/Roll20/roll20-character-sheets/tree/master/Shadowrun%20Sixth%20World Shadowrun Sixth World]
 +
* [https://github.com/Roll20/roll20-character-sheets/tree/master/TheWitcher TheWitcher]
 +
* [https://github.com/Roll20/roll20-character-sheets/tree/master/Twilight-2000-v2.2 Twilight-2000-v2.2]
 +
* [https://github.com/Roll20/roll20-character-sheets/tree/master/WarlockOSR WarlockOSR]
 +
* [https://github.com/Roll20/roll20-character-sheets/tree/master/HeroSystem6eHeroic HeroSystem6eHeroic]
 +
* [https://github.com/Roll20/roll20-character-sheets/tree/master/Knight Knight]
  
 
==Forum threads==
 
==Forum threads==
 +
* [https://app.roll20.net/forum/permalink/10741566/ Custom Sheet javascript determine Dice Roll based on...] - March 2022
 +
* [https://app.roll20.net/forum/permalink/10715873/ Roll Template Tomfoolery] - Feb 2022
 +
* [https://app.roll20.net/forum/post/10681305/rolling-higher-than-and-lower-than-simultaneously#post-10685647 Rolling higher-than and lower-than simultaneously] - Feb 2022
 +
* [https://app.roll20.net/forum/permalink/10449796/ Storing a query value in an Attribute]
 
* {{fpl|10346883/ Adventures with startRoll()}} Aug, 2021 by [[Oosh]]
 
* {{fpl|10346883/ Adventures with startRoll()}} Aug, 2021 by [[Oosh]]
 
** long discussion with many details
 
** long discussion with many details
* {{fpl|10315923/ Custom Roll Parsing - Separating groups of dice by type}}
+
* {{fpl|10315923/ Custom Roll Parsing - Separating groups of dice by type}} Aug. 2021
* {{fpl|10198082/now-on-dev-server-custom-roll-parsing-for-character-sheets Now on Dev Server: Custom Roll Parsing for Character Sheets}} - old thread back when this was on [[Dev Server]] for testing
+
* [https://app.roll20.net/forum/permalink/10503310/ (custom roll parsing) changing what the hover shows] - Nov. 2021
 +
* [https://app.roll20.net/forum/permalink/10198082/ Now on Dev Server: Custom Roll Parsing for Character Sheets] - old thread back when this was on [[Dev Server]] for testing
 +
* [https://app.roll20.net/forum/post/10534166/action-buttons-in-the-macro-bar Action Buttons in the Macro Bar] Dec. 2021
  
 
==See Also==
 
==See Also==
Line 56: Line 230:
 
[[Category:Sheetworker]]
 
[[Category:Sheetworker]]
 
[[Category:Character Sheet Creation]]
 
[[Category:Character Sheet Creation]]
 +
[[Category:New features in 2021]]

Latest revision as of 14:28, 3 May 2024

Custom Roll Parsing (CRP) is a new capability for character sheets can now combine the functionality of roll buttons and action buttons to allow for a new custom roll parsing. It was release July 13th, 2021.

Parts


Example of CRP in use

The functions startRoll and finishRoll will allow sheet authors to access dice rolls and compute their own results for those rolls

Contents

[edit] Sheetworker Functions

Main Page: Sheetworkers

startRoll( roll, callback? ) (asynchronous)

This function accepts a roll as a string (generally a roll template string). The function will initiate a roll to the roll server, the results for which will be returned to the callback. The roll will wait for a corresponding finishRoll function call before posting the results to chat, however if the finishRoll call is not made within 5 seconds, the roll will be posted automatically. The results from the roll server will be an object containing the following properties

rollId: (string)

A unique identifier for this roll, required to finish the roll

results: (object)

An object containing the roll information from the roll server, where the keys are roll names and the values are an object containing the roll information, for example:

results: {
  roll1: {
      // The result of the roll, as calculated by the roll server
      result: 48,
      // An ordered array of the results of all dice in this roll
      dice: [9,9,20,4,4,1],
      // The original expression for this roll
      expression: ‘4d20+2d4’,
      // A breakdown of each “sub-roll” (each part of an expression is rolled separately)
      rolls: [
          {
              // The ‘4’ in ‘4d20’
              dice: 4,
              // The ‘20’ in ‘4d20’
              sides: 20,
              // Array of the results of each die
              results: [9,9,20,4]
          },
          …
      ]
  },
  …
}
finishRoll( rollId, computedResults? )

This function will finish a roll initiated with the startRoll function, and allow for adding computed results to each roll. The function requires the rollId from the startRoll function, and can accept an object, where the keys are roll names and the values are the computed results for that roll, as a string or an integer.


[edit] Roll Template Changes

Main Page: BCS/Roll Templates

To use the custom computed results in your roll templates, replace the roll names in the template with computed::<rollname>:

<rolltemplate class="sheet-rolltemplate-test">
    <div class="sheet-template-container">
        <h1>{{name}}</h1>
        <div class="sheet-results">
            <h4>Result = {{roll1}}</h4>
            <h4>Custom Result = {{computed::roll1}}</h4>
        </div>
    </div>
</rolltemplate>

When the roll is output to the chat, hovering the mouse over a custom result will display the quantum roll symbol, and the original results of each die.

In addition, the roll template functions rollTotal, rollGreater, rollLess, and rollBetween can use the computed result of a roll:

<rolltemplate class="sheet-rolltemplate-test2">
    <div class="sheet-template-container">
        <h1>{{name}}</h1>
        <div class="sheet-results">
            <h4>Result = {{roll1}}</h4>
            <h4>Custom Result = {{computed::roll1}}</h4>
            {{#rollTotal() computed::roll1 0}}
                <h5>Total 0!</h5>
            {{/rollTotal() computed::roll1 0}}
            {{#rollGreater() computed::roll1 1}}
                <h5>Greater Than 1!</h5>
            {{/rollGreater() computed::roll1 1}}
            {{#rollLess() computed::roll1 2}}
                <h5>Less Than 2</h5>
            {{/rollLess() computed::roll1 2}}
            {{#rollBetween() computed::roll1 1 3}}
                <h5>Between 1 and 3</h5>
            {{/rollBetween() computed::roll1 1 3}}
        </div>
    </div>
</rolltemplate>

Note that these roll template functions generally expect an integer value to compare, and attempting to use them to compare string values may not not work as expected.

[edit] Limitations

  • Computed roll functions(CRP ) can now handle more than 10 rolls.
  • Computed values cannot be used as comparisons in roll template helpers
  • Only template properties that are rolls (i.e wrapped with [[ ]]) will be available in the results object. Attributes containing text only and passed as a roll can cause the startRoll to fail.

[edit] Example

Bringing all of these new elements together, here is an example of implementing this feature:

<button type="action" name="act_test">Click me</button>

<rolltemplate class="sheet-rolltemplate-test">
    <div class="sheet-template-container">
        <h1>{{name}}</h1>
        <div class="sheet-results">
            <h4>Result = {{roll1}}</h4>
            <h4>Custom Result = {{computed::roll1}}</h4>
        </div>
    </div>
</rolltemplate>

<script type="text/worker">
    on('clicked:test', (info) => {
        startRoll("&{template:test} {{name=Test}} {{roll1=[[1d20]]}}", (results) => {
            const total = results.results.roll1.result
            const computed = total % 4;

            finishRoll(
                results.rollId,
                {
                    roll1: computed
                }
            );
        });
    });
</script>

[edit] More Examples

  1. Using Custom Roll Parsing to pass data from one roll to another via action buttons inserted into roll templates using the originalRollId property. https://app.roll20.net/forum/permalink/10346884/
  2. Make three dice appear in the roll template using a single roll. https://app.roll20.net/forum/permalink/11735213/

[edit] Hints & Tricks

[edit] Roll Buttons with Custom Roll Parsing

CRP requires action buttons, but action buttons cannot be dragged into the macro bar. This means that one cannot simply upgrade existing roll buttons to action buttons, because that would break the rolls players have dragged into their macro bars. The issue is as follows:

  • Roll buttons can call abilities.
  • Action buttons provide abilities.
  • Ability calls require the character name (or target or selected).
  • Sheet worker scripts can help with getting the character name and generate the ability call.

In order to still achieve this, in its simplest form the following is required for a character named 'Roller' and a button for an athletics check:

<!-- The visible and draggable button for the macro bar -->
<button type="roll" name="roll_athletics" value="%{Roller|athletics-action}">Athletics</button>

<!-- The invisible button allowing the use of custom roll parsing -->
<button type="action" name="act_athletics-action" class="hidden"></button>

This would only work for characters with the exact same name, Roller. In order to fix this, we need to do two things: The roll button value gets replaced with an attribute call that is saved in a hidden input field:

<!-- The visible and draggable button for the macro bar -->
<button type="roll" name="roll_athletics" value="@{athletics_action}">Athletics</button>

<!-- The invisible button allowing the use of custom roll parsing -->
<button type="action" name="act_athletics-action" class="hidden"></button>

<!-- The invisible field for the attribute which contains the ability call -->
<input type="hidden" name="attr_athletics_action" value="%{Roller|athletics-action}">

Then, the attribute must be generated using a sheet worker script which generates the correct ability call. To ensure that this works, the attribute must be set each time the character sheet is opened and when the character name changes. In this example, only a short version for easier comprehension is used:

<!-- The visible and draggable button for the macro bar -->
<button type="roll" name="roll_athletics" value="@{athletics_action}">Athletics</button>

<!-- The invisible button allowing the use of custom roll parsing -->
<button type="action" name="act_athletics-action" class="hidden"></button>

<!-- The invisible field for the attribute which contains the ability call -->
<input type="hidden" name="attr_athletics_action" value="">

[...]
<script type="text/worker">
on("sheet:opened change:character_name", function(eventInfo) {
	getAttrs(["character_name", "athletics_action"], function(v) {
		var attrsToChange = {};
		attrsToChange["athletics_action"] = "%{" + v["character_name"] + "|athletics-action}";
		setAttrs(attrsToChange);
	});
});
</script>

See the corresponding forum thread for a more thorough sheet worker script taking into account many different attributes and also repeating sections.

[edit] Sheets using CRP

Character sheets using Custom Roll Parsing:

[edit] Forum threads

[edit] See Also