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] ScriptCards - Thread #2

Hey Tristan, So I did a stripped down example. Obviously your scriptcard will generate the weapons and do all that you need it to do but I wanted to show a couple things that might work for you with the reentrant buttons. !script {{ --/|DUMMY VARIABLES FOR THE EXAMPLE --/|IN YOUR REAL SCRIPT THESE WOULD ALL BE GENERATED --~|array;define;WeaponArr;Small Wood Blowgun;Medium Wood Bard's Friend;Medium Stone Pick, heavy;Medium Stone Urgrosh, dwarven --h:WeaponHash("Small Wood Blowgun-weight")|1.00 lbs. --h:WeaponHash("Small Wood Blowgun-cost")|2.5 cp --h:WeaponHash("Medium Wood Bard's Friend-weight")|0.50 lbs. --h:WeaponHash("Medium Wood Bard's Friend-cost")|10 cp --h:WeaponHash("Medium Stone Pick, heavy-weight")|4.50 lbs. --h:WeaponHash("Medium Stone Pick, heavy-cost")|6 cp --h:WeaponHash("Medium Stone Urgrosh, dwarven-weight")|9.00 lbs. --h:WeaponHash("Medium Stone Urgrosh, dwarven-cost")|37.5 cp --#title|Re-Entry Whisper Example --~ts|system;date;getdatetime --#reentrant|WeaponGeneration[&ts] --%weapon|foreach;WeaponArr --+|[rbutton][&weapon]::WhisperDescription;[&weapon][/rbutton] --%| --:Done| --X| --:WhisperDescription|WeaponName --#whisper|self --+DEBUG|Sending Player: [&SendingPlayerName] --+|[c][b][&reentryval] Description[/b][/c] --+Weight|[:WeaponHash("[&reentryval]-weight")] --+Cost|[:WeaponHash("[&reentryval]-cost")] --^Done| }} So you can see that all players will get the original Scriptcard output with the buttons but when a player clicks, you can see that --#whisper|self is used to limit the output of the descriptions to just the player that clicked. I added the DEBUG output line with the &SendingPlayerName variable to illustrate that only the clicking player sees the description they clicked. Since you mentioned that variable collision was an issue, I used a timestamp in the --#reentrant parameter to help prevent that. I am guessing that you had a static phrase for --#reentrant| previously, eg. `--#reentrant|WeaponGenerator` and that was keeping variables in the same namespace. With a timestamp, each time you call the ScriptCard it should set reentrant to a unique value to help prevent collisions in the variable stash. Hopefully those things are helpful to you.
1725500206

Edited 1725543639
Joshua thank you so much! I managed to get them working! I used [&LoopCounter] saved as the reentryval. it was actually pretty simple!
1725634386

Edited 1725634556
Hello, is there a way to have a button in a Handout link? Currently, when I write : `!scriptcard  {{ --#titleCardBackground|#66482d --#oddRowBackground|#FFF3E7 --#evenRowBackground|#ECD2BA --#tableBorderRadius|1 --+|[c][button]Test INT::!cof-jet INT 10 _succes Se souvient du code _echec Malus cumulatif de -2 pour le prochain essai (1 fois/j.)[/button][/c] --] }} It generates this : The problem is that it replaces the ":" with the character ":", which seems to prevent the button from appearing. Is there a way to work around this? Thanks in advance!
Hey all,  I'm experiencing a weird error and I want to know if the error is mine.  So this is the code running: --&TargetID|-O698TaFKp3FUDiw6OdM --&TokenID|[*[&TargetID]:t-id] --!t:[&TokenID]|bar1_value:-=[$DamageAmount] And this odd error appears in the Mod console: "ContentIn: [*[&TargetID]:t-id] Match: [&TargetID], vName: TargetID, replacement -O698TaFKp3FUDiw6OdM" "Line Counter: 76, Tag:&TokenID, Content:" "ContentIn: !t:[&TokenID] Match: [&TokenID], vName: TokenID, replacement " "ContentIn: bar1_value:-=[$DamageAmount] Match: [$DamageAmount], vName: DamageAmount, vSuffix: Total, replacement 7" "Line Counter: 77, Tag:!t:, Content:bar1_value:-=7" "Error updating/adding object Unexpected token u in JSON at position 0, thisTag: !t:, thisContent: bar1_value:-=7" "ContentIn: ?[*[&TokenID]:t-bar1_value] -le 0 Match: [&TokenID], vName: TokenID, replacement " It looks like it correctly replaces the Target ID in the first line, but it isn't passing any token ID to the &TokenID string variable.  Why? Thanks!
Erik, What is the TargetID value you have, is that a character id? A token id? Are you hardcoding it in your original ScriptCard or is this a test? If it was just a test, can you post the original code you were trying to use and how you are getting that ID?
It's a character ID hardcoded for a test of a much larger subroutine. The snippet I posted is just the test code. 
I don't think you can get a token id directly from a character id in that object lookup. A character could have any number of tokens on any given page or spread out over multiple pages. Quick example: !script {{ --&CharID|@{selected|character_id} --+CharID|[&CharID] --+Token Property|[*[&CharID]:t-top] --+Character Attribute|[*[&CharID]:hp] }} One typical way would be to compare against the `array;pagetokens` function. Kurt has a procedure in his system neutral library  LibSN_GET_TOKENS_REPRESENTING  that uses pagetokens function to get a character id's tokens on a page. Here is a function I wrote before I knew about Kurt's snlib function to do much the same thing for the currently active page with the player ribbon. --/|GetTokenIDForCharacter returns the token-id for the current page with the player's ribbon for the corresponding character id --:GetTokenIDForCharacter|CharacterID;StringVariableToSetTokenID --~libTokenNum|array;pagetokens;libTokenArr;[*C:playerpageid];char --?[&libTokenNum] -eq 0|&[%2%];NoTokensError --=LastIndex|[&libTokenNum] - 1 --&[%2%]|NotFoundError --%loopCounter|0;[$LastIndex] --&libTID|[*[@libTokenArr([&loopCounter])]:t-id] --&Reps|[*[@libTokenArr([&loopCounter])]:t-represents] --?[&Reps] -eq [%1%]|[ --&[%2%]|[&libTID] --%!| --]| --%| --<|
Super useful, thanks!
1725987546

Edited 1726121247
I have made a D&D 3.5 (AD&D 2e works too) and PF1e  non-euclidean distance card, hopefully it will be useful for someone else! It uses the #sourceToken/#targetToken to work. It now counts from the closest edge of tokens and with my testing works with all sized tokens! Seriously useful! !script {{ --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} --?[*S:t-height] -gt 70|BigBoi --?[*S:t-width] -gt 70|BigBoi --=source_Height|[*S:t-height]/70 / 2 - 1 {CEIL} --=source_Width|[*S:t-width]/70 / 2 - 1 {CEIL} --=target_Height|[*T:t-height]/70 / 2 - 1 {CEIL} --=target_Width|[*T:t-width]/70 / 2 - 1 {CEIL} --=source_Y|[*S:t-top]/70 --=source_X|[*S:t-left]/70 --=token_diff_height|[$target_Height] + [$source_Height] --=token_diff_width|[$target_Width] + [$source_Width] --=target_Y|[*T:t-top]/70 --=target_X|[*T:t-left]/70 --=Y_diff|[$source_Y]-[$target_Y] {ABS} {FLOOR} --=X_diff|[$source_X]-[$target_X] {ABS} {FLOOR} --?[$Y_diff] -lt [$token_diff_height]|[ --=Y_diff|1 --]|[ --=Y_diff|[$Y_diff] - [$token_diff_height] {ABS} --]| --?[$X_diff] -lt [$token_diff_width]|[ --=X_diff|1 --]|[ --=X_diff|[$X_diff] - [$token_diff_width] {ABS} --]| --?[$Y_diff] -lt [$X_diff]|[ --=X_diff_non_euclidean|[$X_diff]-[$Y_diff] --=X_diff_non_euclidean|[$X_diff_non_euclidean] *5 --=Y_diff_non_euclidean|[$Y_diff]*1.5 {FLOOR} *5 --=Total_distance_non_euclidean|[$X_diff_non_euclidean]+[$Y_diff_non_euclidean] --+|[$Total_distance_non_euclidean] TOTAL FT. --]|[ --=Y_diff_non_euclidean|[$Y_diff]-[$X_diff] --=Y_diff_non_euclidean|[$Y_diff_non_euclidean]*5 --=X_diff_non_euclidean|[$X_diff]*1.5 {FLOOR} *5 --=Total_distance_non_euclidean|[$X_diff_non_euclidean] + [$Y_diff_non_euclidean] --+|[$Total_distance_non_euclidean] TOTAL FT. --]| --X| --:BigBoi| --=source_Height_even_odd|[*S:t-height]/70 --%loop|until;[$source_Height_even_odd] -lt 1 --=source_Height_even_odd|[$source_Height_even_odd]-2 --%| --=source_Width_even_odd|[*S:t-width]/70 --%loop|until;[$source_Width_even_odd] -lt 1 --=source_Width_even_odd|[$source_Width_even_odd]-2 --%| --=target_Height_even_odd|[*T:t-height]/70 --%loop|until;[$target_Height_even_odd] -lt 1 --=target_Height_even_odd|[$target_Height_even_odd]-2 --%| --=target_Width_even_odd|[*T:t-width]/70 --%loop|until;[$target_Width_even_odd] -lt 1 --=target_Width_even_odd|[$target_Width_even_odd]-2 --%| --?[$source_Height_even_odd] -eq 0|[ --=source_Height|[*S:t-height]/70 / 2 {CEIL} --]|[ --=source_Height|[*S:t-height]/70 / 2 - 1 {CEIL} --]| --?[$source_Width_even_odd] -eq 0|[ --=source_Width|[*S:t-width]/70 / 2 {CEIL} --]|[ --=source_Width|[*S:t-width]/70 / 2 - 1 {CEIL} --]| --?[$target_Height_even_odd] -eq 0|[ --=target_Height|[*T:t-height]/70 / 2 {CEIL} --]|[ --=target_Height|[*T:t-height]/70 / 2 - 1 {CEIL} --]| --?[$target_Width_even_odd] -eq 0|[ --=target_Width|[*T:t-width]/70 / 2 {CEIL} --]|[ --=target_Width|[*T:t-width]/70 / 2 - 1 {CEIL} --]| --?[$source_Height] -gt 0|[ --=source_Height|[$source_Height]-1 --]|[ --]| --?[$source_Width] -gt 0|[ --=source_Width|[$source_Width]-1 --]|[ --]| --=source_Y|[*S:t-top]/70 --=source_X|[*S:t-left]/70 --=token_diff_height|[$target_Height] + [$source_Height] --=token_diff_width|[$target_Width] + [$source_Width] --=target_Y|[*T:t-top]/70 --=target_X|[*T:t-left]/70 --=Y_diff|[$source_Y]-[$target_Y] {ABS} {FLOOR} --=X_diff|[$source_X]-[$target_X] {ABS} {FLOOR} --?[$Y_diff] -lt [$token_diff_height]|[ --=Y_diff|1 --]|[ --=Y_diff|[$Y_diff] - [$token_diff_height] {ABS} --]| --?[$X_diff] -lt [$token_diff_width]|[ --=X_diff|1 --]|[ --=X_diff|[$X_diff] - [$token_diff_width] {ABS} --]| --?[$Y_diff] -lt [$X_diff]|[ --=X_diff_non_euclidean|[$X_diff]-[$Y_diff] --=X_diff_non_euclidean|[$X_diff_non_euclidean] *5 --=Y_diff_non_euclidean|[$Y_diff]*1.5 {FLOOR} *5 --=Total_distance_non_euclidean|[$X_diff_non_euclidean]+[$Y_diff_non_euclidean] --+|[$Total_distance_non_euclidean] TOTAL FT. --]|[ --=Y_diff_non_euclidean|[$Y_diff]-[$X_diff] --=Y_diff_non_euclidean|[$Y_diff_non_euclidean]*5 --=X_diff_non_euclidean|[$X_diff]*1.5 {FLOOR} *5 --=Total_distance_non_euclidean|[$X_diff_non_euclidean] + [$Y_diff_non_euclidean] --+|[$Total_distance_non_euclidean] TOTAL FT. --]| }}
Hi, I current use this  !setattr --sel --modb --class_resource|+1 charsetattr command to add to a resource without exceeding it's maximum. How would a replicate this command in a script card ?
1726224672

Edited 1726261647
You can call the same API in scriptcards --@setattr| _sel _modb _class_resource|+1
Tristan, Thanks for this. I've tried it out and If I keep running then same command the resource total goes onto exceed the maximum. Interesting this also happen just running the CharSetAttr command as well so don't believe this is a scriptcard issue. If I change the command to hp the hp maximum isn't exceeded regardless of how many times I run the command. Any ideas ? Maybe I need to raise it a separate ChatSetAttr question 
1726247022

Edited 1726248032
--@modbattr|_charid @{selected|character_id} _water|1 --@setattr| _sel _modb _water|1 They both work with in attribute that has a |max in my game. Replace 1 with -1 and try again, does the go below 0? If not then its working as intended and that attribute does not have a max value set. Most character sheets will have a separate value next to it called (same_name)|max for when it is relevant, check if that is how it is labeled. I also added another way of writing the command as well. scriptcards has there own form at of changing attributes that you can check here --!a:@{selected|token_id}|water:+=-1 this is an example of what scriptcards uses, it doesn't check for max and min values so easily.
Tristan, Cracked it. I had the max value linked to pb. I removed that and entered 2 instead and now all works fine. Cheers for your help
1726371833

Edited 1726371897
Has anyone managed to get a "status marker tracker" working? I have one that works fantastic in my opinion but it has one MAJOR issue, token markers over counter 9 (green@9) do NOT display on token, they DO still exist on the token and I can decrement normally but the token will not be displayed until the counter has hit 9 or lower. My immediate thought is to add another identical counter through custom markers (that has a different name) to the token but strip all numbers but the last number and simply use that token? I haven't tried decrementing multiple tokens, maybe displaying multiple markers to represent digits similar to the Fly api? I'm worried I'll be running too much code and slowing my game down. I was hoping to be able to share this when it is better coded and fully implemented so if you have a better solution than adding custom markers I would love to hear it.  I am also interested in cleaning up my code as I'm planning to add more scriptcard automation to my game but I don't want to bog down the sandbox with needless loops my code so far is bellow. Uses token-mod to trigger when needed.  -->BlindedPlayerRemove| just gets code to print and alter either attributes/tokens, depending on the status. ----ScriptCards_Triggers---- ----change:graphic---- !script {{ --#title|Status +++D&D_3.5e+++ --/|TRIGGER_REPLACEMENTS --&CharId|[*[&GraphicNew_id]:character_id] --&Sheet|[*[&GraphicNew_id]:npc-show] --&NewMarkers|[&GraphicNewstatusmarkers] --&OldMarkers|[&GraphicOldstatusmarkers] --%RemovalLoop|until;[$LoopsToRemove] -eq 9 --=LoopsToRemove|[$LoopsToRemove]+1 --&LoopsToRemoveString|[$LoopsToRemove.Raw] --~NewMarkers|string;replace;@[&LoopsToRemoveString];;[&NewMarkers] --~OldMarkers|string;replace;@[&LoopsToRemoveString];;[&OldMarkers] --~NewMarkers|string;replace;[&LoopsToRemoveString]@;;[&NewMarkers] --~OldMarkers|string;replace;[&LoopsToRemoveString]@;;[&OldMarkers] --%| --~|array;fromstring;NewMarkersArray;,;[&NewMarkers] --~|array;fromstring;OldMarkersArray;,;[&OldMarkers] --~NewMarkerString|array;stringify;NewMarkersArray --~OldMarkerString|array;stringify;OldMarkersArray --~|array;remove;NewMarkersArray;[&OldMarkerString] --~|array;remove;OldMarkersArray;[&NewMarkerString] --~NewMarkerString|array;stringify;NewMarkersArray --~OldMarkerString|array;stringify;OldMarkersArray --/|DEBUG --+|New Marker|[&NewMarkerString] --+|Removed Marker|[&OldMarkerString] --?"[&NewMarkerString]" -eq "bleeding-eye"|BlindedAdd --?"[&OldMarkerString]" -eq "bleeding-eye"|BlindedRemove --?"[&NewMarkerString]" -eq "tread"|FlatFootedAdd --?"[&OldMarkerString]" -eq "tread"|FlatFootedRemove --:Return| --X| --:BlindedAdd| --+|[&GraphicNewname] has been [b]Blinded[/b] -->Blinded| --?:"[&Sheet]" -eq "1"|-->BlindedPlayerAdd| --?:"[&Sheet]" -eq "2"|-->BlindedNpcAdd| --^Return| --:BlindedRemove| --+|[&GraphicNewname] is no longer [b]Blinded[/b] --@token-mod| _ids [&GraphicNew_id] _set statusmarkers|-bleeding-eye --?:"[&Sheet]" -eq "1"|-->BlindedPlayerRemove| --?:"[&Sheet]" -eq "2"|-->BlindedNpcRemove| --^Return| }} To decrement , I have added this code to the change:campaign:turnorder script under trigger examples on the gihub found here --:Decrement_Marker| --@token-mod| _ids [&TID] _set statusmarkers|bleeding-eye:-1 --+|[&TID] [&name] --^Return_Decrement|
1726425858

Edited 1726425928
I’ve written a generic Script that works well for me.  There is a limitation to numeric values 0 through 9.  I’ve seen some people use the red/blue/green dots to represent 100’s/10’s/1’s spot.  To represent the number 193 you would place a Red 1, Blue 9 and Green 3 status marker on the token.   As a side note, I’ve been pondering my next big project and it does have some relationship to status markers.  That being an Event Tracker , where the events could be short lived (Vex, Frightened, Held, Stunned, …), medium length (Rage, Inspired, Guidance, Spells, …) and some are longer term (cursed, exhausted, multi-day countdown, …).   The interface to add them would likely be a Wizard (step by step) implemented with Scriptcards. I would output the results to a sorted table via handout, which would also support the removal of events.   I would store the events in State Memory, so the data persists across sessions. For short term, combat, and fixed length events (“Until the end of players next turn”), it would automatically remove itself from the Events log at the right time, using the Turnorder tracker. It would also automatically add/remove status markers based on the type of Event being created, if one was required.  
1726434922

Edited 1726447826
That definitely sounds great! Tracking statuses through multiple events sounds wild! A lot of people would love that level of automation. With my limited capabilities I might have to stick to if marker is added/removed do X while I wait for someone more capable lol. I'm planning to change the 'remove from string' loop to just use 'contains "x"' to process less tho I'm a bit worried it will cause issues. Contains 'green" but if there is a marker called "green_clover_01:0002222" it would false trigger. I have noticed that markers sometimes print with #@ or @#. I'm not sure if it's the processing I have done to the string that has caused that tho. I like the idea of using colors as a denomination, it takes up a lot of space on the token but the statuses will be printed on each turn anyway so I doubt it matters too much.
Hi, I wonder if someone could help me debug an issue that I am currently having retrieving values from an object in a 5e by Roll20 Character Sheet. Here is an example code snippet.  In the actual code, I am retrieving the currentSource dynamically. !script{{ --title|Wand Charges --#sourcetoken|@{selected|token_id} --&charID|@{selected|character_id} --&currentSource|repeating_resource_$0_resource_left --=currentCharges|[*O:[&charID]:attribute:[&currentSource]] --=maxCharges|[*O:[&charID]:attribute:[&currentSource]_max] --+Seeker Wand Charges|[$curCharges.Text] / [$maxCharges.Text] }} I intend to set up the script to be able to eventually be used to check if charges are either maxed out, or are down to 0 before applying an effect that would either use or boost the charges.  I have tried several variants of * references to try to retrieve the data, but I always seem to get an empty string for the currentCharges, and "false" for the max charges, although those values are currently 3 and 7 respectively on that character sheet
Hey Lawrence, For that section of the 2014 5e sheet I recommend using Lib5E_FIND_RESOURCE from Kurt's 5e library . Make a handout, change the name to ScriptCards Library 5eLib, copy that raw github output into the Description & Notes section, and then you can add +++5eLib+++ to your ScriptCard and use those functions.  Wiki link to Library section Also  Nick Olivo has a video on ScriptCard libraries  if you haven't used them before. Once you have the library handout created, your ScriptCard above would look more like: !script {{ --&ResourceName|WandName +++5eLib+++ --#title|Wand Charges --#sourcetoken|@{selected|token_id} -->Lib5E_FIND_RESOURCE|[*S:character_id];[&ResourceName];ResName;ResValue --+Seeker Wand Charges|[$ResValue.Text] / [*S:[&ResValue]^] }} where you'd change the top line to set the string variable &ResourceName to whatever the name of your wand's resource is. Using that library will search for the name in that section where the top 2 resources are standard attributes with names like class_resource and other_resource and the other resources are repeating attributes with names like repeating_resource_-MyVdiK6ZDROJtMHGdfs_resource_left. Let me know if you have any questions.
1726928932
timmaugh
Pro
API Scripter
Tristan P. said: Has anyone managed to get a "status marker tracker" working? I have one that works fantastic in my opinion but it has one MAJOR issue, token markers over counter 9 (green@9) do NOT display on token, they DO still exist on the token and I can decrement normally but the token will not be displayed until the counter has hit 9 or lower. My immediate thought is to add another identical counter through custom markers (that has a different name) to the token but strip all numbers but the last number and simply use that token? I haven't tried decrementing multiple tokens, maybe displaying multiple markers to represent digits similar to the Fly api? I'm worried I'll be running too much code and slowing my game down. Hey Tristan... just to throw one possibility at you... I don't know if ScriptCards takes advantage of (and exposes to you) the ability to put multiple instances of the same marker on a token the way TokenMod does, but if so, Fetch offers a construction to get all of the values as if they were a single number (100s place, 10s place, and 1s place). For instance, for the selected token's "blue" markers, you could use: @(selected.status.blue?all) You can use other token references other than selected, and obviously other token names. Again, not sure if ScriptCards offers the functionality itself to implement multiple copies of the same marker, or if you have to use TokenMod, but here is how TokenMod might do it: !token-mod --set statusmarkers|-blue[]|blue[]:2|blue[]:4|blue[]:2 So you'd just have to segment your value over various powers of 10 in the application, removing all "blue" markers that were there, first. This comes with the caveat that metascripts run before ScriptCards, so you can't use ScriptCards to generate/modify the value IN THE SAME MESSAGE where you want to use the Fetch construction to read the concatenated value. If you use the Fetch construction in *that* message, it will process first, before ScriptCards has time to work. But you could use reentrant syntax. Or you could set the value using one scriptcard call, and then use the Fetch construction anywhere you needed to later refer to that new value (as shown in the image, simply appending it to a string message output to chat).
Joshua N. said: Hey Lawrence, For that section of the 2014 5e sheet I recommend using Lib5E_FIND_RESOURCE from Kurt's 5e library . Make a handout, change the name to ScriptCards Library 5eLib, copy that raw github output into the Description & Notes section, and then you can add +++5eLib+++ to your ScriptCard and use those functions.  Wiki link to Library section Also  Nick Olivo has a video on ScriptCard libraries  if you haven't used them before. Once you have the library handout created, your ScriptCard above would look more like: !script {{ --&ResourceName|WandName +++5eLib+++ --#title|Wand Charges --#sourcetoken|@{selected|token_id} -->Lib5E_FIND_RESOURCE|[*S:character_id];[&ResourceName];ResName;ResValue --+Seeker Wand Charges|[$ResValue.Text] / [*S:[&ResValue]^] }} where you'd change the top line to set the string variable &ResourceName to whatever the name of your wand's resource is. Using that library will search for the name in that section where the top 2 resources are standard attributes with names like class_resource and other_resource and the other resources are repeating attributes with names like repeating_resource_-MyVdiK6ZDROJtMHGdfs_resource_left. Let me know if you have any questions. Hi Joshua, Thank you for your help.  I am actually using code taken from that library and modified to find and return the value that I am using for "currentSource".  What I am doing is to return that to the calling code, and then work with the value and the max individually. However, your suggested code made me look at some alternatives, and I got the following to work: !script{{ --title|Wand Charges --#sourcetoken|@{selected|token_id} --&charID|[*S:character_id] --&currentSource|repeating_resource_$0_resource_left --=curCharges|[*[&charID]:[&currentSource]] --=maxCharges|[*[&charID]:[&currentSource]^] --+Seeker Wand Charges|[$curCharges.Text] / [$maxCharges.Text] }} I am not sure why [*S:character_id] worked, where @{selected|character_id} didn't, but I also found that I could get the code to work with the * object_id: syntax. I also had missed that "_max" was unreliable, and the substitution of ^ did the trick there.
Question. Using the 5E Sheet - testing the ScriptCard Libraries functions. I loaded the dnd5elib and was using the Lib5E_DeductSpellSlot function to deduct a LVL 1 slot however the function bumps up the slots_expended by two(??? see the code) and the sheet show a plus 2 amount in slots remaining which is incorrect. Is there a character attribute that corresponds to the "slots" remaining" field? It looks like "slots_expeneded" is tied to slots remaining which is weird. Could be me! !script {{ +++dnd5elib+++ --Lsettings|@{selected|token_name} --#title|Update Spell Slot --#emoteState|1 --#sourceToken|@{selected|token_id} --&CharID|@{selected|character_id} -->Lib5E_DeductSpellSlot|@{selected|character_id};1 }}
1727790917

Edited 1727791006
I was going to post this in the Working and Sharing forum, but it aged out. This script creates a hashtable of all of the characters in the journal, with their name as the keys, and their ID as the value, allowing you to look up character IDs by name. It checks the journal folder for all objects in the journal, then scans through those objects for ones with an ID that starts with a - (required for a valid object ID).  If it appears to have a valid object ID, then it  checks if it has a type of "character".  If an object is a character, it then gets the name and adds the character and its ID to the hash table.  Once it has finished checking all objects, it then stores the hashtable in persistent storage for later use. !script {{ --&folders|[*C:journalfolder] --~|array;fromstring;objArray;,;[&folders] --=testValue|1 --%curItem|foreach;objArray --=itemIndex|[&curItem(indexof,-)] --?[$itemIndex] -ge [$testValue]|[ --~curItem|string;after;-;[&curItem] --~curItem|string;before;";[&curItem] --&curType|[*-[&curItem]:type] --?[&curType] -eq character|[ --&curName|[*O:-[&curItem]:character:name] --h:fullCharList("[&curName]")|-[&curItem] --]| --]| --%| --s:|fullCharList }} to retrieve the hash table, add this line to your script: --l:|fullCharList You can then look up character IDs with code like this: --&curChar| <a character name> --&charID| [:fullCharList("[&curChar]")] One problem that I still have with this script is that it throws an error into the API for each object that isn't a character, although none of them cause the script to fail. This script uses the ScriptCards persistent storage function, so you need to have a " ScriptCards_Storage" character in your game to persist the index
1728843705

Edited 1728844459
I'm playing with Jumpgate right now and just a heads up, it looks like Scriptcards are working, but sub-routines do not: This works! !scriptcard  {{   --#title|Quarterstaff   --#sourceToken|@{selected|token_id}   --#targetToken|@{target|token_id}   --#emoteText|@{selected|token_name}   --=TestRoll|1d20   --+Test Roll|[$TestRoll] }} This is broken: !scriptcard  {{   --#title|Quarterstaff   --#sourceToken|@{selected|token_id}   --#targetToken|@{target|token_id}   --#emoteText|@{selected|token_name}   -->MakeRoll|   --X|     --:MakeRoll|         --=TestRoll|1d20         --+Test Roll|[$TestRoll]     --<| }} ***Update*** I was wrong! It was the --X| that was breaking the script - not the subroutine, the following does work: !scriptcard  {{   --#title|Quarterstaff   --#sourceToken|@{selected|token_id}   --#targetToken|@{target|token_id}   --#emoteText|@{selected|token_name}   -->MakeRoll|     --:MakeRoll|         --=TestRoll|1d20         --+Test Roll|[$TestRoll]     --<| }} Let me know if this should be reported as a bug.  I'm not sure what else is broken yet, but I'm going to try to write some automated attacks and spells to work with 5e 2024 and Jumpgate. Thanks to scriptcards my combat encounters are insanely fast, which allows me to run games with more people, and I can't see myself going on without them. To get 2024 content, I'd rather disable the character mancer, than go without scriptcards. I have a ton of rolls premade  here , which are setup to be easily modified, in case you want to check out what I've made in the past.
1728945964

Edited 1728957605
Alright I'm making a lot of progress and I got some rolls working with 2024 sheets and Jumpgate!  --X| works today, when it didn't yesterday, so I'm not sure what changed there... Something I learned: @{target|npc_ac} no longer works and using it throws an error in the console,   sheet.js:659 Uncaught TypeError: Cannot read properties of undefined (reading 'attributes')     at Object.vdr [as convertLegacyMacroAttributes] (sheet.js:659:17190)     at l.onmessage (sheet.js:431:31540) but can be changed to @{target|ac}
Alright - I've worked out some of what's broken, and hit a point where I probably won't be using Jumpgate to run my next game .  Built in function to create an array of all the page tokens is totally broken - meaning AOE spells wont work: --~|array;pagetokens;alltokens 'alltokens' variable is now undefined and attempts to loop through it fail. I confirmed Kurt Jaegers Fireball example which relies on this also does not work. The following attributes appear to no longer exist, all throw errors when used except spellcasting_ability: npc_ac (replace with just 'ac' to fix) npc_vulnerabilities,  npc_resistances,  npc_immunities,  spellcasting_ability Bonus problem - it appears all tokens of the same image/sheet have the same token Id now, so using the TokenMod to auto-apply damage from the script, applies that damage to all of the tokens with the same sheet / image - see below, both the Kobold tokens on the right took the 2 damage, even though only one target was selected:
1728987838
Kurt J.
Pro
API Scripter
Michael O. said: Alright - I've worked out some of what's broken, and hit a point where I probably won't be using Jumpgate to run my next game .  Built in function to create an array of all the page tokens is totally broken - meaning AOE spells wont work: --~|array;pagetokens;alltokens 'alltokens' variable is now undefined and attempts to loop through it fail. I confirmed Kurt Jaegers Fireball example which relies on this also does not work. The following attributes appear to no longer exist, all throw errors when used except spellcasting_ability: npc_ac (replace with just 'ac' to fix) npc_vulnerabilities,  npc_resistances,  npc_immunities,  spellcasting_ability Bonus problem - it appears all tokens of the same image/sheet have the same token Id now, so using the TokenMod to auto-apply damage from the script, applies that damage to all of the tokens with the same sheet / image - see below, both the Kobold tokens on the right took the 2 damage, even though only one target was selected: Not sure what you are running into here, but in my test Jumpgate game, all of this is working as expected (including the --X|): !script {{   --+TokenID|@{selected|token_id}   --#sourcetoken|@{selected|token_id}   --+Name|[*S:t-name]   --+npc_ac|[*S:npc_ac]   --+npc_vulnerabilities|[*S:npc_vulnerabilities]   --+npc_resistances|[*S:npc_resistances]   --+npc_immunities|[*s:npc_immunities] }} For the HP getting updated on all tokens, if the HP bar is linked to the HP attribute, then yes - modifying it will modify all tokens that are also linked. The HP bar should not be linked on the token. Are you attempting to use the 2024 sheet? If so, absolutely *nothing* should be working because none of the attributes have been exposed from Beacon at this time.
Yes --X| was causing cards to fail for at least two days, but seems to be working now. Using npc_ac results in an error in the Google Console: sheet.js:659 Uncaught TypeError: Cannot read properties of undefined (reading 'attributes')     at Object.Adr [as convertLegacyMacroAttributes] (sheet.js:659:17190)     at l.onmessage (sheet.js:431:31540) For resist/vuln:  Note  I'm using *T not *S, but here's the API error output (from Scriptcards): "Error: No attribute or sheet field found for character_id -O95bVPpPSLJjX1prLih named npc_resistances" "Error: No attribute or sheet field found for character_id -O95bVPpPSLJjX1prLih named npc_immunities" "Error: No attribute or sheet field found for character_id -O95bVPpPSLJjX1prLih named npc_vulnerabilities" Spellcasting_ability doesn't throw an error, but the value is null, using a wizard token. As far as the token ID issue - I ran a test - clicking each token and outputting the associated token ID. Same image/sheet => same token ID. I am not using any sheet attributes for the bars.
I think this post explains my problems: <a href="https://app.roll20.net/forum/post/12099109/mod-api-issues-in-jumpgate-w-slash-tokens/?pageforid=12099217#post-12099217" rel="nofollow">https://app.roll20.net/forum/post/12099109/mod-api-issues-in-jumpgate-w-slash-tokens/?pageforid=12099217#post-12099217</a>
Some of the Visual effects no longer work once I switched to Jumpage. Still work manually, but not in Scriptcards. For example: &nbsp;&nbsp;--vbetweentokens|@{selected|token_id} @{target|token_id} beam-fire Works fine, but &nbsp;&nbsp;--vbetweentokens|@{selected|token_id} @{target|token_id} rocket-fire or &nbsp;&nbsp;--vbetweentokens|@{selected|token_id} @{target|token_id} custom does not. Any ideas?
1730107293
Kurt J.
Pro
API Scripter
Kaspar K. said: Some of the Visual effects no longer work once I switched to Jumpage. Still work manually, but not in Scriptcards. For example: &nbsp;&nbsp;--vbetweentokens|@{selected|token_id} @{target|token_id} beam-fire Works fine, but &nbsp;&nbsp;--vbetweentokens|@{selected|token_id} @{target|token_id} rocket-fire or &nbsp;&nbsp;--vbetweentokens|@{selected|token_id} @{target|token_id} custom does not. Any ideas? Are you certain you are on the ribbon page? And are you using the 2024 sheet? If so, @target doesn't work at all. I have not made changes to ScriptCards yet for Jumpgate and/or the 2024 sheet because they are both in such a poor state both functionality-wise and from a documentation standpoint. I'm waiting until they have ironed out some of the issues before looking into required coding changes.
Me again, with another brain teaser! Is there a way to transfer a repeating row from one character to another using Scriptcards and the !or or hash commands? I'm trying to move an item from a shared party loot character to a PC.&nbsp; Thanks!