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

Need help new character creation macro with ScriptCard, ZeroFrame, & Muler

I'm trying to create a generic new character creation macro for my game. I have a snippet here to illustrate my problem: !script {{   --&Name|@{target|character_name}   --#title|Character Creation for [&Name]   --+Name = [&Name]|   --=Num|?{Enter Dexterity:|0}   --=Dex| [$Num] + 1   --+Dex = [$Dex]|   -->Dexterity|   --X|   --:Dexterity|  {& mule Hudson.Chart}   set.Hudson.Chart.Dexterity = 4/set    --<| }} This prints and sets correctly. When I replace the stand in fixed Muler commend with  {& mule [&Name].Chart} set.[&Name].Chart.Dexterity = [$Dex]/set to make it a generic macro it doesn't work. I have tried various possibilities using ZeroFrame and none have worked. Is it possible to make this work? If so how? Also obviously the whole macro will have many other attributes and abilities to set, will there have to be an increasingly more complicated structure necessary for each additional set?  
1667438287
timmaugh
Pro
API Scripter
Hey, James... you have to think of the metascripts as a series of loops before the destination script (ScriptCards) gets involved. The order of operations for a loop goes: Roll20 Parsing: ========================================   Abilities   Macros   Attributes (repeat these three up to 99 times)   Roll queries (up to 99 levels deep)   Inline Rolls Meta Toolbox Scripts: ==================================   one after another in whatever order you have them installed (without ZeroFrame) or sequenced (with ZeroFrame) If ZeroFrame is installed and detects that changes have been made, it initiates the loop over again. The caveat about subsequent loops is that after the first loop you no longer get roll queries, and you no longer get @{selected...} resolution... only resolution by character name. Then, once all of that is done and ZeroFrame detects no further work to do, it releases the message... which then gets picked up by ScriptCards. So. You can see you can't really use ScriptCards to feed information *into* a metascript operation... at least while you're in the same message stack. (I'll explain that in a minute). You can agnosticize the metascript operation with Roll20 constructions, since those get parsed before the metascripts get at the message: {&mule ?{Mule character|}.Chart } {&mule @{Target|Mule character|character_name}.Chart} ...and then use the same Roll20 construction for your get/set statements: set.@{Target|Mule character|character_name}.Chart.Dexterity/set New Message Stack If you absolutely need to use information from ScriptCards in your metascript operation, that's fine. You can absolutely construct the appropriate meta-syntax. The question, then, is: how do you get that to process? Your metascript window has closed, right? Half right. ScriptCards can issue new outbound commands... I think the SC syntax is to start a line with --@scripthandle| If you send a new message, you start a new message with it's own metascript loop. While you can't further alter the initial message (that has already gone through the metascript loop), you can do things like set mule variables, etc. If you don't actually need the outbound message to land in another script, just use a dummy handle for a nonexistent script: --@meta|{^&  mule [&Name].Chart} set^.[&Name].Chart.Dexterity = [$Dex]/^set Note the carets (^) used to break up the metascript syntax. I believe the ^ is the ScriptCards deferral character, but I think you can actually change that, too, so whatever you want to use, just follow ScriptCards syntax for establishing the deferral character. Whatever character you use, use it like I did to break up the character strings that would trigger a metascript (Muler, in this case) from detecting a syntax token on which it needs to take action. By using the deferral character, you hide it at the initial metascript loop. Then ScriptCards prepares your information, builds the syntax, removes the deferral character, and issues a new command. For the new message, the metascripts detect their work (Muler, in this case, recognizes a variable has to be set), and they do their thing before stepping out of the way. Then the message carries on, waiting to be picked up by a script that watches for !meta ... which you don't have. Or, if you do... pick something else. =D
I am not sure where things should be. Here is how I put things. !script {{ {&mule ?{Mule character|}.Chart } {&mule @{Target|Mule character|character_name}.Chart}     --&Name|@{target|character_name}   --#title|Character Creation for [&Name]   --+Name = [&Name]|   --=Num|?{Enter Dexterity:|0}   --=Dex| [$Num] + 1   --+Dex = [$Dex]|   -->Dexterity| --@meta|{^& mule [&Name].Chart} set^.[&Name].Chart.Dexterity = [$Dex]/^set   --X|   --:Dexterity|  set.@{Target|Mule character|character_name}.Chart.Dexterity/set    --<| }} I assumed all the set statements would be made in a section after all the interaction. No errors but I had to choose the target twice, which I expected, but I had to enter the name for 'Mule Character,' which I did not expect. Unfortunately Dexterity was not changed to the new value.
I see now that  {&mule ?{Mule character|}.Chart } is producing the Input Value window to enter the name. I tried removing that line and it worked the same (i.e. without setting Dexterity but the card was correct.) It appears to do the same thing as the line below it, just a different way of achieving the same thing.
1667451655
timmaugh
Pro
API Scripter
Yes, those lines were just options to accomplish the same task. Also, you only need one solution or the other... you can either use a Roll20 construction to set up the metasyntax (i.e., the targeting statement), OR you can use ScriptCards to construct your syntax and then dispatch it with the --@meta| statement. Just like you don't need both of the roll query lines I gave as examples, you don't need both solutions in your ScriptCard. =D The only difference between them is that the targeting-statement-version will run *before* your ScriptCard, but require you to target a token, while the ScriptCards-constructing-the-metasyntax version will run during/after your ScriptCard and not ask for any targeting. I know it can get deep in the meta, so if this isn't clear, post back.
I removed the {&mule ?{Mule character}.Chart} construction.  I’m trying to figure out why it is not setting   Hudson.Chart.Dexterity as it should. I used your ZeroFrame log command. In LOOP 1 I can follow the log of the program running. Next it logs MULERGET as Green so something needs to be changed and the log shows everything LOOP 1 showed except the log command and loading Hudson.Chart. MULERSET is Blue so nothing needs to be changed and so nothing logged. I don’t understand why the GET has changes and SET does not.   IN LOOP 2 it logs exactly what was logged in MULERGET in LOOP 1. MULERGET, MULERSET, and OUTRO are Blue and Final Message logs exactly MULERGET in LOOP 1 again. I can follow the ScriptCard and Muler commands but why some substitutions are shown, e.g.  {&mule Hudson.Chart} and others are not, e.g. -+Name = [&Name]| I don’t have enough information about log to understand. What have I done wrong that it is not setting Hudson.Chart.Dexterity? 
1667513218
timmaugh
Pro
API Scripter
That MulerGet portion of the log handles both the loading of the mules and the getting of any variables... so after that first MulerGet, you can see that the {&mule...} statement has been consumed. Your set command isn't running because you've opted for the deferred message to do the setting. It won't be detected in this message stack. I'm not super fluent in ScriptCards, but try this alteration to your last posted macro syntax. Note, I'm going to drop a log command in the initial message AND in the deferred message, so you can see both. This should give you 2 log panels. It's asynchronous as to which will finish first, but given that sending the new outbound message is just about the last thing in this macro I would think you'll see them in the correct order. !script {{   --&Name|@{target|character_name}   --#title|Character Creation for [&Name]   --+Name = [&Name]|   --=Num|?{Enter Dexterity:|0}   --=Dex| [$Num] + 1   --+Dex = [$Dex]|   -->Dexterity|   --X|   --:Dexterity| --+meta|{^& mule [&Name].Chart} set^.[&Name].Chart.Dexterity = [$Dex]/^set{^&log}   --@meta|{^& mule [&Name].Chart} set^.[&Name].Chart.Dexterity = [$Dex]/^set{^&log}   --<| }} {&log} Just to make it perfectly clear: you don't need to do anything in the first pass of metascript operations... you only need to take action after SC has constructed the info for you. So all of the muler syntax can be deferred and sent in the new outbound message. (FYI, After consulting with resident ScriptCards sage, David M., I added a line to output the text of the outbound message to the chat so you can review. Thank you, David!)
Reply keeps eating my posts. Is it working now?
Apparently it will not let me post the ZeroFrame log (at least as I'm trying to do it.) So I'll try without it. First let me say that I appreciate very much all the time and effort you have put in to help me with my problem. I ran the program you provided above and it still didn't set Dexterity. I wrote a long explanation of how I analyzed the program and the Roll20 Reply ate it, twice. So I will cut to my conclusion which comes from the log. The FINAL MESSAGE on the log is "!meta set.Hudson.Chart.Dexterity = 9/^set"  Note that in the FINAL MESSAGE the first set has had its circumflex removed but the second one has not had it removed "9/^set" I checked this using a MulerSet starting with "!meta" with "9/^set" and it didn't set Dexterity but if I substituted "9/set" it did set Dexterity to 9. I tried just removing the circumflex from the last set in the your program and as I expected it didn't work. Does the circumflex need to be in a different place? I know you sometimes use backslashes to postpone things, should those be used instead or in addition? I know vaguely what is going on, but the details escape me. Thank you some much for your help, I do appreciate it. May I impose on you yet again?
1667539231
timmaugh
Pro
API Scripter
I think what is happening is that Kurt has the ScriptCard deferral character looking for specific metascript-type constructions... things like: {&... If it sees: {^&... ...then it will remove the deferral character. Same with the set^. I think the /^set is slipping past that detection since it doesn't fit the pattern. I'll try to point this out to Kurt to see if there's a way he can address the gap, but for your usage I think we can still manage. We'll just get creative. We need something that will get removed *after* ScriptCards has dispatched the outbound message. The backslashes you mention having seen me use sometimes come from ZeroFrame, but ZeroFrame deferral wouldn't work in this instance: since ZeroFrame will act in the initial metascript processing phase, it will remove those backslashes (one level at a time) so long as it detects that metascript work has been done. And since you have a {&log} statement in the initial message scope, that constitutes "work" (any change to the message). Instead, let's try moving the deferred log statement into the set statement in the place of the SC deferral character: --@meta|{^& mule [&Name].Chart} set^.[&Name].Chart.Dexterity = [$Dex]/{^&log}set What should happen here is that SC will build the information, remove the caret from {^& mule...  ,  set^. , and {^&log} , and dispatch the outbound command. When the new message enters metascript processing, ZeroFrame will remove the deferred log statement, turning this: /{&log}set ...into... /set That should clear the way for Muler to set the value. If it works, you'll need to keep the deferred log statement in your macro until Kurt can patch that small gap in the string parsing. Don't forget you'll need to make this same change on the line above in your macro (that prints the outbound command to chat) -- or simply delete that line once you know it's working. Let us know how this goes!
Almost! Using the "/{^&log}set" did indeed handle the problem I had noticed of "/^set". However the FINAL MESSAGE does not include "{& mule Hudson.Chart}" I  had assumed it had been opened earlier and was not needed now. Apparently not. Here's the script: !script {{   --&Name|@{target|character_name}   --#title|Character Creation for [&Name]   --+Name = [&Name]|   --=Num|?{Enter Dexterity:|0}   --=Dex| [$Num] + 1   --+Dex = [$Dex]|   -->Dexterity|   --X|   --:Dexterity|   --@meta|{^& mule [&Name].Chart} set^.[&Name].Chart.Dexterity = [$Dex]/{^&log}set   --<| }} {&log} Here's the first log: The "--@meta|{^& mule [&Name].Chart}" is in the set command in the FINAL MESSAGE. Here's the second log: As you can see the substituted "{& mule Hudson.Chart}" disappeared from the set command in the FINAL MESSAGE of the second log. It was there in LOOP 1 but missing in LOOP 2. It appears to have been taken out in the MULERGET stage in LOOP 1.
1667576601
timmaugh
Pro
API Scripter
That is weird, James. I tested that set statement against the regex that should be detecting it (I had to type the text, but provided there's no special characters in there, that should work), and the regex found it, no problem. You are correct that the {&mule} statement gets consumed during the MulerGet portion... that's when the mule and all the variables get loaded into the message, so they are available when the MulerSet portion of the loop comes around. Part of the set command being replaced is that the mule is actually loaded in the message, however... so I might wonder whether you have properly identified your character (ie, do you actually have a character named "Hudson" with a mule named "Chart"), except that you also said that your command works if you just type it. So that can't be it. One last test. If this doesn't work, you can invite me via PM and promote me to GM so I can poke around and see what is actually happening. First, try this... Move the {&log} statement (the one that is breaking up the /set construction) back to the end of that line. In its place, leave 2 backslash characters (the ZeroFrame deferral character). I know I said ZF deferral wouldn't work in this case, but it's more nuanced than that: if ZF detects any metascript work has gone on, it strips a deferral backslash and runs another loop. The {&log} statement of the original message would constitute "work" (the message command line has changed), so that would normally trigger ZF to strip the \ and start another loop... exposing the /set construction too early. You can either remove the outer {&log} statement to remove the only metascript work going on for the initial message or you can defer the /set construction twice (two backslashes). If you're interested, the process should go: =============== ORIGINAL MESSAGE =============== == METASCRIPTS == ...original message enters metascript loop => -- LOOP 1 ---------- {&log} statement detected - triggering another loop after this one no other metascript work ZeroFrame strips one backslash (turning /\\set into /\set )and initiates another loop -- LOOP 2 ---------- no further metascript work ZeroFrame releases the message == STANDARD SCRIPTS == ScriptCard picks up the message, constructs information, strips out deferral characters, and issues second message =============== SECOND MESSAGE =============== == METASCRIPTS == ...second message enters metascript loop => -- LOOP 1 ---------- {&log} statement is detected - triggering another loop after this one MulerGet detects mule, loads variables no other metascript work ZeroFrame strips one backslash (turning /\set into /set ) and initiates another loop -- LOOP 2 ---------- MulerSet detects set statement, sets variable - triggering another loop no other metsacript work ZeroFrame looks for backslashes to remove (there are none), and initiates another loop -- LOOP 3 ---------- no metascript work ZeroFrame releases the message == STANDARD SCRIPTS == Nothing picks up the !meta handle Try that and see if works better. Like I said, if it doesn't I'll jump in and see if I can figure out what's going on.
1667576689
timmaugh
Pro
API Scripter
To be clear, making the change to the ScriptCards macro line should result in this: --@meta|{^& mule [&Name].Chart} set^.[&Name].Chart.Dexterity = [$Dex]/\\set  {^&log}
I substituted your line and when I ran it the final message was " !meta set.Hudson.Chart.Dexterity = 7/\set " and Dexterity wasn't changed. Since there was an unwanted backslash in the set command I tried removing one of the backslashes and running it again. This time the final message was what we wanted " !meta set.Hudson.Chart.Dexterity = 7/set " but Dexterity didn't change.  It looks like the ultimate option is required and I will PM you.