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

Nesting Macro Error - seeking advice?

Hello! I have been using Roll20 for about a year and slowly adding macros to my game. I am inexperienced with coding and want to learn the macro route manually a bit more before jumping into API's if possible, I like understanding how things work before using them and never getting around to it. I have a macro already that shows remaining spell slots on selected tokens, but am trying to make a query macro to select a PC from a drop-down instead. I found a tutorial on Nesting Macros that worked for a couple of other things but I can't seem to get it to work in this application. Essentially I have created a macro for each PC in my game which show all remaining spell slots, but when I create a query macro referencing all of the individual ones it just posts the queried macro title in chat but doesn't run it. If I manually type the macro into chat it runs properly. Here is an example of the specific PC macro #2CragSpells: /w gm &{template:default} {{name=Spell Slots}} {{name= @{Crag Dugin|character_name} Spell Slots}} {{**Level 1:** [[@{Crag Dugin|lvl1_slots_expended}]] ** of ** [[@{Crag Dugin|lvl1_slots_total}]] **Spell Slots Remaining**}}{{**Level 2:** [[@{Crag Dugin|lvl2_slots_expended}]] ** of ** [[@{Crag Dugin|lvl2_slots_total}]] **Spell Slots Remaining**}}{{**Level 3:** [[@{Crag Dugin|lvl3_slots_expended}]] ** of ** [[@{Crag Dugin|lvl3_slots_total}]] **Spell Slots Remaining**}} Here is the query macro: ?{spell slots?|Crag,#2CragSpells|Galdrean,#2GaldreanSpells|llm,#2IlmSpells|Klepto,#2KleptoSpells|Mira,#2MiraSpells} Can someone offer an advice or point out my error in the macro? Thanks in advance!
1714449661
timmaugh
Pro
API Scripter
In order for that to expand properly, you need to include a space before the hash mark for each macro... ... however... Once you get the nested macro to be recognized and expanded, you're going to need HTML character substitutions so the nested command doesn't break the query. A query has certain control characters: A comma, to separate the displayed query option from the returned value. A vertical pipe to designate a new option in the query.  A right brace to close the query. If any of these characters appear in the command line of the nested macro, they will need to be replaced with their HTML equivalents. For instance, the } needs to be replaced with }  The exception is where those characters are involved in something like an attribute call. The attribute will be resolved before the query runs, so it won't affect the query. ...but... That hash tells me you saved these as a Collection tab macro rather than a character sheet ability. That means you are going to run into these character substitutions reverting. It is a known issue with collection tab macros that when you do HTML solutions in them and save the macro, it will work. However, if you edit the macro at any point after that, the HTML substitutions will revert to their actual character equivalents. That would mean that you'd have to do the substitutions all over again just for having opened the macro to look at it.  It is much better to do things like this in an ability on some sort of macro character mule sheet. HTML substitutions in a character sheet ability do not revert when you open the ability to look at it.  Of course, if we are talking about the best way to do something like this, then I feel like we should mention chat menus... Or the meta script toolbox, if you do want to get into the realm of scripts.
1714450168
Gauss
Forum Champion
to add to what Timmaugh wrote: Chat Menus:&nbsp; <a href="https://wiki.roll20.net/Chat_Menus" rel="nofollow">https://wiki.roll20.net/Chat_Menus</a> Please, avoid queries when you have to do this much HTML substitution. Use Chat Menus instead. Save your brain cells the pain of having to deal with HTML substitution. :) Brought to you by the organization, Save the Control Characters Conservancy. (note: this last bit is a joke)
Thank you both! I think API Scripts is the route I will likely end up going, but wanted to try to create a simpler version I could wrap my head all the way around. Lol I will look into Chat Menus in the meantime. Thank you both for your prompt responses, help for a total coding newbie and the joke too! Thanks again!
1714453083

