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 .
×
Advertisement Create a free account

[Script] ScriptCards - My "Spiritual Successor" to PowerCards

1611964235

Edited 1631831384
Kurt J.
Pro
API Scripter
ScriptCards allows you to create powerful macros that produce a card-style output to the game chat window similar to PowerCards (see the next post in this thread for some background info). The major difference is that ScriptCards is actually a scripting language interpreter that includes variables, loops, procedures (with parameters) and its own dice roll parser. The first few posts in this thread contain the following: This Post &nbsp;contains basic information about the ScriptCards script The Second Post&nbsp; contains some background information on ScriptCards vs PowerCards The Third Post &nbsp;is reserved for a FAQ (Frequently Asked Questions) section Links Wiki Documentation:&nbsp; <a href="https://wiki.roll20.net/Script:ScriptCards" rel="nofollow">https://wiki.roll20.net/Script:ScriptCards</a> Development on GitHub:&nbsp; <a href="https://github.com/kjaegers/ScriptCards/tree/main/ScriptCards_API" rel="nofollow">https://github.com/kjaegers/ScriptCards/tree/main/ScriptCards_API</a> YouTube Overview and Demonstration:&nbsp; <a href="https://www.youtube.com/watch?v=hyR7Jnq4mQM" rel="nofollow">https://www.youtube.com/watch?v=hyR7Jnq4mQM</a> YouTube Deep-Dive on Magic Missile:&nbsp; <a href="https://www.youtube.com/watch?v=u50xvNzS9Zk" rel="nofollow">https://www.youtube.com/watch?v=u50xvNzS9Zk</a> New: Discord Server&nbsp; <a href="https://discord.gg/gTzRkdvY" rel="nofollow">https://discord.gg/gTzRkdvY</a> Overview Current Version (OneClick) : 1.4.0e Current Version (Development) : 1.4.2 Update Links: 1.4.2: (Math functions, bug fixes) 1.4.2 Update Notes 1.4.0: (pagetokens performance, array sort) 1.4.0 Update Notes &nbsp;( d ) 1.3.9a/b/c: (Angle function, Repeating Section Performance) 1.3.9a Update Notes &nbsp;( b ) ( c ) 1.3.9: (HR code, Title Shadow, findability, array setatindex) 1.3.9 Update Notes 1.3.8: (Bug fixes, get raw date) 1.3.8 Update Notes 1.3.7: (Button background images, dumpvariables function) 1.3.7 Update Notes 1.3.6b: (Bug fix, buttontextcolor options) 1.3.6b Update Notes 1.3.6a: (International character support in variable names) 1.3.6a Update Notes 1.3.6: (title card backgrounds &amp; gradients, no-highlight rolls) 1.3.6 Update Notes 1.3.5: (Date functions, find token inits, readsetting function) 1.3.5 Update Notes 1.3.1: (Referencing/Replacement Rewrite) 1.3.1 Update Notes 1.2.9: (More Deferral, Point Custom FX, pixel distance, replaceall, trim, executionlimit) 1.2.9 Update Notes 1.2.8a: (SelectManager Deferral Support) 1.2.8a Update Notes 1.2.8: (Point VFX, Roll Parser Math Funcs) 1.2.8 Update Notes 1.2.7: (For..Next, Statement Block, Data Statements) &nbsp; 1.2.7 Update Notes 1.2.3: (Inline Roll Semi-Support, lower/upper/title case)&nbsp; 1.2.3 Update Notes 1.2.2: (#activepage, [*C:] (campaign) and [*P:] (page) attributes: 1.2.2 Update Notes 1.2.1: (URL Attributes, Non-Branching Conditionals): 1.2.1 Update Notes 1.1.19: New Roll Formula, Button Formatting, Status Markers, Array Updates: 1.1.19 , A , C , E 1.1.18: Errors &amp; Warnings, GM Text, SheetButtons, Reentrant Scripts: 1.1.18 Update Notes 1.1.15: Persistable Array: 1.1.15 Update Notes 1.1.14: Token Array Functions: 1.1.14 Update Notes 1.1.13: Bug Fixes and Stringify Arrays: 1.1.13 Update Notes 1.1.12 (Mislabeled 1.1.2): New Roll Syntaxes, Turn Tracker Support, Arrays: 1.1.12 Update Notes 1.0.8: Table Markup, Custom VFX, Token Attributes: 1.0.8 Update Notes &nbsp; 1.0.2: -ninc Operator, br formating, Info Request (--i) Support : 1.0.2 Update Notes 1.0.0: Predefined Player Strings, Case (--c) Statement, Procedure Library Support: 1.0.0 Update Notes 0.0.15: Comments (--/), Modulo operator, rdump, Function Groups: 0.0.15 Update Notes 0.0.14: Referencing Updates, #NoMinMaxHilight, getselected function: 0.0.14 Update Notes 0.0.13: Bug Fixes, Repeating Sections (--r), and Functions (--~): 0.0.13 Update Notes ,&nbsp; A 0.0.11: Button Customization, Dice Fonts, Whisper Support: 0.0.11 Update Notes , A 0.0.10: New Settings, String Variables, VFX, Echo (--e), Buttons w/API code: 0.0.10 Update Notes , A , B 0.0.8: Storage (--s and --l), Rollable Tables, Multipart Conditionals: 0.0.8 Update Notes General Overview NOTE: ScriptCards has evolved to the point where it would not be possible to document it in a forum post. Please see the ScriptCards WIKI entry for complete documentation. The information below should be treated as an introductory overview.
1611964242

Edited 1617738101
Kurt J.
Pro
API Scripter
Some Background Information Many of you probably know me as the guy that has been updating and maintaining the PowerCards API script for the last couple of years. One of the things I’ve always wanted to do was address some of the use cases that are just simply not possible/practical with PowerCards, such as: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; The ability to use the results of one roll within another roll &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; The ability to make formatting and other single-use options conditional &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; Actual branching and looping At first, I considered continuing to attempt to modify PowerCards to add some of these capabilities, but the things that prevent them from happening are pretty fundamentally baked into the DNA of PowerCards. Modifying those underpinnings would require breaking changes to PowerCards, rendering existing content people are using in games unusable. To prevent that, I decided on starting from scratch with the intent of a scripting language as the base for the API script. Both PowerCards and ScriptCards can be installed in the same Roll20 game and live happily side by side.
1611964261

