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

[Script]Menu Maker

1558757082

Edited 1570562233
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Chat menus are a great way to select actions from a sheet without having to open the sheet itself, but manually made ones are a pain to keep up to date if you want to include references to repeating sections (ie a spell list chat menu), and not all sheets have this quality of life feature. About a week ago GiGs and I both had the same idea to address this through a script. GiGs' Pathfinder Actions Chat Menu Generator and the follow up Universal Chat Menus scripts are excellent solutions to the problem, but since I wanted to finish my attempt at a solution, here's: Menu Maker v0.02 Welcome to Menu Maker. This script helps create dynamic chat button menus for character sheets that don't have an integrated chat menu system. Below are the instructions for the two types of dynamic macros that the script can create and maintain. Chat Menus Create templates of the menus you want to create as abilities on the  attributes & abilities  tab of this character. Templates are created using the same syntax as normal Roll20 macros with the addition of some syntax to denote where repeating items should be added. An area that is supposed to dynamically update with repeating item calls is bracketed with the following: [section:"sectionName"...] ... [/section] Inside the starting section declaration, you can also give options to control which repeating items should be included. The options in the order they should be added are: section: This is required and tells the script which repeating section to pull row ids from. The section name is bracketed with quotation marks and a colon separates the section keyword from the section name. attrany: This acts as a boolean to tell the script whether all, or just some, of the attrFilters (see below) need to be found. attrFilters: A semicolon separated list of non repeating attribute names and regex to test them with. The attribute name and the regex are separated by a colon (:), and the regex is bracketed with forward slashed (/). repeatany: Functions like attrany, but controls the behavior of the repeatFilters matching. repeatFilters: Functions as attrFilters, but for repeating attributes. Only the attribute name should be used, not the row's ID or section. An example declaration using all of these is: [section:"attack" attrany attrFilters=spellcasting_ability:/_mod/ repeatany repeatFilters=atkrange:/^$/] This will look pull repeating items from the attack section, but only if the character's spellcasting_ability attribute contains the string _mod in it. It will also only inject ids for repeating items that have an empty atkrange attribute (repeating_attack_$X_atkrange). Additionally you can denote headers and footers that will be added to the beginning or end (respectively) of the section. These are denoted by bracketing the header or footer text with the following: [header] ... [/header] [footer] ... [/footer] Below is a complete template showing all of these features. The attribute names used are from the 5e by Roll20 character sheet. &{template:default} {{name=Attacks for @{character_name}}} [section:"attack" repeatFilters=atkrange:/^$/] [header]{{Melee}} {{[/header][@{repeating_attack_$X_atkname}](~@{character_name}|repeating_attack_$X_attack)[footer]}} [/footer] [/section][section:"attack" attrFilters=spellcasting_ability:/_mod/ repeatFilters=atkrange:/^$/] [header]{{Spells}} {{=[/header][@{repeating_attack_$X_atkname}](~@{character_name}|repeating_attack_$X_attack)[footer]}} [/footer] [/section] Custom Repeating Abilities The script can also create custom abilities for repeating sections. Simply name the template in the format  SECTION _$X_ ROLLNAME . The ROLLNAME must be a unique name that is not used elsewhere on the sheet. Custom repeating abilities can only reference non repeating attributes or attributes in a single repeating item. Menu Maker will work with any character sheet, because you define what the menu should look like and what attributes should be called where. The script uses an interactive bio/info page of a character sheet that the script creates to handle configuring how the sheet runs and how templates should be applied. This looks like this: GIF link I was going to design some in depth template macros to show off what you can do with this script, but I was lucky enough to have a dedicated Alpha tester in Keith Curtis who has been kind enough to volunteer to share the templates he made to work with the 5e OGL sheet. You'll be able to find them in the first response . The script's code can be found in this gist .
1558757753