Edited 1714455632
Gauss
Forum Champion
Chat Menus are really easy actually.&nbsp; Here is the Chat Menu you can use instead of a query. It should work but I haven't tested it. If it doesn't please let me know and I can troubleshoot it.&nbsp; &amp;{template:default} {{name=Spell Slots?}} {{select one=[Crag](`#2CragSpells)%NEWLINE%[Galdrean](`#2GaldreanSpells)%NEWLINE%[Ilm](`#IlmSpells)%NEWLINE%[Klepto](`#2KleptoSpells)%NEWLINE%[Mira](`#MiraSpells)}} Set it up as a macro. You can whisper it to yourself via /w GM if you'd prefer not spamming chat with it.&nbsp; Personally though, I would suggest migrating away from the Collection tab Macros and towards a Macro Mule 's Ability macros (Attributes and Abilities tab). I find Abilities are generally better for most macro uses.&nbsp;
I started to delve into Chat Menus and got halfway there before you solved it for me! Thank you so much, I really appreciate the help and learning the super basics. Thanks again!
1714455683
Gauss
Forum Champion
Cortana said: I started to delve into Chat Menus and got halfway there before you solved it for me! Thank you so much, I really appreciate the help and learning the super basics. Thanks again! I've written so many chat menus at this point that I can probably write them in my sleep.&nbsp; I barely do queries anymore because nesting queries is a pain, chat menus are easy. :)
1714456123
GiGs
Pro
Sheet Author
API Scripter
Gauss said: I barely do queries anymore because nesting queries is a pain, chat menus are easy. :) I can second this. I never use nested queries if I can avoid them - a chat menu will almost always do the job and be so much easier to write (and maintain).
1714482320
timmaugh
Pro
API Scripter
Cortana said: Thank you both! I think API Scripts is the route I will likely end up going, but wanted to try to create a simpler version I could wrap my head all the way around. Lol I will look into Chat Menus in the meantime. Thank you both for your prompt responses, help for a total coding newbie and the joke too! Thanks again! Hey, Cortana, if you want to look at script potential solutions, here is a post discussing how to do it with the Metascript Toolbox (namely Fetch &amp; ZeroFrame). It can be a different way of thinking about things, so feel free to post with any questions if you go this route. =D
1714488182

Edited 1714488210
It looks like you're playing D&amp;D 5th Edition and using the D&amp;D 5E by Roll20 sheet (based on the attributes I saw in your macro) so I'll definitely plug my D&amp;D 5E Universal MacroMule .&nbsp; The Spells menu lists the current/max spell slots per level (along with the spells that are on the sheet for the character): It would be pretty easy to add a custom menu to show only spell slots for a character as well.
This community is awesome, and so welcoming. Thanks everyone for the suggestions and links to helpful information, especially the Metascript Toolbox! I think Chat Menus is the route I will be using for now, but definitely heading towards more API options cause there is so much cool stuff out there! But I am definitely intrigued by your Universal MacroMule and will be checking that out too.
1714492583

Edited 1714506000
Since you have a Pro subscription, you can use the Mod script and add the MacroMule in about a minute.&nbsp;&nbsp; Then, if you want to add a 'Spell Slots' count to the MacroMule,&nbsp; here is what the output will look like, only displaying levels that the character has spells: Create two new Abilities: SpellCount %{MM|SpellsTemplate}%{MM|SpellCountList}%{MM|StatsFooter}}} {{name=Spell Slots}} &amp;{noerror} SpellCountList [**Level 1:**](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-1_$0_spellname|max};) [**@{selected|lvl1_slots_expended}**/**@{selected|lvl1_slots_total}**](%{MM|SpellLinkStyle} display: inline-block@{selected|repeating_spell-1_$0_spellname|max};) [Spell Slots Remaining](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-1_$0_spellname|max};)[ ](%{MM|BreakLinkStyle} display: block@{selected|repeating_spell-1_$0_spellname|max};)[**Level 2:**](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-2_$0_spellname|max};) [**@{selected|lvl2_slots_expended}**/**@{selected|lvl2_slots_total}**](%{MM|SpellLinkStyle} display: inline-block@{selected|repeating_spell-2_$0_spellname|max};) [Spell Slots Remaining](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-2_$0_spellname|max};)[ ](%{MM|BreakLinkStyle} display: block@{selected|repeating_spell-2_$0_spellname|max};)[**Level 3:**](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-3_$0_spellname|max};) [**@{selected|lvl3_slots_expended}**/**@{selected|lvl3_slots_total}**](%{MM|SpellLinkStyle} display: inline-block@{selected|repeating_spell-3_$0_spellname|max};) [Spell Slots Remaining](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-3_$0_spellname|max};)[ ](%{MM|BreakLinkStyle} display: block@{selected|repeating_spell-3_$0_spellname|max};)[**Level 4:**](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-4_$0_spellname|max};) [**@{selected|lvl4_slots_expended}**/**@{selected|lvl4_slots_total}**](%{MM|SpellLinkStyle} display: inline-block@{selected|repeating_spell-4_$0_spellname|max};) [Spell Slots Remaining](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-4_$0_spellname|max};)[ ](%{MM|BreakLinkStyle} display: block@{selected|repeating_spell-4_$0_spellname|max};)[**Level 5:**](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-5_$0_spellname|max};) [**@{selected|lvl5_slots_expended}**/**@{selected|lvl5_slots_total}**](%{MM|SpellLinkStyle} display: inline-block@{selected|repeating_spell-5_$0_spellname|max};) [Spell Slots Remaining](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-5_$0_spellname|max};)[ ](%{MM|BreakLinkStyle} display: block@{selected|repeating_spell-5_$0_spellname|max};)[**Level 6:**](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-6_$0_spellname|max};) [**@{selected|lvl6_slots_expended}**/**@{selected|lvl6_slots_total}**](%{MM|SpellLinkStyle} display: inline-block@{selected|repeating_spell-6_$0_spellname|max};) [Spell Slots Remaining](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-6_$0_spellname|max};)[ ](%{MM|BreakLinkStyle} display: block@{selected|repeating_spell-6_$0_spellname|max};)[**Level 7:**](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-7_$0_spellname|max};) [**@{selected|lvl7_slots_expended}**/**@{selected|lvl7_slots_total}**](%{MM|SpellLinkStyle} display: inline-block@{selected|repeating_spell-7_$0_spellname|max};) [Spell Slots Remaining](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-7_$0_spellname|max};)[ ](%{MM|BreakLinkStyle} display: block@{selected|repeating_spell-7_$0_spellname|max};)[**Level 8:**](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-8_$0_spellname|max};) [**@{selected|lvl8_slots_expended}**/**@{selected|lvl8_slots_total}**](%{MM|SpellLinkStyle} display: inline-block@{selected|repeating_spell-8_$0_spellname|max};) [Spell Slots Remaining](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-8_$0_spellname|max};)[ ](%{MM|BreakLinkStyle} display: block@{selected|repeating_spell-8_$0_spellname|max};)[**Level 9:**](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-9_$0_spellname|max};) [**@{selected|lvl9_slots_expended}**/**@{selected|lvl9_slots_total}**](%{MM|SpellLinkStyle} display: inline-block@{selected|repeating_spell-9_$0_spellname|max};) [Spell Slots Remaining](%{MM|InfoLinkStyle} display: inline-block@{selected|repeating_spell-9_$0_spellname|max};)[ ](%{MM|BreakLinkStyle} display: block@{selected|repeating_spell-9_$0_spellname|max};) Create a Collections Macro: SpellSlots %{MM|SpellCount} &amp;{noerror}&nbsp; And if you want to have the Spell Slots button added to the footer, then just manually change the MenuList ability: MenuList [Stats](~MM|Stats%{MM|StatLinkStyle} cursor: pointer; %{MM|FooterLinkStyle}display: inline-block; )[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} display: inline-block;)[Rolls](~MM|Rolls%{MM|RollLinkStyle} %{MM|FooterLinkStyle}display: inline-block; )[ ](%{MM|BreakLinkStyle} margin-top: -2px; display: block;)[Attacks](~MM|PCAttacks%{MM|ActionLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{MM|at}{MM|at}{MM|PC@{selected|npc}}; )[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{MM|at}{MM|at}{MM|PC@{selected|npc}}; )[Traits](~MM|PCTraits%{MM|TraitLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{MM|at}{MM|at}{MM|PC@{selected|npc}}; )[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{MM|at}{MM|at}{MM|PC@{selected|npc}}; )[Prof](~MM|PCProficiencies%{MM|ReactionLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{MM|at}{MM|at}{MM|PC@{selected|npc}}; )[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{MM|at}{MM|at}{MM|PC@{selected|npc}}; )[Equip](~MM|PCEquipment%{MM|ItemLinkStyle} cursor: pointer; %{MM|FooterLinkStyle}display: inline-block@{MM|at}{MM|at}{MM|PC@{selected|npc}}; )[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} display: inline-block@{MM|at}{MM|at}{MM|PC@{selected|npc}}; )[Bio](~MM|PCBio%{MM|LegendaryLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{MM|at}{MM|at}{MM|PC@{selected|npc}}; )[Abilities](~MM|NPCAbilities%{MM|HeaderLinkStyle} cursor: pointer; %{MM|FooterLinkStyle}display: inline-block@{MM|at}{MM|at}{MM|NPC@{selected|npc}}; )[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_npcaction_$0_name|max}; )[Action](~MM|NPCActions%{MM|ActionLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_npcaction_$0_name|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_npcbonusaction_$0_name|max}; )[Bonus](~MM|NPCBonusActions%{MM|BonusActionLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_npcbonusaction_$0_name|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_npctrait_$0_name|max}; )[Trait](~MM|NPCTraits%{MM|TraitLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_npctrait_$0_name|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_npcreaction_$0_name|max}; )[React](~MM|NPCReactions%{MM|ReactionLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_npcreaction_$0_name|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_npcaction-l_$0_name|max}; )[Legend](~MM|NPCLegendarys%{MM|LegendaryLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_npcaction-l_$0_name|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_npcaction-m_$0_name|max}; )[Mythic](~MM|NPCMythics%{MM|MythicLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_npcaction-m_$0_name|max};)[ ](%{MM|BreakLinkStyle} margin-top: -2px; display: block;) [Slots](~MM|SpellCount%{MM|SpellLinkStyle} cursor: pointer; %{MM|FooterLinkStyle}display: none; display: inline-block@{MM|at}{MM|at}{MM|spellcaster@{selected|npcspellcastingflag}}; display: inline-block@{MM|at}{MM|at}{MM|spellcaster@{selected|caster_level}}; )[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-cantrip_$0_spellname|max}; ) [Spells](~MM|Spells%{MM|SpellLinkStyle} cursor: pointer; %{MM|FooterLinkStyle}display: none; display: inline-block@{MM|at}{MM|at}{MM|spellcaster@{selected|npcspellcastingflag}}; display: inline-block@{MM|at}{MM|at}{MM|spellcaster@{selected|caster_level}}; )[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-cantrip_$0_spellname|max}; )[C](~MM|Cantrips%{MM|SpellLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-cantrip_$0_spellname|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-1_$0_spellname|max}; )[1](~MM|Lvl1%{MM|SpellLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-1_$0_spellname|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-2_$0_spellname|max}; )[2](~MM|Lvl2%{MM|SpellLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-2_$0_spellname|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-3_$0_spellname|max}; )[3](~MM|Lvl3%{MM|SpellLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-3_$0_spellname|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-4_$0_spellname|max}; )[4](~MM|Lvl4%{MM|SpellLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-4_$0_spellname|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-5_$0_spellname|max}; )[5](~MM|Lvl5%{MM|SpellLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-5_$0_spellname|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-6_$0_spellname|max}; )[6](~MM|Lvl6%{MM|SpellLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-6_$0_spellname|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-7_$0_spellname|max}; )[7](~MM|Lvl7%{MM|SpellLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-7_$0_spellname|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-8_$0_spellname|max}; )[8](~MM|Lvl8%{MM|SpellLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-8_$0_spellname|max};)[&amp;nbsp;|&amp;nbsp;](%{MM|InfoLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-9_$0_spellname|max}; )[9](~MM|Lvl9%{MM|SpellLinkStyle} %{MM|FooterLinkStyle}display: inline-block@{selected|repeating_spell-9_$0_spellname|max};)