EDIT: Kurt announced that 3.0.12 is going to be the 1-Click version soon. <a href="https://app.roll20.net/forum/post/11175456/script-scriptcards-thread-number-2/?pageforid=12433032#post-12433032" rel="nofollow">https://app.roll20.net/forum/post/11175456/script-scriptcards-thread-number-2/?pageforid=12433032#post-12433032</a> So hopefully soon the part following part about fetching from Github won't be necessary. Sure FFR. I actually redid the Spawn ScriptCards to take advantage of some new features that Kurt added to the latest ScriptCards. So that one does require a newer version of ScriptCards than what is in the 1-Click install. Which you can grab the latest version here from Github . The 3.0.12 version has support for reading the _defaulttoken property of a Character which simplifies my old setup. 1. ScriptCards Triggers requires a character to be created named ScriptCards_Triggers and that character needs to have an ability named change:graphic Note: I don't think that can be a Beacon sheet at the moment. I'm not sure because I stopped testing on Beacon sheets so I could be wrong here. 2. After creating that character, restart the API Mod Sandbox so ScriptCards registers that character for triggers. You'll see a message like: 3. In the change:graphic ability on ScriptCards_Triggers this is the ScriptCard: !script {{
--&LogLevel|error
--&EnableLinkedTokenMirroring|true
--&LinkageLocation|gmnotes
--&LinkagePrefix|linked
--/|TRIGGER_REPLACEMENTS
--#hidecard|1
--/|Check if linked token mirroring is enabled
--?"[&EnableLinkedTokenMirroring]" -ne "true"|[
-->LogMessage|DEBUG;Linked token mirroring is not enabled. exiting
--^Done|
--]|
--/|Check if the change was a token moving
--?"[&GraphicNewlastmove]" -eq "[&GraphicOldlastmove]"|[
-->LogMessage|DEBUG;old lastmove [&GraphicOldlastmove] same as new lastmove [&GraphicNewlastmove] so change was not movement. exiting
--^Done|
--]|
--/|Check if the changed token is linked
--?"[&GraphicNew[&LinkageLocation]]" -ninc "[&LinkagePrefix]"|[
-->LogMessage|DEBUG;Linkage location [&LinkageLocation] on changed token [&GraphicNew[&LinkageLocation]] does not contain linkage prefix of [&LinkagePrefix]. exiting
--^Done|
--]|
-->MoveLinkedToken|[&GraphicNew_id]
--:Done|
--X|
--:MoveLinkedToken|SourceTokenID
-->LogMessage|DEBUG;Inside MoveLinkedToken function with source token of [%1%]
--&_mltLinkedToken|[*[%1%]:t-[&LinkageLocation]]
--&_mltLinkedToken|[&_mltLinkedToken([&LinkagePrefix(length)])]
-->LogMessage|DEBUG;Linked token id [&_mltLinkedToken] would get moved to match top [*[%1%]:t-top] and left [*[%1%]:t-left]
--!t:[&_mltLinkedToken]|top:[*[%1%]:t-top]|left:[*[%1%]:t-left]
-->LogMessage|DEBUG;Leaving MoveLinkedToken function
--<|
--:LogMessage|MessageLevel;Message
--&_lmPrefix|SC change:graphic trigger
--&_lmMessageLevel|[%1%]
--?"[&_lmMessageLevel(tolowercase)]" -eq "fatal"|_lmSENDTOCONSOLE
--&_lmNum|1
--?"[&LogLevel(tolowercase)]" -eq "warn"|&_lmNum;10
--?"[&LogLevel(tolowercase)]" -eq "info"|&_lmNum;100
--?"[&LogLevel(tolowercase)]" -eq "debug"|&_lmNum;1000
--&_lmMLNum|1
--?"[&_lmMessageLevel(tolowercase)]" -eq "warn"|&_lmMLNum;10
--?"[&_lmMessageLevel(tolowercase)]" -eq "info"|&_lmMLNum;100
--?"[&_lmMessageLevel(tolowercase)]" -eq "debug"|&_lmMLNum;1000
--?[&_lmMLNum] -gt [&_lmNum]|_ENDLOG
--:_lmSENDTOCONSOLE|
--\log|[&_lmPrefix] [&_lmMessageLevel(touppercase)]: [%2%]
--?"[&_lmMessageLevel(tolowercase)]" -eq "fatal"|Done
--:_ENDLOG|
--<|
}} 4. This is the ScriptCard to spawn a default token and link it to the selected token: !script {{
--/|CONFIGURATION VARIABLES
--&CharacterToSpawn|SpellArea-Square
--&LinkageLocation|gmnotes
--&LinkagePrefix|linked
--&SquareSize|4
--&PixelSize|70
--&SC_Minimum_Version|300120
--#title|Spawn and Link Tokens
--#sourceToken|@{selected|token_id}
--?[&SC_VERSION_NUMERIC] -lt [&SC_Minimum_Version]|[
--+ERROR|Must have at least ScriptCards 3.0.12 installed to work with _defaulttoken properties. Exiting
--^Done|
--]|
-->lookupCharacterIDbyName|[&CharacterToSpawn];SpawnCharID
--?"[&SpawnCharID]" -eq "NotFound"|[
--+ERROR|Could not find character id for [&CharacterToSpawn]. Make sure only 1 character starting with [&CharacterToSpawn] exists. Exiting
--^Done|
--]|
--~|hash;set;OverrideProps;top==[*S:t-top];left==[*S:t-left];_pageid==[*S:t-_pageid];height==[= [&SquareSize] * [&PixelSize] ];width==[= [&SquareSize] * [&PixelSize] ]
-->SpawnDefaultToken|[&SpawnCharID];OverrideProps;NewTID
-->MoveTokenToBack|[&NewTID]
-->LinkTokens|[*S:t-id];[&NewTID]
--+Spawned|Token [&NewTID] spawned and linked to [*S:t-name]
--:Done|
--X|
--:SpawnDefaultToken|CharacterToSpawn;TokenPropertyOverrideHash;StringReturnVariable
--~|array;fromkeys;_sdtOverKeys;[%2%]
--~|hash;fromjson;_sdtDTHash;[*[%1%]:_defaulttoken]
--~|array;fromkeys;_sdtDTKeys;_sdtDTHash
--~|array;define;_sdtTokenPropArray
--%_sdtDTProp|foreach;_sdtDTKeys
--~_sdtOverIdx|array;indexof;_sdtOverKeys;[&_sdtDTProp]
--?"[&_sdtOverIdx]" -ne "ArrayError"|%
--~|array;add;_sdtTokenPropArray;[&_sdtDTProp]:"[:_sdtDTHash("[&_sdtDTProp]")]"
--%|
--%_sdtOverProp|foreach;_sdtOverKeys
--~|array;add;_sdtTokenPropArray;[&_sdtOverProp]:"[:[%2%]("[&_sdtOverProp]")]"
--%|
--~_sdtTokenPropList|array;stringify;_sdtTokenPropArray;|
--!ot:[%3%]|[&_sdtTokenPropList]
--<|
--:LinkTokens|SourceTokenID;SpawnedTokenID
--!t:[%1%]|[&LinkageLocation]:[&LinkagePrefix][%2%]
--<|
--:MoveTokenToBack|TokenID
--z:graphic:[%1%]|toback
--<|
--:lookupCharacterIDbyName|CharacterName;StringReturnVariable
--~|array;objects:character;_lcibnCharArr;[%1%]
--?"[@_lcibnCharArr(length)]" -eq 0|&[%2%];NotFound
--?"[@_lcibnCharArr(length)]" -ge 2|&[%2%];NotFound
--?"[&[%2%]]" -eq "NotFound"|<
--&[%2%]|[@_lcibnCharArr(0)]
--<|
}} So there are some configuration at the top that you may need to adjust: --&CharacterToSpawn|SpellArea-Square
--&LinkageLocation|gmnotes
--&LinkagePrefix|linked
--&SquareSize|4
--&PixelSize|70 The &CharacterToSpawn is the name of the Character that has the default token you want to summon. So in my case I have a character named SpellArea-Square that has a defaulttoken set to the token i want to use an area. &LinkageLocation is the location on the selected token that will get the linked token id. In this case the gmnotes field but could be bar3_max or tooltip or wherever you prefer. &LinkagePrefix is what the LinkageLocation will start with. So in the example above, the selected token's gmnotes field would get "linked-sometokenid" &SquareSize is how big of a square to summon. This could get changed to separate heights and width as needed but for simplicity sake this example is a square. &PixelSize is 70 which is the default pixel size for a page in roll20 and is used to determine size of height and width of summoned token in conjuction with &SquareSize. So the Spawn ScriptCard will spawn a token at the same location as the selected token, move the spawned token to the back, and add the spawned token id to the selected token's gmnotes field. Then when a token is changed, the change:graphic will check if linked movement is enabled, if the change was movement, and if the changed token has that linkage prefix. And if it does, it will move the linked token to the same location the source token moved to. Note that this is not real time. The linked token moves after the source token is dropped. So there is a little lag. I wish it were real time but I don't think that's possible with Roll20 event triggers today. I'd love to be wrong on that though. Let me know if you have any questions about that.