Edited 1558758897
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
I've been working with Scott on this for a few days, him doing awesome magic stuff, and me doing my best to break it. Here's what I've come up with for the 5e OGL sheet by Roll20. All of my  menus use a Stylus tweak  to turn the big pink buttons into inline links. This is a statblock for PCs: And the code: /w gm &{template:npcaction} {{rname=@{character_name}}} {{description=* @{selected|class_display}* **STR @{selected|strength}** *(@{selected|strength_mod})* | [roll](~selected|strength) | [save](~selected|strength_save) **DEX @{selected|strength}** *(@{selected|dexterity_mod})* | [roll](~selected|dexterity) | [save](~selected|dexterity_save) **CON @{selected|constitution}** *(@{selected|constitution_mod})* | [roll](~selected|constitution) | [save](~selected|constitution_save) **INT  @{selected|intelligence}** *(@{selected|intelligence_mod})* | [roll](~selected|intelligence) | [save](~selected|intelligence_save) **WIS @{selected|wisdom}** *(@{selected|wisdom_mod})* | [roll](~selected|wisdom) | [save](~selected|wisdom_save) **CHA @{selected|charisma}** *(@{selected|charisma_mod})* | [roll](~selected|charisma) | [save](~selected|charisma_save) SKILLS [Acrobatics](~selected|acrobatics) | [Animal Handling](~selected|animal_handling) [Arcana](~selected|arcana) | [Athletics](~selected|athletics) | [Deception](~selected|deception) [History](~selected|history) | [Insight](~selected|insight) | [Intimidation](~selected|intimidation) [Investigation](~selected|investigation) | [Medicine](~selected|medicine) | [Nature](~selected|nature) [Perception](~selected|perception) | [Performance](~selected|performance) [Persuasion](~selected|persuasion) | [Religion](~selected|religion) [Sleight of Hand](~selected|sleight_of_hand) | [Steath](~selected|stealth) | [Survival](~selected|survival) [section:"traits" repeatany repeatFilters=name:/./] [header]TRAITS AND FEATURES [/header][@{repeating_traits_$X_name}](~repeating_traits_$X_trait) | [footer] [/footer] [/section] COMBAT  [section:"attack" repeatFilters=atkrange:/^$/] [header]Melee [/header][@{repeating_attack_$X_atkname}](~@{character_name}|repeating_attack_$X_attack) | [footer] [/footer] [/section][section:"attack" repeatFilters=atkrange:////] [header]Ranged [/header][@{repeating_attack_$X_atkname}](~@{character_name}|repeating_attack_$X_attack) | [footer] [/footer] [/section][section:"attack" repeatFilters=atkattr_base:/spell/] [header]Spells [/header][@{repeating_attack_$X_atkname}](~@{character_name}|repeating_attack_$X_attack) | [footer] [/footer] [/section] **[Spellcasting](~Spells-Available)** }} Clicking on the Spellcasting link at the bottom of the template brings up this: Here is the code: Edited. updated version shows only prepared spells. /w gm &{template:npcaction} {{rname=Spells for @{character_name}}} {{description=[section:"spell-cantrip" repeatFilters=name:/./] [header]Cantrips [/header][@{repeating_spell-cantrip_$X_spellname}](~repeating_spell-cantrip_$X_spell) | [footer] [/footer] [/section][section:"spell-1" repeatFilters=name:/./;spellprepared:/1/] [header]Level One *(@{selected|lvl1_slots_expended}/@{selected|lvl1_slots_total})* [/header][@{repeating_spell-1_$X_spellname}](~repeating_spell-1_$X_spell) | [footer] [/footer] [/section][section:"spell-2" repeatFilters=name:/./;spellprepared:/1/] [header]Level Two *(@{selected|lvl2_slots_expended}/@{selected|lvl2_slots_total})* [/header][@{repeating_spell-2_$X_spellname}](~repeating_spell-2_$X_spell) | [footer] [/footer] [/section][section:"spell-3" repeatFilters=name:/./;spellprepared:/1/] [header]Level Three *(@{selected|lvl3_slots_expended}/@{selected|lvl3_slots_total})* [/header][@{repeating_spell-3_$X_spellname}](~repeating_spell-3_$X_spell) | [footer] [/footer] [/section][section:"spell-4" repeatFilters=name:/./;spellprepared:/1/] [header]Level Four *(@{selected|lvl4_slots_expended}/@{selected|lvl4_slots_total})* [/header][@{repeating_spell-4_$X_spellname}](~repeating_spell-4_$X_spell) | [footer] [/footer] [/section][section:"spell-5" repeatFilters=name:/./;spellprepared:/1/] [header]Level Five *(@{selected|lvl5_slots_expended}/@{selected|lvl5_slots_total})* [/header][@{repeating_spell-5_$X_spellname}](~repeating_spell-5_$X_spell) | [footer] [/footer] [/section][section:"spell-6" repeatFilters=name:/./;spellprepared:/1/] [header]Level Six *(@{selected|lvl6_slots_expended}/@{selected|lvl6_slots_total})* [/header][@{repeating_spell-6_$X_spellname}](~repeating_spell-6_$X_spell) | [footer] [/footer] [/section][section:"spell-7" repeatFilters=name:/./;spellprepared:/1/] [header]Level Seven *(@{selected|lvl7_slots_expended}/@{selected|lvl7_slots_total})* [/header][@{repeating_spell-7_$X_spellname}](~repeating_spell-7_$X_spell) | [footer] [/footer] [/section][section:"spell-8" repeatFilters=name:/./;spellprepared:/1/] [header]Level Eight *(@{selected|lvl8_slots_expended}/@{selected|lvl8_slots_total})* [/header][@{repeating_spell-8_$X_spellname}](~repeating_spell-8_$X_spell) | [footer] [/footer] [/section][section:"spell-9" repeatFilters=name:/./;spellprepared:/1/] [header]Level Nine *(@{selected|lvl9_slots_expended}/@{selected|lvl9_slots_total})* [/header][@{repeating_spell-9_$X_spellname}](~repeating_spell-9_$X_spell) | [footer] [/footer] [/section]}} Here is a statblock for NPCs And the code: /w gm &{template:npcaction} {{rname=@{character_name}}} {{description=* @{selected|npc_type}* **STR @{selected|strength}** *(@{selected|strength_mod})* | [roll](~selected|strength) | [save](~selected|npc_str_save) **DEX @{selected|strength}** *(@{selected|dexterity_mod})* | [roll](~selected|dexterity) | [save](~selected|npc_dex_save) **CON @{selected|constitution}** *(@{selected|constitution_mod})* | [roll](~selected|constitution) | [save](~selected|npc_con_save) **INT  @{selected|intelligence}** *(@{selected|intelligence_mod})* | [roll](~selected|intelligence) | [save](~selected|npc_int_save) **WIS @{selected|wisdom}** *(@{selected|wisdom_mod})* | [roll](~selected|wisdom) | [save](~selected|npc_wis_save) **CHA @{selected|charisma}** *(@{selected|charisma_mod})* | [roll](~selected|charisma) | [save](~selected|npc_cha_save) SKILLS [Acrobatics](~selected|npc_acrobatics) | [Animal Handling](~selected|npc_animal_handling) [Arcana](~selected|npc_arcana) | [Athletics](~selected|npc_athletics) | [Deception](~selected|npc_deception) [History](~selected|npc_history) | [Insight](~selected|npc_insight) | [Intimidation](~selected|npc_intimidation) [Investigation](~selected|npc_investigation) | [Medicine](~selected|npc_medicine) | [Nature](~selected|npc_nature) [Perception](~selected|npc_perception) | [Performance](~selected|npc_performance) [Persuasion](~selected|npc_persuasion) | [Religion](~selected|npc_religion) [Sleight of Hand](~selected|npc_sleight_of_hand) | [Steath](~selected|npc_stealth) | [Survival](~selected|npc_survival) [section:"npctrait" repeatany repeatFilters=name:/./] [header]TRAITS AND FEATURES [/header][@{repeating_npctrait_$X_name}](~npctrait_$X_traitreport) | [footer] [/footer] [/section] [section:"npcaction" repeatFilters=name:/./] [header]ACTIONS [/header][@{repeating_npcaction_$X_name}](~repeating_npcaction_$X_npc_action) | [footer] [/footer] [/section] **[Spellcasting](~Spells-Available)** }} This one required a Custom Repeating Ability (the instructions are on the script's handout). The Traits section has no macro buttons, and required a report of the text. Here is an example: And the code. The macro is named npctrait_$X_traitreport /w gm &{template:npcaction} {{rname=@{repeating_npctrait_$X_name}}} {{description=@{repeating_npctrait_$X_desc}}} The Sheet permissions are shown here:
1558760234
GiGs
Pro
Sheet Author
API Scripter
That looks very nice. It's definitely better written than mine, hehe.
1558764923
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
I was talking to Scott about this. Each has its own niche. This one is very powerful and customizable. Yours is simpler to implement and deploy, with fewer "moving parts". It's kind of like the difference between Shaped and OGL. I still haven't made up my mind which one I'll use for the OGL campaign I want to run.
1558765399
GiGs
Pro
Sheet Author
API Scripter
Agreed. My focus is on making it as simple as possible for the user, which does come with some potential limits in power and flexibility. There's definitely room for both.
1558766355
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
I'm curious to see the menus others will come up with. I tried to be as thorough as possible with the statblock menus for 5e in both scripts, but I'd like to see what can be done with a little creativity. For instane, it just occurred to me that either of these scripts could be used to make a money report for the Shaped Sheet, where coinage is a repeating field.
GiGs, quick and simple is sometimes exactly what you want.  Sacrificing flexibility for ease of use isn't a bad trade. 
My first foray into the scripts and API - i could not get the PC's traits to display in the same way as the NPC's But i added custom repeating for that as well. The macro is named: traits_$X_traitreport /w gm &{template:npcaction} {{rname=@{repeating_traits_$X_name}}} {{description=@{repeating_traits_$X_description}}} And editing the Statblock to: [header]TRAITS AND FEATURES [/header][@{repeating_traits_$X_name}](~traits_$X_traitreport) | [footer] [/footer] To make it work and match naming Thx for this cool functionality
1559136309
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Hmm, thanks for the report torben. I'll take a look.
1559140330

