
D20Plugin
Implements a highly configurable D20 automation rulesetDetails
D20 Plugin
This unofficial TaleSpire plugin implements a highly customizable D20 ruleset automation including:
-
Skill checks
-
Opposed skill checks
-
Attacks
-
Damage
-
Healing
Using a distributed system where players only need character sheets for Instigators (PCs taking the action) as long as someone else (such as the GM) has character sheets for the enemies. This means the GM can easily add monster sheets to the game without having to send the sheets to all the players.
Addition features include:
-
Common sheet for multiple instances of a monster (e.g. Goblin1, Goblin2 and so on can all use a single sheet)
-
Multiple Instigator actions (for GM)
-
Multiple Targets actions (for PC)
-
Rolling with advantage or disadvantage
This plugin, like all others, is free but if you want to donate, use: http://LordAshes.ca/TalespireDonate/Donate.php
Install
Use R2ModMan or similar installer to install this plugin.
Note: Shortcut key can be configured in the R2ModMan config for the plugin.
Configuration
Two sample character sheets are provided for reference: Mink and Goblin.
You need a character sheet for each mini, that will use the plugin, in the game. PC sheets should be placed on the PC devices while NPC and monster sheets can be anywhere (typically GMs device). The character sheet files need to be named:
org.lordashes.plugins.5e.character.#.json
Where # is the mini name (without any trailing integer numbers). For example, "Goblin" not "Goblin01".
The message scripts used to narrate what is happening are contained in:
org.lordashes.plugins.5e.scripts.json
Each scenario has multiple messages, one for the gm, one for the instigator (person performing the action), possibly one for the target (for opposed actions), and one for others (all players not gm, instigator or target). Each of these messages can use a number of different place holders to fill in information to make the final messages. Available place holders are:
instigatorName: Name of the instigator (e.g. Mink)
targetName: Name of the target for opposed actions (e.g. Goblin)
name: Name of action (e.g. Stealth)
formula: The roll or value without any dice rolled or place holders replaced (e.g. 1D20+[WIS]+[PB]``)
roll: The roll or value with its place holders replaced but dice not rolled (e.g. 1D20+3+2).
dice: The roll or value with its place holders replaced and dice rolled (e.g. 17+3+2).
total: The total of the roll or value (e.g. 22).
opposedName: Name of the opposing action (e.g. Perception). If more than one was possible this is the chosen one.
opposedFormula: The opposed roll or value with its place holders replaced but dice not rolled. This is not a typo. Unlike the original action, the opposing formula starts with its place holders already replaced so opposedFormula and opposedRoll show the same thing.
opposedRoll: The opposed roll or value with its place holders replaced but dice not rolled.
opposedDice: The opposed roll or value with its place holders replaced and dice rolled.
opposedTotal: The total of the opposed roll or value.
damageType: Type of damage (e.g. Slashing).
damageFormula: The roll or value damage formula without any dice rolled or place holders replaced.
damageRoll: The damage roll or value with its place holders replaced but dice not rolled.
damageDice: The damage roll or value with its place holders replaced and dice rolled.
damageTotal: The total of the damage roll or value before vunerability, resistance and immunity adjustment.
damageAdjusted: The total of the damage roll or value after vunerability, resistance and immunity adjustment.
damageAdjustor: Reason for adjustment. Regular (no adjustment), Immunity, Resistance, or Vulnerability.
targetOldHP: Target's old HP.
targetHP: Target's new HP.
targetMaxHP: Target's max HP.
targetState: Target state based on % of life: Unhurt, Scratched, Wounded, Bloodied, Critical, Dying.
The plugin has a few configurable parameters in the plugin configruation:
Toggle Menu: Keyboard binding to toggle the D20 UI menu. This can also be done from the Radial menu.
Reload Character Sheets: Keyboard binding to reload character sheets. Use this when non-exposed values need to be changed duing a session.
Max Reolution Nested Levels: This is the number of pass that the system makes to resolve place holders. For example, a value entry of 1D20+[WIS SAVE] requires 1 pass to resove [WIS_SAVE]. This might resolve to 1D20+[WIS]+[PB]. Another pass would be needed to resolve that to 1D20+3+2. Increase this number of your value entries consits of more levels before they are resolved.
Clear Select On Action: When a PC selects multiple targets for an action, this setting indicates if the selection is cleared after the action or if the selected targets remain selected.
Use Animations: When set to true, the minis generate attack emotes when successful and the target emotes when missed.
Hit Melee: The emote animation used when a creature executes a successful melee hit. Only applicable when Use Animations is true.
Hit Ranged: The emote animation used when a creature executes a successful ranged hit. Only applicable when Use Animations is true.
Miss Melee: The emote animation used when a creature executes a failed attack. Only applicable when Use Animations is true. Despite the name it is used for both melee and ranged attacks and is done by the target.
Conversion of Ruleset5E Plugin Characters To D20 Plugin
A conversion application is provides that takes a dnd5e file (such as the one used by Ruleset5e plugin) and converts it to the new D20 format. The converter does a best attempt at conversion and will usually generate a usable character but it may not be optimized. Similarly it will place entries into the Radial Menu based on the dnd5e location or a default location but the user may want to customize the location afterwards. As such the conversion application is more intended as a conversion starting point with possible manual refinement afterwards.
To use the conversion application, open a command prompt, and then type:
Convert_5E_D20.exe Keeshu_LV6.dnd5e Keeshu
Where Keeshu_LV6.dnd5e is replaced by the name of the dnd5e file (that should be placed in the same folder as the conversion application EXE) and Keeshu is the name to be used for the D20 character. This is the name that your mini needs to have to match the D20 file.
The conversion application can be found in the root of the plugin install folder.
Usage
Skill Check
-
Select the instigator (mini making the action).
-
Right click on the mini making it also the target.
-
Select the Action menu.
-
Select the desired skill from the menu. The location of skills is configurable. By default skills appear unders a Skills section.
Opposed Skill Check Or Attack
-
Select the instigator (mini making the action).
-
Right click on the opposing mini selecting it as the target.
-
Select the Action menu.
-
Select the desired opposed skill or attack from the menu.
Multiple Instigator Actions (GM Only)
-
Select one of the instigator (mini making the action). This is necessary to determine the menu that will appear.
-
Lasso all instigators including the selected one. This indicates the instigators that will be used in the action.
-
Right click on the opposing mini selecting it as the target.
-
Select the Action menu.
-
Select the desired opposed skill or attack from the menu.
Multiple Targets Actions (PC Only)
-
Select the instigator (mini making the action).
-
Click on each of the targets. The base ring of the target will light up when they are selected.
-
Right click on one of the opposing mini.
-
Select the Action menu.
-
Select the desired opposed skill or attack from the menu.
Multiple Targets Using Target Panel
-
Select the instigator (mini making the action).
-
Right click on one the instigator.
-
Select the Action menu.
-
Select the desired opposed skill or attack from the menu.
-
The targets panel will appear. Selected the desired targets.
-
Press the "Apply Targets" button.
Character Sheet Configuration
A character sheet is a JSON consisting of Spec objects.
Basic Value Entry
The minimum entry for a Spec object, for Character Sheet configuration, is:
{
"name": "#", "formula": "#", "extra": [ { "key": "type", "value": "value" } ], "menu": null
},
Where the first # is the name of the value and the second # is value. A value can be a numeric value (e.g. 35), a roll expression (e.g. 1D20+3+2+1D4) or a string (e.g. Bob). The { "key": "type", "value": "value" } portion tells the plugin that this is a basic value entry. The "menu": null tells the plugin that this item will not show up in the Radial menu. This type of an entry is ideal for defining constants that can be used in other entries.
Value Entry With UI Edit
If we want to be able to change the Value Entry at runtime using the UI menu then we add an addition entry into the extra section such as:
{
"name": "#", "formula": "#", "extra": [ { "key": "type", "value": "value" }, { "key": "edit", "value": "#" } ], "menu": null
}
The addition of the { "key": "edit", "value": "#" } tells the plugin that the value entry should appear in the UI menu and the value of # is the name shown in the UI. The UI name and the value entry name don't need to match and in most case they don't, allowing the name to be short but still provide a more detailed display name. For example:
{
"name": "ROLL", "formula": "", "extra": [ { "key": "type", "value": "value" }, { "key": "edit", "value": "Roll (A/D)" } ], "menu": null
}
Value Entry With Radial Roll
If we want to define a value entry that appears in the radial menu (i.e. an action) then we need to add a menu entry such as:
{
"name": "#", "formula": "#", "extra": [ { "key": "type", "value": "value" } ], "menu": "#"
}
The change to a vlaue in menu (as opposed to null) places the value entry into the radial menu for selecting as an action. The value of the menu # indicastes the full path of where the item will be located in the radial menu.
Example:
{
"name": "STR Save Roll", "formula": "1D20+[STR Save]", "extra": [ { "key": "type", "value": "save" } ], "menu": "/Saves/STR"
}
However, for value entries added to the radial menu, the type is changed from the basic value to one of ability, save, skill, attack, spell, damage or heal. This tells the plugin how that entry should be processed. In addition some of these entries require additional information in the extra section.
Skills
Regular skills do not need any additional information.
Example:
{
"name": "Acrobatics", "formula": "1D20[ROLL]+[DEX]+[GUIDE]+[SB]", "extra": [ { "key": "type", "value": "skill" } ], "menu": "/Skills/Acrobatics"
}
Opposed Skills
Opposed skill check require the definition of a opposed key.
Example:
{
"name": "Deception", "formula": "1D20[ROLL]+[CHA]+[GUIDE]+[SB]", "extra": [ { "key": "type", "value": "skill" }, { "key": "opposed", "value": "Insight" } ], "menu": "/Skills/Deception"
}
This can be a single opposed entry or a list:
Example:
{
"name": "Grapple", "formula": "1D20[ROLL]+[STR]+[PB]+[GUIDE]+[SB]", "extra": [ { "key": "type", "value": "skill" }, { "key": "opposed", "value": "Athletics,Acrobatics" } ], "menu": "/Skills/Grapple"
}
Attacks
Attacks require the definition of an opposed as well as either a damage key or an effect key (or both). The damage key value is a string representing an array of damage entries. The effect key value is a string representing an array of effect entries. These reference damage and effect value entries defined elsewhere in the character sheet.
Example:
{
"name": "Eldritch Blast", "formula": "1D20[ROLL]+[CHA]+[PB]+[BLESS]+[AB]",
"extra": [ { "key": "type", "value": "attack" },
{ "key": "opposed", "value": "AC" },
{ "key": "damage", "value": "[ 'Eldritch Blast Damage', 'Hex Damage' ]" }
{ "key": "effect", "value": "[ 'Eldritch Blast Push' ]" }
],
"menu": "/Spells/Cantrip/Eldritch Blast"
},
Adding the key half does 1/2 damage when the target saves. Note: Not usually used with AC opposed attacks since that would make the attack do half damage on a miss.
Damage
Damage entries requireuire an damageType key which indicates the keyword of the damage type which is used with immunities, resistances and vulnerabilities.
{
"name": "Eldritch Blast Damage", "formula": "1D10+[CHA]", "extra": [ { "key": "type", "value": "damage" }, { "key": "damageType", "value": "Force" } ], "menu": "/Spells/Cantrip/Eldritch Blast Damage"
},
Damage value entries can be added into the radial menu so that they can be rolled individually as well as from the attack.
Effect
Effect entries requireuire no addition entries. The formula is what is exposed as a parameter to be used in messages.
{
"name": "Eldritch Blast Push", "formula": "Traget is move back 10'", "extra": [ { "key": "type", "value": "effect" } ], "menu": null
},
Heal
Heal does not need any additional information.
Example:
{
"name": "Cure Wounds", "formula": "1D8+[LV]", "extra": [ { "key": "type", "value": "heal" } ], "menu": "/Spells/Level 1/Cure Wounds"
},
Making Toggles
A common desire is to be able to include or exclude bonuses. For example, the benefits of Bless Spell or Guidance Cantrip. Using a simple vlaue entry with a UI representation we can do something like:
{
"name": "GUIDE", "formula": "", "extra": [ { "key": "type", "value": "value" }, { "key": "edit", "value": "Guidance Cantip (0 or 1D4)" } ], "menu": null
}
and then
{
"name": "Acrobatics", "formula": "1D20[ROLL]+[DEX]+[GUIDE]", "extra": [ { "key": "type", "value": "skill" } ], "menu": "/Skills/Acrobatics"
}
Now the user can enter either 0 or 1D4 in the UI to add the effect of Guidance. However, this requires the user to actually type 0 or 1D4. A better way is to use the toggle feature. We can turn a value entry into a toggle simply by adding a toggle key such as:
{
"name": "GUIDE", "formula": "0", "extra": [ { "key": "type", "value": "value" }, { "key": "edit", "value": "Guidance Cantrip (GUIDE)" }, { "key": "toggle" } ], "menu": null
},
Now this entry will appear as a toggle button instead of a text box in the UI. Toggles always resolve to 0 or 1. We can use the fact that our formulas allow multiplication to then use this like:
{
"name": "Acrobatics", "formula": "1D20[ROLL]+[DEX]+[GUIDE]*1D4", "extra": [ { "key": "type", "value": "skill" } ], "menu": "/Skills/Acrobatics"
}
If the toggle is on (1) then the [GUIDE]*1D4 will become 1*1D4 and thus add the 1D4 for Guidance. If the toggle is off (0) then the [GUIDE]*1D4 will become 0*1D4 thus not adding the 1D4.
This works and you can absolutely configure it that way but it does look a little ugly when looking at the formula. We can address this by adding in one in-between layer, such as:
{
"name": "TOGGLE1", "formula": "0", "extra": [ { "key": "type", "value": "value" }, { "key": "edit", "value": "Guidance Cantrip (GUIDE)" }, { "key": "toggle" } ], "menu": null
},
{
"name": "GUIDE", "formula": "[TOGGLE1]*1D4", "extra": [ { "key": "type", "value": "value" } ], "menu": null
},
{
"name": "Acrobatics", "formula": "1D20[ROLL]+[DEX]+[GUIDE]", "extra": [ { "key": "type", "value": "skill" } ], "menu": "/Skills/Acrobatics"
}
Now our skill check only has a nice GUIDE in the formula but the in-between middle entry resolves that to the toggle values multiplied by the 1D4.
Forced Multiple Targets
Forced multiple targets selection can be activated by adding a targets key with a integer value greater than 0.
This will trigger a message indicating that the user needs to select the correct number of targets and allows the user to pick them off.
Private, Semi Private and Public Results
By default checks are public and thus the various messages (bubble and chat) are displayed for the GM, instigator, target and others as per the scripts file. However, it is possible to turn a check into a private or semi private check.
private: Only GM messages, as configured in the scripts file, are sent.
semiprivate: Only GM, instigator and target messages (but not other messages), as configured in the scripts file, are sent.
public: All receipient's messages, as configured in the scripts file, are sent.
A check can change its message publicity setting by including a message key in the extra section. The value of the key is private, semiprivate or public.
Reserved Value Entries
There are a few value entry that have special meaning for the plugin.
Critical Hits
Critial hits can be implemented using the CritOn and critFormula properties in the damage entry. If the 1D20 roll is equal to or more than then critOn value then the damage will be replaced by the critical formula instead. It should be noted that the critical formula is not an addition, it is a replacement. As such the critical formula should have both the base damage and any critical damage.
{ "name": "Longsword Damage", "formula": "1D8+[STR]", "extra": [ {"key": "type", "value": "damage"}, {"key": "damageType", "value": "Slashing"}, { "key": "critOn", "value": 20}, { "key": "critFormula", "value": "2D8+[STR]" } ], "menu": "/Attacks/Melee/Longsword Damage" },
Note: There is no support for confirmations and thus 3.5E critical hits still need to be done as two attack entries.
Reaction
The reaction toggle determines if the plugin stops to allow the character to take reactions.
{
"name": "Reaction", "formula": "0", "extra": [ { "key": "type", "value": "value" }, { "key": "edit", "value": "Reaction" }, { "key": "toggle" } ], "menu": null
}
This toggle value entry indicates if the plugin should stop to allow the character a reaction when the character is the target of an opposed skill check or attack.
If the toggle is set (1) then the plugin will cause, displaying a "Reaction Comeplete" button in the bottom left. Press this button to continue. This allows the character to use the UI to adjust any parameters as a reaction (e.g. toggle Shield Spell on).
Reaction now stops before opposing roll is made (for things like Shield Spell before AC is evaluated) and before damage process (for things like Evasion).
Immunites, Resistances, and Vulnerabilities
The value of the immunities, resistances and vulnerabilities value entries is a command delimited list of damage to to which the character has immunities, resistances, or vulnerabilities.
{
"name": "Resistances", "formula": "cold,fire", "extra": [ { "key": "type", "value": "value" } ], "menu": null
}
Chaining
Each attack (or opposed skill check) is allow to have only opposed operation. However, in some cases an attack needs more than one opposed check. For example, an attack that inficts damage on a hit but also has a chance of poison would need as second opposed check for the DC of the poison. For such attacks, the chain propeties can be used.
chainSuccess: Executes the indicated attack (or opposed skill check) if the previous opposed skill check was successful.
chainFailure: Executes the indicated attack (or opposed skill check) if the previous opposed skill check was unsuccessful.
chainAlways: Executes the indicated attack (or opposed skill check) regardless of the outcome of the previous opposed check.
The value of the property is the name of an attack or opposed skill check.
Value Entry Resolver & Dice Roller
When resolving a value entry, the plugin first replaces place holders - text surrounded by square brackets - with its current values. This is done repeatedly a number of times equal to the configured nested setting. This allows one place holder to resolve to more place holders such as WIS_SAVE_ROLL resolving to 1D20+[WIS_SAVE] which may resolves to 1D20+[WIS]+[PB] which may resolve to 1D20+3+2.
Then dice roll expressions (i.e. #D#) are resolved to their rolled values. Dice expressions can contained a training A or D to roll with advantage or disadvantage. This can easily be takedn advante of by adding in a value entry for this letter, making it available in the UI, and then appending it to roll such as: 1D20[ROLL]+[DEX]+[GUIDE]. Now if the ROLL value entry is empty, it will roll normally. If the ROLL value entry is A or D it will roll with advantage or disadvantage.
Lastly the expression is run though a calculator to compute the total. Operators supported are: +, -, * (multiplication) and / (floor division).
Limitation
- Only randomly generated dice rolls are supported at this time.
- Since the configruation of the message sets are local to each device, a player could modify them to gain more information that he/she should.
- Attacks always do damage. No support, yet, for attacks that inflict a condition instead.
- No current support for 1/2 on save success.