Edited 1624124136
Kurt J.
Pro
API Scripter
Script Sharing Index Please see Craven's " ScriptCard API Working and Sharing " post, as he has gathered and indexed a large number of ScriptCards scripts in one place. If others pop up in different locations, I'll link to them here.
1611966494
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Interesting. These are the things I originally thought Powercards was for, but was always either disappointed or (more likely) confused. This looks very intriguing!
This looks SUPER cool. I think maybe this is the incentive I need to take the plunge and figure this powercard-type stuff out.
1611981291

Edited 1611981304
David M.
Pro
API Scripter
Loops and function calls in macros, in addition to conditionals? Nice! Can't wait to try it out!
1612019167
Kurt J.
Pro
API Scripter
I updated the GIST (no version number change) to remove a couple of log lines I was using for debugging that would output the content of each row to the console. That spam should be gone if you re-import the script.
1612019650
David M.
Pro
API Scripter
Looks like the Magic Missile example above never includes the first missile in the total damage. However, I got it to work by initializing a value of 0 to the MissileDamage roll variable (bolded below) prior to the first call to the FireMissile procedure. &nbsp;!scriptcard {{ --#title|Magic Missile --#leftsub|Slot level ?{Spell Slot Level?|1|2|3|4|5|6|7|8|9} --#rightsub|Ranged Attack (120ft) --=MissileCount|?{Spell Slot Level?} + 2 --=DisplayCount|1 --=MissileDamage|0 --:MissileLoop| --&gt;FireMissile| --=DisplayCount|[$DisplayCount] + 1 --?[$DisplayCount] -le [$MissileCount]|MissileLoop --+Total|Total damage is [$MissileDamage] --X| --:FireMissile| --=ThisMissile|1d4 + 1 --=MissileDamage|[$MissileDamage] + [$ThisMissile] --+Missile|[$DisplayCount.Total] Hits for [$ThisMissile] [b]force[/b] damage --&lt;| }} EDIT:&nbsp; Also works if I just declare it but put no value for the variable (defaults to 0). --=MissileDamage|
1612022533
Kurt J.
Pro
API Scripter
Good catch :) I've updated the Wiki version of the example and will update the first post here as well.
1612051414

Edited 1612051981
David M.
Pro
API Scripter
Played around with this a little bit again today. Really neat, Kurt! I decided to try it out with the 5e Barbarian Path of Wild Magic "Wild surge" feature . I know this could be done with rollable tables and RecursiveTable or similar api to handle the rolls within some of the table entries, but this was more of a syntax study project for me with functions, formatting, and whatnot. I figured I'd share it here in case somebody wanted to use it or just wanted another practical example. Simple enough to use. Select the barbarian token and run the macro. Rolls 1d8 against the surge table, checks the result, and possibly makes more rolls prior to output (these were put into the individual functions to keep the overhead low). &nbsp;!scriptcard {{ --:___Formatting___ --#title|Wild Surge --#leftsub|Path of Wild Magic Feature --#titleCardBackground|#932729 --#oddRowBackground|#CEC7B6 --#evenRowBackground|#B6AB91 --:___Primary Rolls___ --=DC|8 + @{selected|pb} + @{selected|constitution_mod} --=SurgeRoll|1d8 --:___Conditionals___ --?[$SurgeRoll] -eq 1| &gt;Roll_1 --?[$SurgeRoll] -eq 2| &gt;Roll_2 --?[$SurgeRoll] -eq 3| &gt;Roll_3 --?[$SurgeRoll] -eq 4| &gt;Roll_4 --?[$SurgeRoll] -eq 5| &gt;Roll_5 --?[$SurgeRoll] -eq 6| &gt;Roll_6 --?[$SurgeRoll] -eq 7| &gt;Roll_7 --?[$SurgeRoll] -eq 8| &gt;Roll_8 --X|___Exit Macro___ --:___Functions___ --:Roll_1| --=NecroDam|1d12 --=TempHP|1d12 --+[c]**~~Shadow Tendrils~~|**[/c] --+|Shadowy tendrils lash around you. --+|[j]Each creature of your choice that you can see within 30 feet of you must succeed on a **[#990000]Constitution saving throw (DC [$DC.Total])[/#]** or take [$NecroDam] necrotic damage.[/j] --+|You also gain [$TempHP] temporary hit points. --&lt;| --:Roll_2| --+[c]**~~Teleport~~|**[/c] --+|[j]**You teleport up to 30 feet** to an unoccupied space you can see.[/j] --+Ongoing Effect|[j]Until your rage ends, you can use this effect again on each of your turns as a bonus action.[/j] --&lt;| --:Roll_3| --=ForceDam|1d6 --+[c]**~~Intangible Spirit~~|**[/c] --+|[j]An intangible spirit, which looks like a **flumph** or a **pixie** (your choice), appears within 5 feet of one creature of your choice that you can see within 30 feet of you.[/j] --+|[j]At the end of the current turn, the spirit explodes, and each creature within 5 feet of it must succeed on a **[#990000]Dexterity saving throw (DC [$DC.Total])[/#]** or take [$ForceDam] force damage.[/j] --+Ongoing Effect|[j]Until your rage ends, you can use this effect again, summoning another spirit, on each of your turns as a bonus action.[/j] --&lt;| --:Roll_4| --+[c]**~~Force Weapon~~|**[/c] --+|[j]Magic infuses one weapon of your choice that you are holding.[/j] --+|[j]Until your rage ends, the **weapon's damage type changes to force, and it gains the light and thrown properties**, with a normal range of 20 feet and a long range of 60 feet.[/j] --+|[j]If the weapon leaves your hand, the weapon reappears in your hand at the end of the current turn.[/j] --&lt;| --:Roll_5| --+[c]**~~Retributive Strike~~|**[/c] --+Ongoing Effect|[j]Whenever a creature hits you with an attack roll before your rage ends, that creature takes **[#990000]1d6 force damage[/#]**, as magic lashes out in retribution.[/j] --&lt;| --:Roll_6| --+[c]**~~Protective Aura~~|**[/c] --+Ongoing Effect|[j]Until your rage ends, you are surrounded by multi colored, protective lights. You gain a **[#990000]+1 bonus to AC[/#]**, and while within 10 feet of you, your allies gain the same bonus.[/j] --&lt;| --:Roll_7| --+[c]**~~Entangling Aura~~|**[/c] --+|[j]Flowers and vines temporarily grow around you.[/j] --+Ongoing Effect|[j]Until your rage ends, the ground within 15 feet of you is **[#990000]difficult terrain[/#]** for your enemies.[/j] --&lt;| --:Roll_8| --=RadiantDam|1d6 --+[c]**~~Radiant Bolt~~|**[/c] --+|[j]A bolt of light shoots from your chest.[/j] --+|[j]Another creature of your choice that you can see within 30 feet of you must succeed on a **[#990000]Constitution saving throw (DC [$DC.Total])[/#]** or take [$RadiantDam] radiant damage and be blinded until the start of your next turn.[/j] --+Ongoing Effect|[j]Until your rage ends, you can use this effect again on each of your turns as a bonus action.[/j] --&lt;| }} Some sample output
1612109116
I've been playing with this script all day yesterday, and am really loving it.&nbsp; The ability to have conditionals and subroutines in a macro is a large enhancement for Roll20's scripting language.&nbsp; It also appears that one could develop simple looping, which I'll be testing out soon.&nbsp;&nbsp; BTW, the Code link on your WIKI page is a dead-end link.&nbsp;&nbsp;
1612113218
Kurt J.
Pro
API Scripter
Will M. said: I've been playing with this script all day yesterday, and am really loving it.&nbsp; The ability to have conditionals and subroutines in a macro is a large enhancement for Roll20's scripting language.&nbsp; It also appears that one could develop simple looping, which I'll be testing out soon.&nbsp;&nbsp; BTW, the Code link on your WIKI page is a dead-end link.&nbsp;&nbsp; Looks like the code element is a built-in part of the script Wiki template, and always wants to point to somewhere on the Roll20 GITHUB. I couldn't find a way to point it to the GIST, but I did manage to get it to not show up to remove confusion.
1612113429
GiGs
Pro
Sheet Author
API Scripter
This looks very cool. Your video was a very good tutorial.
1612135929
This looks AWESOME....!!!! Cant Wait to implement...
1612136856
Kurt J.
Pro
API Scripter
Thanks everyone that has checked it out. I've had a lot of fun putting this together, and I've submitted a pull request to get it up on OneClick (hopefully this week).
1612200394
David M.
Pro
API Scripter
Can procedures be called from other procedures, or is it limited to one branch level? Simple example: Create a roll variable "Var" initialized to 0. Call procedure "TestProc" that rolls a 1d2 and on a roll of 1, call a subprocedure "AddToVar" (via bolded line below) that increments Var by one. Then return output. The following never &nbsp;increments the counter "Var", which makes me think we might be limited to one level of branching? (...or I goofed in the syntax somewhere) !scriptcard {{ --#title|Test --:Main --=Var|0 --&gt;TestProc| --+Value of "Var"|[$Var] --X|Exit macro --:TestProc| --=Temp|1d2 --+Roll|[$Temp] --?[$Temp.Total] -eq 1|&gt;AddToVar --&lt;| --:AddToVar --=Var|[$Var] +1 --&lt;| }} If not, is there a way to update a roll variable directly from a query? I tried the following with no luck: --?[$Temp.total] -eq 1|=Var|[$Var] + 1
1612202499

Edited 1612202671
Kurt J.
Pro
API Scripter
David M. said: Can procedures be called from other procedures, or is it limited to one branch level? Simple example: Create a roll variable "Var" initialized to 0. Call procedure "TestProc" that rolls a 1d2 and on a roll of 1, call a subprocedure "AddToVar" (via bolded line below) that increments Var by one. Then return output. The following never &nbsp;increments the counter "Var", which makes me think we might be limited to one level of branching? (...or I goofed in the syntax somewhere) !scriptcard {{ --#title|Test --:Main --=Var|0 --&gt;TestProc| --+Value of "Var"|[$Var] --X|Exit macro --:TestProc| --=Temp|1d2 --+Roll|[$Temp] --?[$Temp.Total] -eq 1|&gt;AddToVar --&lt;| --:AddToVar --=Var|[$Var] +1 --&lt;| }} If not, is there a way to update a roll variable directly from a query? I tried the following with no luck: --?[$Temp.total] -eq 1|=Var|[$Var] + 1 Nested procedure calls is supported. The issue above is that the --:AddToVar line is missing the trailing | so the line is being skipped (and therefore not recognized by the procedure call as a legitimate label). If you add a | to the end of that line it works as expected for me. (the same will be true of --:Main, but since it is never branched to it doesn't end up hurting anything). When nesting procedure calls, a return stack is built that can support (theoretically) any depth of nesting. A parameter stack is also built, so if you pass "A;B;C" to Procedure1 which calls Procedure2 and passes "D;E;F" when you return from Procedure2 to Procedure1 the "D;E;F" parameters are popped off the stack and the current parameter set becomes "A;B;C" again. For the second part, conditionals ONLY support branching (direct or procedure). they currently don't support an alternative statement type when true.
1612204214
David M.
Pro
API Scripter
Perfect, I was hoping it was just a syntax issue. Thanks!
1612205703

Edited 1612206580
Kurt J.
Pro
API Scripter
You can also use recursion: !scriptcard {{ --#title|Recursion Test --=BaseValue|0 --=RollCount|0 --=MaxValue|1000 --+Info|Going to roll d10s until we reach 1000 or higher! --&gt;AddIt| --+Results|It took [$RollCount.Total] rolls to reach [$BaseValue.Total] --X| --:AddIt| --=BaseValue|[$BaseValue] + 1d10 --=RollCount|[$RollCount] + 1 --?[$BaseValue] -lt [$MaxValue]|&gt;AddIt --&lt;| }} Probably wouldn't be necessary unless the card was really complicated, but it can be done :) I pushed the max number up to 1,000,000, resulting in 182,148 recursive die rolls and the sandbox didn't crash or timeout :) It did take ~10 seconds to complete though :)
1612206810

Edited 1612206942
I really like ScriptCards and see a lot of potential.&nbsp; I have had an issue with making API calls (--@) as the script doesn't always evaluate the variables I pass it correctly.&nbsp; I'll work on getting a simple example to demonstrate the problem.&nbsp;&nbsp; Also - What happens if you put the card into an endless loop and how do you interrupt the code at that point?&nbsp; I'm guessing restarting the API Sandbox is your best bet.&nbsp;&nbsp;
1612212182

Edited 1612214033
I believe I found a bug associated with making API calls when using the API command (--@).&nbsp; If you make more than one API call, ScriptCards uses the last command and calls it equal to the number of total API calls.&nbsp; For example: !scriptcard {{ &nbsp; --#title|Heal &nbsp; --@modbattr|_name @{selected|character_name} _HP|1 &nbsp; --@modbattr|_name @{selected|character_name} _HP|2 &nbsp; --@modbattr|_name @{selected|character_name} _HP|3 }} modbattr is a command from the ChatSetAttr API script which I use to adjust character-sheet attributes.&nbsp; I placed debug code in the script to log the actual commands being sent to the API and I get this as a result: "!modbattr&nbsp; --name BB --HP|3" "!modbattr&nbsp; --name BB --HP|3" "!modbattr&nbsp; --name BB --HP|3" The ScriptCards code should increase the token HP by 1, 2, and 3 for a total of 6.&nbsp; What actually happens is the token HP is increased by 3, 3, and 3 for a total of 9.&nbsp; This is verified by both the debug msg (log()) and the observed increase in the tokens HP to 9.&nbsp; I'm guessing that you wrote this assuming the user would issue only one API command per card.&nbsp;&nbsp; Update:&nbsp; I think the bug has something to do with the setTimeout() function, which causes the code to run asynchronously.&nbsp; I'm guessing that because it is calling the 3 functions in rapid succession, it is using stored memory from the last call and executing the 3 calls against the last set of data in memory.&nbsp; I modified your code to run the sendChat outside of the setTimeout() function fixes the problem for me.&nbsp; This is around line 215 of your script.&nbsp; &nbsp; Will
1612213720

Edited 1612221059
Kurt J.
Pro
API Scripter
Will M. said: I believe I found a bug associated with making API calls when using the API command (--@).&nbsp; If you make more than one API call, ScriptCards uses the last command and calls it equal to the number of total API calls.&nbsp; For example: !scriptcard {{ &nbsp; --#title|Heal &nbsp; --@modbattr|_name @{selected|character_name} _HP|1 &nbsp; --@modbattr|_name @{selected|character_name} _HP|2 &nbsp; --@modbattr|_name @{selected|character_name} _HP|3 }} modbattr is a command from the ChatSetAttr API script which I use to adjust character-sheet attributes.&nbsp; I placed debug code in the script to log the actual commands being sent to the API and I get this as a result: "!modbattr&nbsp; --name BB --HP|3" "!modbattr&nbsp; --name BB --HP|3" "!modbattr&nbsp; --name BB --HP|3" The ScriptCards code should increase the token HP by 1, 2, and 3 for a total of 6.&nbsp; What actually happens is the token HP is increased by 3, 3, and 3 for a total of 9.&nbsp; This is verified by both the debug msg (log()) and the observed increase in the tokens HP to 9.&nbsp; I'm guessing that you wrote this assuming the user would issue only one API command per card.&nbsp;&nbsp; Hope this makes sense. Will I see what is happening. The setTimeout appears to be the culprit. If I just simply call sendChat without the setTimeout construct it works as expected. I'll make some updates in the next version. As far as putting the script into an endless loop, you could certainly do that, and your sandbox will detect and endless loop and stop on its own. Update: I've updated the development GIST with a fix for the multi API call issue, and updated the code on my pull request, so this fix should make it to the OneClick version that should go up tomorrow.
1612255196
This looks like a lot of fun! I started playing around with the problem I was trying to solve at the moment. I'm trying to determine which values to use in a DC Heroes unarmed melee attack depending on the skill level of the characters attacking and defending, and then passing the values to the Megs API written by GiGs. However I keep crashing the sandbox.&nbsp; I am able to write a macro that gets the values from the selected and targeted tokens: &nbsp; !scriptcard &nbsp;{{ &nbsp;--#title|Unarmed Melee Attack &nbsp;--=SMA|@{selected|skill_martial-artist} &nbsp; --+Martial Artist|[$SMA] &nbsp; &nbsp;--=SDEX|@{selected|dex}&nbsp; &nbsp;--+Attacker Dex|[$SDEX] &nbsp;--=TMA|@{target|skill_martial-artist} &nbsp; --+ Target Martial Artist|[$TMA] &nbsp; &nbsp;--=TDEX|@{target|dex}&nbsp; &nbsp;--+Target Dex|[$TDEX]&nbsp; &nbsp;}} But my attempts at evaluating the Dex attribute and Martial Arts skill and using the higher value crashes the API. Here is one attempt, I've also tried skipping the "=" declarations and get the values from the token in the "?" declaration: !scriptcard &nbsp;{{ &nbsp;--#title|Unarmed Melee Attack &nbsp;--=MA|@{selected|skill_martial-artist} &nbsp; --+Martial Artist|[$MA] &nbsp; &nbsp;--=DEX|@{selected|dex}&nbsp; &nbsp;--+Dex|[$DEX] &nbsp;--?|[$DEX] -lt [$MA]|UseMA &nbsp;--:UseMA &nbsp;--+You attack using your| [$MA] Martial Artis skill &nbsp;--X &nbsp;--:UseDex &nbsp;--+You attack using your| [$DEX] Dexterity attribute &nbsp; }} Also my attempts at passing values to the Megs API crash the sandbox: !scriptcard {{ --#title|Unarmed Melee Attack --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} --#emoteText|@{selected|token_name} attacks @{target|token_name} --=AV|@{selected|dex} --=EV|@{selected|body} --=OV|@{target|dex} --=RV|@{target|body} --@megs|_av:[$AV] _ev:[$EV] _ov:[$OV] _rv:[$RV] }}
1612268964
Kurt J.
Pro
API Scripter
Marius said: This looks like a lot of fun! I started playing around with the problem I was trying to solve at the moment. I'm trying to determine which values to use in a DC Heroes unarmed melee attack depending on the skill level of the characters attacking and defending, and then passing the values to the Megs API written by GiGs. However I keep crashing the sandbox.&nbsp; I am able to write a macro that gets the values from the selected and targeted tokens: &nbsp; !scriptcard &nbsp;{{ &nbsp;--#title|Unarmed Melee Attack &nbsp;--=SMA|@{selected|skill_martial-artist} &nbsp; --+Martial Artist|[$SMA] &nbsp; &nbsp;--=SDEX|@{selected|dex}&nbsp; &nbsp;--+Attacker Dex|[$SDEX] &nbsp;--=TMA|@{target|skill_martial-artist} &nbsp; --+ Target Martial Artist|[$TMA] &nbsp; &nbsp;--=TDEX|@{target|dex}&nbsp; &nbsp;--+Target Dex|[$TDEX]&nbsp; &nbsp;}} But my attempts at evaluating the Dex attribute and Martial Arts skill and using the higher value crashes the API. Here is one attempt, I've also tried skipping the "=" declarations and get the values from the token in the "?" declaration: !scriptcard &nbsp;{{ &nbsp;--#title|Unarmed Melee Attack &nbsp;--=MA|@{selected|skill_martial-artist} &nbsp; --+Martial Artist|[$MA] &nbsp; &nbsp;--=DEX|@{selected|dex}&nbsp; &nbsp;--+Dex|[$DEX] &nbsp;--?|[$DEX] -lt [$MA]|UseMA &nbsp;--:UseMA &nbsp;--+You attack using your| [$MA] Martial Artis skill &nbsp;--X &nbsp;--:UseDex &nbsp;--+You attack using your| [$DEX] Dexterity attribute &nbsp; }} Also my attempts at passing values to the Megs API crash the sandbox: !scriptcard {{ --#title|Unarmed Melee Attack --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} --#emoteText|@{selected|token_name} attacks @{target|token_name} --=AV|@{selected|dex} --=EV|@{selected|body} --=OV|@{target|dex} --=RV|@{target|body} --@megs|_av:[$AV] _ev:[$EV] _ov:[$OV] _rv:[$RV] }} The issue with the second script is that your conditional line has an extra vertical bar before the condition: --?|[$DEX] -lt [$MA]|UseMA should be --?[$DEX] -lt [$MA]|UseMA I don't get any negative effects running the second one. What is the sandbox error message when it crashes? I have updated the GIST and repo for OneClick to handle empty conditions gracefully instead of crashing.
1612271258
Thank you! So now this code: !scriptcard {{ --#title|Unarmed Melee Attack --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} --#emoteText|@{selected|token_name} attacks @{target|token_name} --?@{selected|dex} -lt @{selected|skill_martial-artist}|MA --:MA| --=AVM|@{selected|skill_martial-artist} --=EV|@{selected|body} --=OV|@{target|dex} --=RV|@{target|body} --+megs|_av:[$AVM] _ev:[$EV] _ov:[$OV] _rv:[$RV] --^Final| --:Dex| --=AVD|@{selected|dex} --=EV|@{selected|body} --=OV|@{target|dex} --=RV|@{target|body} --@megs|_av:[$AVD] _ev:[$EV] _ov:[$OV] _rv:[$RV] --^Final| --:Final| }} Produces this result: While changing the "+" to "@" gives this result: And this crash-report: For reference, the error message generated was:&nbsp; TypeError: Cannot read property 'id' of undefined TypeError: Cannot read property 'id' of undefined at getSender (apiscript.js:82:38) at handleInput (apiscript.js:273:28) at eval (eval at &lt;anonymous&gt; (/home/node/d20-api-server/api.js:154:1), &lt;anonymous&gt;:65:16) at Object.publish (eval at &lt;anonymous&gt; (/home/node/d20-api-server/api.js:154:1), &lt;anonymous&gt;:70:8) at /home/node/d20-api-server/api.js:1662:12 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147) at Kd (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:546) at Id.Mb (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:489) at Zd.Ld.Mb (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:94:425) For reference, running "!megs --av:4 --ev:3 --ov:9 --rv:8" gives this (intended) result:
1612272057
Kurt J.
Pro
API Scripter
This looks like the megs API is trying to evaluate who sent the message and coming up with nothing, then trying to look up the ID on that nothing. These functions: getSender (apiscript.js:82:38) at handleInput (apiscript.js:273:28) (getSender and handleInput) don't exist in ScriptCards, so they are likely coming from megs. The sendChat that is used to call the api passes along the msg.who value for the sender.
1612292762

Edited 1612292836
This looks so cool and naturally I saw it after I did a near complete macro rewrite for my campaign. :) I do have a couple questions about syntax:&nbsp; Is it possible to do math in conditionals? For example, does this work? &nbsp; --?[$AttackRoll] -ge @{target|bar2} + 10|Crit Secondly, what is the format for button commands?&nbsp; &nbsp; --+What did you do?|[button]Fumble::~GenericMacro|FumbleRoll[/button] This command seems to output the button fine, but then doesn't execute the macro correctly for the Powercard.&nbsp;
1612293127
David M.
Pro
API Scripter
On a related note, is there currently support for AND/OR logic for conditionals? This doesn't seem to work. &nbsp; --?[$Roll1] -eq 1 AND [$Roll2] -eq 1|DoSomething
1612296939
Kurt J.
Pro
API Scripter
Erik M. said: This looks so cool and naturally I saw it after I did a near complete macro rewrite for my campaign. :) I do have a couple questions about syntax:&nbsp; Is it possible to do math in conditionals? For example, does this work? &nbsp; --?[$AttackRoll] -ge @{target|bar2} + 10|Crit Secondly, what is the format for button commands?&nbsp; &nbsp; --+What did you do?|[button]Fumble::~GenericMacro|FumbleRoll[/button] This command seems to output the button fine, but then doesn't execute the macro correctly for the Powercard.&nbsp; Math is only supported in variable assignment statements (--=) so you would need to break it into two lines and assign a variable to compare against. I've run API commands with the button controls, but I'll experiment with other uses and see what might be happening. The button code is very simple, though... it just replaces the text with [Text](Action). You might be running into the chat server messing with the result and need to use the escape sequences to hide the character references from the macro.
1612296992
Kurt J.
Pro
API Scripter
David M. said: On a related note, is there currently support for AND/OR logic for conditionals? This doesn't seem to work. &nbsp; --?[$Roll1] -eq 1 AND [$Roll2] -eq 1|DoSomething AND and OR is on my list for the next version update (coming soon) along with a few other features as well.
1612297372
David M.
Pro
API Scripter
Sweet, thanks!
1612299775
Kurt J.
Pro
API Scripter
David M. said: Sweet, thanks! Found a bug in the -inc code while working on adding and/or. it wasn't returning true if the inclusion started at the first character of the string (so "Hello -inc He" was returning false (incorrectly), while "Hello -inc ello" was returning true (as it should) . I have a little more testing and documenting to do and I'll get a new version up on the GIST this evening.
1612314178

Edited 1612324269
Kurt J.
Pro
API Scripter
ScriptCards version 0.0.8 is on the Development GIST I have released a new version of ScriptCards to the public GIST. The following updates have been made since 0.0.5: Added two new statement types : --S and --L to save and load groups of settings or roll variables. The syntax is "--Ssettings|GroupName" or --Srollvariables|GroupName" to save, and "--Lsettings|GroupName" or "--Lrollvariables|GroupName" to load. Saving settings saves all current settings that are different from their defaults (things like background colors, fonts, etc.) under the given name. Saving roll variables saves all currently defined variables. The groups are separate (MyStuff could exist as both settings and rollvariables and wouldn't collide). When loading rollvariables, the stored roll variables are added to any variables already on the card. If an existing variable has the same name as a loaded variable, it will be overwritten. When loading settings, any setting loaded as part of the group can be overridden by simply re-setting it with a --# statement. The idea behind the stored settings is to function as a replacement for the --format tag in PowerCards, allowing you to save named formats (using @{selected|token_name} for character names, for example). and loading them to customize the appearance of the card on a per-character basis. Stored items persist between cards, and between roll20 sessions. Added support statement : !sc-liststoredsettings will produce a card listing all of your stored setting groups with buttons to click to see the details of each group. Added support for rollable tables in --= statements . If the roll equation contains a rollable table in the format [T#tablename] where tablename is the case-sensitive name of the table in your game, two new properties will be set on the roll variable - .tableEntryText and .tableEntryImgURL. Proper weighting of table items is taken into account when performing the roll. Added support for multi-part&nbsp; conditionals using -and and -or. Multi-part conditionals are evaluated left to right with a running result value, so T and F or T will return true (T and F will be F, but F or T will result in true at the end). See the wiki for more details. Corrected a bug &nbsp;that would duplicate the same API call parameters if multiple API calls were in a script. Corrected a bug in the -inc conditional operator that was not recognizing the first character of the lefthand string (ie, "Hello" -inc "Hell" would be false, while "Hello" -inc "ell" would be true). Empty conditionals (--?|) will no longer crash the sandbox . They won't work, but they won't crash the sandbox :) Some details on rollable tables. Given this table: This script: !scriptcard {{ --=SpellIcon|[T#SpellTokens] --+Spell Name|[$SpellIcon.tableEntryText] --+Image|[r][img width=128][$SpellIcon.tableEntryImgURL][/img][/r] }} Will produce output like this:
1612339599
Kurt J. said: This looks like the megs API is trying to evaluate who sent the message and coming up with nothing, then trying to look up the ID on that nothing. These functions: getSender (apiscript.js:82:38) at handleInput (apiscript.js:273:28) (getSender and handleInput) don't exist in ScriptCards, so they are likely coming from megs. The sendChat that is used to call the api passes along the msg.who value for the sender. Would this be fixable on the Scriptcards end of things? The MEGS issue is probably not affecting anyone else, but if some kind of api-as/api-subsitution was possible that might be applicable across a number of APIs? I'm way out of my depth here, but I believe Tokenmod and CombatMaster do something like this? I'm also looking forward to playing around with rollable tables, went to bed thinking about how I could name characters based on tables and npc-types last night...
1612351734
Kurt J.
Pro
API Scripter
Marius said: Kurt J. said: This looks like the megs API is trying to evaluate who sent the message and coming up with nothing, then trying to look up the ID on that nothing. These functions: getSender (apiscript.js:82:38) at handleInput (apiscript.js:273:28) (getSender and handleInput) don't exist in ScriptCards, so they are likely coming from megs. The sendChat that is used to call the api passes along the msg.who value for the sender. Would this be fixable on the Scriptcards end of things? The MEGS issue is probably not affecting anyone else, but if some kind of api-as/api-subsitution was possible that might be applicable across a number of APIs? I'm way out of my depth here, but I believe Tokenmod and CombatMaster do something like this? I'm also looking forward to playing around with rollable tables, went to bed thinking about how I could name characters based on tables and npc-types last night... I tried looking for the code for Megs based on your post above, but both of the github links lead to empty pages. It is unlikely anything I do on the scriptcards side would help, but I'd need to see the Megs code to know for sure.The API isn't capable of passing along certain information (selected tokens, the player ID of the message sender), so if an API script relies on that information it can't be called from other scripts. Token-Mod checks to see if the caller is a GM, but also includes a settable option to allow non-GMs to use the --ids command, which allows it to be called working around those restrictions.
1612351962
Kurt J. said: I tried looking for the code for Megs based on your post above, but both of the github links lead to empty pages. It is unlikely anything I do on the scriptcards side would help, but I'd need to see the Megs code to know for sure.The API isn't capable of passing along certain information (selected tokens, the player ID of the message sender), so if an API script relies on that information it can't be called from other scripts. Token-Mod checks to see if the caller is a GM, but also includes a settable option to allow non-GMs to use the --ids command, which allows it to be called working around those restrictions. It was moved here:&nbsp; <a href="https://gist.github.com/birdbrainiac/4a18d202ef43ab5fee938facecedb09e" rel="nofollow">https://gist.github.com/birdbrainiac/4a18d202ef43ab5fee938facecedb09e</a>
1612366634
GiGs
Pro
Sheet Author
API Scripter
Alternatively, just let me know what i need to change in MEGS to work with scriptcards.
1612368070
Kurt J.
Pro
API Scripter
GiGs said: Alternatively, just let me know what i need to change in MEGS to work with scriptcards. I think the only thing that would need to change is in this function: const getSender = msg =&gt; { const character = findObjs({ type: 'character', name: msg.who })[0], player = getObj('player', msg.playerid); if (character) return 'character|'+character.id; else return 'player|'+player.id; }; When using sendChat, the SpeakingAs parameter fills in msg.who, but msg.playerid will always be "API" (I haven't found a way to change that). ScriptCards (and powercards) just pass along whatever they got for msg.who so if I'm reading things right, the only time the crash indicated above would happen is when the GM (who's msg.who value doesn't equal a character name) runs something that calls !megs via the API. In that case the character lookup will fail by name (for example, my msg.who is "Kurt J (GM)" which isn't a valid character name) and the script will try looking up a player by ID, which will also result in undefined since playerid will be API, which isn't a valid player. Modifying the return portion should account for these possibilities and just return whatever it got for msg.who if it can't find a character or player with a matching name. if (character) return 'character|'+character.id; if (player) return 'player|'+player.id; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return msg.who; It looks like the only place the sender is used is as the sendChat speakingAs parameter for the final output, so it might look a little weird if a GM runs it, but it should not impact the sandbox.
1612368458
GiGs
Pro
Sheet Author
API Scripter
Thanks, I'll keeep that in mind for future scripts, I hadnt considered the possibility of people running my scripts via another script.
1612372403

Edited 1612372591
Kurt J. said: GiGs said: Alternatively, just let me know what i need to change in MEGS to work with scriptcards. I think the only thing that would need to change is in this function: const getSender = msg =&gt; { const character = findObjs({ type: 'character', name: msg.who })[0], player = getObj('player', msg.playerid); if (character) return 'character|'+character.id; else return 'player|'+player.id; }; When using sendChat, the SpeakingAs parameter fills in msg.who, but msg.playerid will always be "API" (I haven't found a way to change that). ScriptCards (and powercards) just pass along whatever they got for msg.who so if I'm reading things right, the only time the crash indicated above would happen is when the GM (who's msg.who value doesn't equal a character name) runs something that calls !megs via the API. In that case the character lookup will fail by name (for example, my msg.who is "Kurt J (GM)" which isn't a valid character name) and the script will try looking up a player by ID, which will also result in undefined since playerid will be API, which isn't a valid player. Modifying the return portion should account for these possibilities and just return whatever it got for msg.who if it can't find a character or player with a matching name. if (character) return 'character|'+character.id; if (player) return 'player|'+player.id; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return msg.who; It looks like the only place the sender is used is as the sendChat speakingAs parameter for the final output, so it might look a little weird if a GM runs it, but it should not impact the sandbox. This works! Tested it in my game now.&nbsp;
1612373004
David M.
Pro
API Scripter
Excited about rollable table image support! Very cool. Some comments/questions: 1) I noticed that it does not seem to handle table names that include a dash (like the default "new-table" name). Haven't tried other special characters. NBD if we just have to remember to name appropriately. 2) Is there support for multiple table images on a single line? If so, I haven't figured out the syntax. Example would be for concisely displaying custom dice graphics without spamming the chat with very "tall" cards for games with large dice pools. 3) Related dice pool subject: When trying to get dice pools with a variable number of dice to output to a single line (ignoring graphics for now), it seems like I have to explicitly check for each potential number of dice. A simple example: !scriptcard {{ --=NumDice|?{How Many Dice?|1} --+NumDice=|[$NumDice] --?[$NumDice.Total] -eq 1|&gt;RollAndOutput1 --?[$NumDice.Total] -eq 2|&gt;RollAndOutput2 --?[$NumDice.Total] -eq 3|&gt;RollAndOutput3 --?[$NumDice.Total] -gt 3|&gt;TooManyDice --X| --:TooManyDice| --+Results|Many dice, Much sad --&lt;| --:RollAndOutput1| --=R1|1d6 --+Results|[$R1] --&lt;| --:RollAndOutput2| --=R1|1d6 --=R2|1d6 --+Results|[$R1] [$R2] --&lt;| --:RollAndOutput3| --=R1|1d6 --=R2|1d6 --=R3|1d6 --+Results|[$R1] [$R2] [$R3] --&lt;| }} This isn't too bad with small dice pools, but can get crazy with larger pools and/or multiple pools with subsequent comparisons, etc. Loops and recursion work perfectly for variable dice (ala the Magic Missile example) as long as we output to separate lines, but I haven't figured out a way to do it with more concise output. Any thoughts? Having a blast playing around with this, btw! Another tool in the utility belt. BatCards!
1612374869

Edited 1612374882
David M.
Pro
API Scripter
Hmm, looks like Rolls can be dynamically named, e.g. --=i|1 --=Roll[$i.Total]|1d6 This might be the trick!
1612379924

Edited 1612381565
David M.
Pro
API Scripter
Almost there! Think I'm doing something stupid with the conditionals in the Output branch, as the macro below tries to output all three lines, when I only want one. Trying to query for arbitrary number of dice, then roll them (dynamically creating Roll names in a recursive loop) and then output all in a single line. I haven't figured out how to avoid the brute force explicit conditionals in the output branch yet, but it's more concise code than it was before (when you take out the debug output). Any tips on creating single-line output for any number of dice without making a huge number of conditionals would be appreciated :) Some kind of BuildOutput procedure that could append rolls and/or text? !scriptcard {{ --:Query and assign NumDice| --=NumDice|?{How Many Dice?|1} --+debug_NumDice=|[$NumDice.Total] --:Initialize counter and call RollDiceLoop| --=i|1 --&gt;RollDiceLoop| --:Output| --+[#990000]Output[/#]| --?[$NumDice.Total] -eq 1|--+Rolls|[$Roll1] --?[$NumDice.Total] -eq 2|--+Rolls|[$Roll1] [$Roll2] --?[$NumDice.Total] -eq 3|--+Rolls|[$Roll1] [$Roll2] [$Roll3] --X| Exit macro --:RollDiceLoop| --=Roll[$i.Total]|1d6 --+debugLoop_start| --+debug_i|[$i] --+debug_nested_Roll_i|[$Roll[$i.Total]] --=i|[$i] + 1 --?[$i.Total] -le [$NumDice]|RollDiceLoop --&lt;| }}
1612381698
Kurt J.
Pro
API Scripter
David M. said: Almost there! Think I'm doing something stupid with the conditionals in the Output branch, as the macro below tries to output all three lines, when I only want one. Trying to query for arbitrary number of dice, then roll them (dynamically creating Roll names in a recursive loop) and then output all in a single line. I haven't figured out how to avoid the brute force explicit conditionals in the output branch yet, but more concise code than it was before (when you take out the debug output). Any tips on creating single-line output for any number of dice without making a huge number of conditionals would be appreciated :) Some kind of BuildOutput procedure that could append rolls and/or text? !scriptcard {{ --:Query and assign NumDice| --=NumDice|?{How Many Dice?|1} --+debug_NumDice=|[$NumDice.Total] --:Initialize counter and call RollDiceLoop| --=i|1 --&gt;RollDiceLoop| --:Output| --+[#990000]Output[/#]| --?[$NumDice.Total] -eq 1|--+Rolls|[$Roll1] --?[$NumDice.Total] -eq 2|--+Rolls|[$Roll1] [$Roll2] --?[$NumDice.Total] -eq 3|--+Rolls|[$Roll1] [$Roll2] [$Roll3] --X| Exit macro --:RollDiceLoop| --=Roll[$i.Total]|1d6 --+debugLoop_start| --+debug_i|[$i] --+debug_nested_Roll_i|[$Roll[$i.Total]] --=i|[$i] + 1 --?[$i.Total] -le [$NumDice]|RollDiceLoop --&lt;| }} Last night/early this morning I was working on another update, which I think you'll like. The new version will add string variable support (like roll variables, but they don't do any rolling), making what you are trying to do much easier (I had it roll 1500d6 and output each result as a test). I've also added a false branch option for conditionals, support for vfx, a couple new settings and a pass-through echo statement. Here is a quick script using the new string variables: !scriptcard {{ --=NumDice|?{How Many Dice?|1} --+Rolling|[$NumDice.Total]d6 --=DieCount|0 --:Loop| --=DieCount|[$DieCount] + 1 --&gt;RollADie| --?[$DieCount] -lt [$NumDice]|Loop --+Results|[&amp;DieSummary] --X| --:RollADie| --=ThisRoll|1d6 --&amp;DieSummary|+ [$ThisRoll] --&lt;| }} and the result: The update should be up on the GIST later tonight (I'll post about it with full details and update the wiki).
1612384261
David M.
Pro
API Scripter
High five!
1612387428
David M.
Pro
API Scripter
Looking at stored settings: is there a way to delete them?
1612389367
Kurt J.
Pro
API Scripter
David M. said: Looking at stored settings: is there a way to delete them? This functionality will also be in the tonight's release.
1612391975

Edited 1612392072
Kurt J.
Pro
API Scripter
ScriptCards Version 0.0.10 is up on the Development GIST Added two new card settings : hideTitleCard and hideCard . Setting either to a non-zero value (the default) will cause either the title portion of the card (with the title and subtitle)&nbsp; or the whole card itself will not be output.&nbsp; Added support for string variables (--&amp;) : Sting variables are maintained as a separate list from Roll Variables and function in most of the same ways. The biggest difference is that string variables do not attempt to do roll evaluation when setting them. A string variable can be directly set: --&amp;MyString|Hello or text can be appended to a string variable by prefixing the content with a "+" sign: --&amp;MyString|+ World String variables can be referenced with the syntax [&amp;variablename] and do not support any properties (like .Total, etc from roll variables). Added Visual Effects statement type (--V) : The tag portion of the statement can be either "token" or "betweentokens", and the content portion is a list of parameters separated by spaces. For "token" effects, the parameters are SouceTokenID and EffectType ( --Vtoken|@{selected|token_id} burst-fire ). For "betweentokens" effects, the parameters are SourceTokenID, TargetTokenID, and EffectType ( --Vbetweentokens|@{selected|token_id} @{target|token_id} beam-magic ). The effect will play on the page that the source token is on. The EffectType specifiers follow the "shape"-"element" type system used in the FX dropdown (shapes like burst, nova, beam, breath, and elements like fire, magic, acid, poison). Added an Echo statement type (--E) : This is a simple statement that executes a sendChat command. The tag portion of the line is used as the speakingAs parameter and the content portion is used as the content of the message. Normal parsing occurs on the content and tags takes place before exeuction. For example: --eA ghost:|/em hovers around @{selected|character_name} Conditionals now support an If False branch :&nbsp; In a conditional, after the branch for true you can add a vertical bar (|) and a branch for a false result. None, one, or both branches can be gosub branches, and gosub branches still accept parameters as normal in both cases. Deletion of Settings Groups: The !sc-liststoredsettings command now also provides a button next to each setting group to allow them to be deleted. The Wiki page has been updated to reflect these changes.
1612411977
David M.
Pro
API Scripter
v10 looks awesome! Question about conditional text output syntax. Tried a few variations, but not getting expected results. I'm probably doing something stupid. With this syntax, the text always displays regardless of what value I set to "Roll"&nbsp; !scriptcard {{ --+Test| --=Roll|0 --?[Roll.Total] -eq 1|--+This shouldn't display| }} With this syntax, it never displays regardless of roll value !scriptcard {{ --+Test| --=Roll|1 --?[Roll.Total] -eq 1|+This should display| }} Is conditional direct text supported, or do I need to call a procedure or a goto? Having trouble with If/else combined with string variable assignment (so many pipes | maybe causing issues?), and also with passing different params to the same procedure to allow re-use, but it's late and I need some sleep so I'll save those for later :) Sorry for being such a pain!
1612438671
Kurt J.
Pro
API Scripter
David M. said: v10 looks awesome! Question about conditional text output syntax. Tried a few variations, but not getting expected results. I'm probably doing something stupid. With this syntax, the text always displays regardless of what value I set to "Roll"&nbsp; !scriptcard {{ --+Test| --=Roll|0 --?[Roll.Total] -eq 1|--+This shouldn't display| }} With this syntax, it never displays regardless of roll value !scriptcard {{ --+Test| --=Roll|1 --?[Roll.Total] -eq 1|+This should display| }} Is conditional direct text supported, or do I need to call a procedure or a goto? Having trouble with If/else combined with string variable assignment (so many pipes | maybe causing issues?), and also with passing different params to the same procedure to allow re-use, but it's late and I need some sleep so I'll save those for later :) Sorry for being such a pain! Conditionals only support branching, not conditional execution of other statement types. This was intentional to avoid confusion because line breaks are ignored by the script parser (same as PowerCards)... It was not uncommon for people to ask why something like: --?? $Attack.base == 20 ??|--One|Do Something --Two|Do something else --Three|Yet another thing Would run Two and Three even if Attack.base wasn't 20. Requiring branching add a little complexity when you only want to do one thing, but I think makes it more obvious what is going to execute.&nbsp;
1612440681
David M.
Pro
API Scripter
Got it, thanks for the clarification!