Edited 1559140350
Ada L.
Marketplace Creator
Sheet Author
API Scripter
Very cool!  Any chance the script's development roadmap will include programmatic support for other kinds of menus in the future, or will its scope be limited to just views on attributes from character sheets?
1559141248
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
What sorts of menus are you thinking of Stephen?
1559142082
Ada L.
Marketplace Creator
Sheet Author
API Scripter
I was thinking about how this could be used by other scripts to display menus that set up script-specific configurations, properties on objects, or invoking commands supported by those scripts. 
1559144339
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Ah, I mean, it could, but it's a little overkill for that use case. I'll think on it, but I don't think that's going to fall in the expected scope for this script.
1560225777
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Torben V. said: My first foray into the scripts and API - i could not get the PC's traits to display in the same way as the NPC's But i added custom repeating for that as well. The macro is named: traits_$X_traitreport /w gm &{template:npcaction} {{rname=@{repeating_traits_$X_name}}} {{description=@{repeating_traits_$X_description}}} And editing the Statblock to: [header]TRAITS AND FEATURES [/header][@{repeating_traits_$X_name}](~traits_$X_traitreport) | [footer] [/footer] To make it work and match naming Thx for this cool functionality Torben, Sorry for the abysmal delay in responding. Did you also change the section line of Keith's statblock macro: [section:"npctrait" repeatany repeatFilters=name:/./] to [section:"traits" repeatany repeatFilters=name:/./] Scott
Hi Scott, I honestly cant remember if i changed it, but i have it :) Can teach me to keep a changelog :) /Torben
keithcurtis said: The Sheet permissions are shown here: Hi Keith (and Scott - great script!) - am I missing something with "Spells Available" Apply To section? It looks like its set to "Filter" - what values should be put in for that?
1560743684

Edited 1560743703
As a follow up - is it possible to delete/uninstall this and start fresh? I disabled the script and then realized I still had a bunch of Statblock-NPC and npctrait actions. Re-enabling the script doesn't show any Templates to delete.
1560744968
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Hmm, when you disabled the script, did you delete the menu maker character? That's probably why it's not updated.
Yeah, unfortunately. Am I just out of luck with all those extraneous actions?
1560808760
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
For the short term yes. I can update the script to handle them though. I just need to find some time to do so.
1562211099

Edited 1562211215
Having a really hard time getting this script to work whenever I try to change a setting the whole API freezes and no change is made. Seems to create a loop.
1562213851
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Anthony V. said: Having a really hard time getting this script to work whenever I try to change a setting the whole API freezes and no change is made. Seems to create a loop. Anthony, can you give me some more detail on what you're trying to do, what error you're seeing, and any other info you think might help.