-
Notifications
You must be signed in to change notification settings - Fork 0
/
SFTL Stream Deck v2.4.json
6 lines (6 loc) · 228 KB
/
SFTL Stream Deck v2.4.json
1
2
3
4
5
6
{
"deck_data": "{ \"background_color\": 4210752.0, \"on\": false, \"grid_y\": 12.0, \"snap_grid\": 1.0, \"lb_version\": \"2023.1.1\", \"background_image\": \"\", \"sammi_version\": \"2023.1.1\", \"encrypted\": 0.0, \"adaptive_resizing\": 1.0, \"unique_id\": \"20230403200051570050702\", \"button_list\": [ { \"color\": 105.0, \"persistent\": 1.0, \"text\": \"!!READ ME FIRST!!\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 317.0, \"b0\": \"BEFORE YOU DO ANYTHING ELSE, RUN \\\"INITIALIZE SFTL TEST LAB\\\" WHILE OBS IS RUNNING\\n---\\nAlso make sure you've grabbed \\\"SFTLTestPack.zip\\\" and unzipped it directly to your SAMMI\\ninstallation directory. For example, if SAMMI is in...\\n\\nC:\\/Streaming\\/SAMMI\\n\\n... unzip this *directly* to C:\\/Streaming\\/SAMMI and not a sub-folder.\\n\\nThe Initialize button will ensure that scenes, sources, and INI files are created,\\nwhile the files from SFTLTestPack will add necessary files for many of the buttons\\nincluded in this deck.\\nIf the file names or folder structures have been changed, certain buttons won't work\\nproperly.\\n\\nOkay, on with the rest.\", \"v0\": 0.0 }, { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 380.0, \"b0\": \"ABOUT THIS DECK\\n---\\nThis deck and the buttons included are provided with no warranty or guarantees.\\n\\nIt's not like pressing one is going to make your PC explode, but I'm just a guy\\ntrying to make fun buttons for other people to use in SAMMI. What works for my\\nenvironment may not work for everyone else's, and I've only got so many options\\nfor testing. But I hope they work for you, and I hope you have fun with them. <3\\n\\nMost of these are Twitch related - that's just the nature of the beast right now.\\nFor example, you can't pull the number of YouTube Subscribers you have in the\\nsame way you can pull Twitch Followers. I may look into some YouTube options \\ndown the line based on interest and feedback, but I'm just one person doing this\\nin my free time. That said, a lot of the principles that apply to Twitch can also\\napply to YouTube with a few adjustments.\\n\\nPlease note that this has been tested with OBS v28 and above. Certain buttons and\\neffects may run into issues with v27 and below due to changes in OBS between those\\ntwo major versions.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 276.0, \"b0\": \"TWITCH ALERTS\\n---\\nA variety of alerts for different situations. These have triggers set already,\\nso you can try triggering them via SAMMI Bridge in OBS to see how they work.\\n\\nKeep in mind they're extremely basic and for boring reasons that aren't worth\\ngetting into, they lack visual polish. These are meant to show you how the\\ncookies are made so that you can make your own cookies, rather than being an\\nout of the box solution.\\n\\nSome of them include pulling the names of raiders, shoutouts, and more, so\\nI recommend triggering these via SAMMI Bridge in OBS to see how they work\\nin action (if you run the button on its own via SAMMI Core, it'll still *run*,\\nbut you'll get lots of text replaced with \\\"undefined\\\").\", \"v0\": 0.0, \"comment_color\": 16747008.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 115.0, \"b0\": \"TWITCH SUB GOALS\\n---\\nMostly different types of trackers to see where your current subs are at\\nas well as sub goals. Realistically you can use the methods described here\\nto track just about any piece of data Twitch provides, including things\\nlike followers. Go wild!\", \"v0\": 0.0, \"comment_color\": 10764644.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 63.0, \"b0\": \"TWITCH COMMANDS\\n---\\nReplacements for slash commands as well as some other helpful automations.\\nNot a ton more to say than that.\", \"v0\": 0.0, \"comment_color\": 5385234.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 337.0, \"b0\": \"SECURITY CENTER\\n---\\nAutomations that can take some pressure off of you when it comes to\\nmoderation needs, particularly when your team is just you.\\n\\nThese tend to be pretty powerful, so instead of having \\\"out of the box\\\"\\ntriggers, I've added information on HOW to set the triggers. That way your\\nregulars aren't accidentally caught in the crossfire.\\n\\nTriggers also copy when you copy a button, so keep that in mind if you want\\nto copy these to your own deck(s) or want to make different buttons for\\ndifferent purposes, but don't want to set up every single trigger again.\\n\\nAdded Twitch chat security that can be combined with automations to create\\na safer streaming environment.\\nYou can also combine these with things like Twitch announcements to let\\npeople know when chat is open and closed.\", \"v0\": 0.0, \"comment_color\": 3938340.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 233.0, \"b0\": \"PERSISTENT THING COUNTER\\n---\\nA set of buttons that keeps track of a number, and relies on an INI file\\nto do so. Since SAMMI doesn't keep any information in memory when it's\\nclosed (or crashes, or otherwise), INI files are an easy way to store\\ninformation across sessions.\\n\\nIf no INI file exists, there won't be anything to load from, so make sure\\nany adjustments you make to the INI file and\\/or folder where it's stored\\nare updated in SAMMI, too!\", \"v0\": 0.0, \"comment_color\": 2098242.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 110.0, \"b0\": \"GEARWORKS\\n---\\nThings that are entirely local to SAMMI and OBS, and are not tied to any specific\\nplatform. These are more jumping off points to make your own effects and\\/or other\\nmiscelaneous automations.\", \"v0\": 0.0, \"comment_color\": 9551906.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 233.0, \"b0\": \"TWITCH POINTS\\n---\\nExamples of how to modify Twitch Point redeems, such as adding an artificial\\ncooldown by pausing \\/ unpausing them or changing the point values on the fly.\\n\\nYou'll need to make sure SAMMI \\\"owns\\\" rewards before you can do anything with\\nthem; you can do this from the SAMMI Core by going to\\nTwitch Connections > Edit Rewards and making dupes of any rewards that SAMMI\\ndoesn't already own. You'll need to go to Twitch directly to delete the\\noriginal versions once you make dupes, but you'll still be able to edit\\nthem from Twitch even though SAMMI is the owner.\", \"v0\": 0.0, \"comment_color\": 12590996.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 215.0, \"b0\": \"BOT COMMANDS\\n---\\nDespite what it says, you only need a second Twitch account for this, no\\ncoding or scripting knowledge required. If you don't want to use a second\\naccount, you can set these up using your primary streaming account, too.\\n\\nThese are commands that are designed to either run in response to a specific\\ntrigger in chat, i.e. \\\"!lurk\\\", or on a timer, such as a message that is sent\\nto chat every 15 minutes. They're building blocks to make your own channel bot\\nthat's handled via SAMMI instead of via scripting!\\n\", \"v0\": 0.0, \"comment_color\": 14095312.0, \"name\": \"\" } ], \"press_type\": 0.0, \"x\": 0.0, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.83333333333333337034076748750522, \"button_id\": \"ID2\", \"button_duration\": 0.0, \"y\": 0.0, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 9551906.0, \"persistent\": 1.0, \"text\": \"Display Random\\nImage\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 334.0, \"b0\": \"DISPLAY RANDOM IMAGE\\n---\\nGets a random image via one of two methods and displays it on stream. Note that\\nthis displays the image, but at that point it will just sit there. What you do\\nwith it beyond that is up to you.\\nYou can work either of these methods into alerts, Twitch Point redeems, random effects,\\nand anything else you put your mind to.\\n\\nThere are two methods outlined below: A weighted array, and the Random command. Each one\\nwill have its own section below. Use whichever method best suits your needs!\\n(Note that if you have both enabled, Option 2: Random will take priority since it's\\nfurther down the chain of commands.)\\n\\nNOTE: Want to display a random VIDEO instead? You can swap \\\"file\\\" (with quotes)\\nfor \\\"local_file\\\" (with quotes) in the Settings (JSON) boxes below. More info on\\nthat here:\\nhttps:\\/\\/sammi.solutions\\/docs\\/commands\\/obs-settings\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"OPTION 1: WEIGHTED ARRAY\\n---\\nPull down for more info:\\nUses an array to allow more precise control over which files are being loaded\\nand why by setting weights for how likely certain things will come up.\\nIt's a great option if you want to make a rarity roller or want certain things\\nto come up more or less often compared to others.\\n\\nA second array and additional inserts with \\\"_weight\\\" added for each array insert are\\nrequired to add weights. If Circle is the first insert and you want it to have a weight\\nof 5, the first weight should be 5.\\n\\nWeights do not need to add up to 100! You're only setting the odds of how likely\\nany given option will come up compared to the others. Arrays are cumulative, so\\nthe example below clears the array before re-creating it to keep things tidy.\\n\\nFinally, name matters - we'll be pulling the selected item from the array as a\\nvariable, so for ease of use, the file name should match as well... unless you\\nwant to use Switch and Case Statements. You'll want to go to the Rarity Roller\\nto learn how those work.\", \"v0\": 15.0 }, { \"cmd\": 234.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage\" }, { \"cmd\": 234.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage_weight\" }, { \"cmd\": 17.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage\" }, { \"cmd\": 17.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage_weight\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage\", \"b2\": \"\\\"circle\\\"\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage\", \"b2\": \"\\\"star\\\"\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage\", \"b2\": \"\\\"heart\\\"\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage\", \"b2\": \"\\\"thecools\\\"\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage_weight\", \"b2\": \"5\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage_weight\", \"b2\": \"20\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage_weight\", \"b2\": \"20\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage_weight\", \"b2\": \"50\" }, { \"b1\": \"varImageWeight\", \"cmd\": 101.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage_weight\", \"b2\": \"\" }, { \"b1\": \"varImage\", \"cmd\": 101.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayImage\", \"b2\": \"\" }, { \"b1\": \"{\\\"file\\\":\\\"\\/$global.main_directory_slash$\\/sftltestlab\\/images\\/\\/$varImage$\\/.png\\\"}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Random \\/\\/ Image\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 17.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 1.0, \"xpan\": 35.0, \"b0\": \"OPTION 2: RANDOM\\n---\\nPull down for more info:\\nThe \\\"Random\\\" command pulls from a value, and that value is saved to a variable that's\\nthen used to determine how an image source in OBS will change. The easiest way to do\\nthis is to have all files in a single location with incrimental numbers - so for the\\nexample below:\\n\\n1.png, 2.png, 3.png, etc.\\n\\nIf you want to use a naming scheme, like cat1.png, cat2.png, cat3.png, make sure\\nyou put the name *before* the variable, or OBS will attempt to load an image that\\ndoesn't exist.\\n\\nKeep in mind that the forward slahes (\\/) around a variable aren't part of the file\\nstructure, so any variable that's used in a path needs to have a forward slash\\nfollowing it, too.\", \"v0\": 2.0 }, { \"b1\": \"1\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 18.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"randomImage\", \"b2\": \"4\", \"v0\": 0.0 }, { \"b1\": \"{\\\"file\\\":\\\"\\/$global.main_directory_slash$\\/sftltestlab\\/images\\/\\/$randomImage$\\/.png\\\"}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 19.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Random \\/\\/ Image\" } ], \"press_type\": 0.0, \"x\": 0.83333333333333337034076748750522, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666657414808128123695, \"button_id\": \"ID349\", \"button_duration\": 0.0, \"y\": 0.1666666666666666574148081281237, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 9551906.0, \"persistent\": 1.0, \"text\": \"Image Location\\nRandomizer\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 209.0, \"b0\": \"IMAGE LOCATION RANDOMZIER\\n---\\nCauses an image to move to a random location.\\n\\nCan be adjusted and customized in a variety of ways to create your own effects.\\nOne example is to combine commands from this button with \\\"Display Random Image\\\"\\nand an alpha filter in OBS to have a random image fade in at a random location,\\nthen fade back out. You can even add scale and movement, if you want!\\n\\nAs always, there's no real limit on what you can do, so don't be afraid to\\nexperiment.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"XPOS AND YPOS\\n---\\nPull down for more info:\\nThis set of commands uses \\\"Random\\\" to assign a number to a set of variables that will be used later.\\n\\nVariables: Unless you have a specific reason to change the names, leave the variables as xpos and ypos.\\n These are the X (horizontal) and Y (vertical) values that we'll be using later.\\n\\nValues: You may want to adjust these based on the size of the image or other media you're displaying so\\n that it will show up on-screen *based on the positional alignment set in OBS*. For this example,\\n assuming your canvas in OBS is 1920x1080, an image that's 300x300 with default \\\"Top Left\\\"\\n alignment should be set at 0 minimum and 1620 maximum for xpos, and 0 minimum and 780 maximum\\n for ypos. This ensures that the full image will display on screen without being cut off.\\n\\n(You generally shouldn't need to use \\\"Allow Float\\\". This will allow decimals, which in this case means\\nOBS will try to use sub-pixel values that aren't relevant here.)\", \"v0\": 4.0 }, { \"b1\": \"0\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"xpos\", \"b2\": \"1620\", \"v0\": 0.0 }, { \"b1\": \"0\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"ypos\", \"b2\": \"780\", \"v0\": 0.0 }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"xpos\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"ypos\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 0.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 33.0, \"b0\": \"CHANGE IMAGE LOCATION\\n---\\nPull down for more info:\\nCauses the image to move to a location set by \\\"xpos\\\" and \\\"ypos\\\" above.\", \"v0\": 1.0 }, { \"b1\": \"Random \\/\\/ Image\", \"b3\": \"ypos\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"xpos\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 1.0, \"xpan\": 33.0, \"b0\": \"MOTION EFFECT (OPTIONAL)\\n---\\nPull down for more info:\\nIn this example, causes the image to move upward by 50 pixels. If you don't want the image\\nto move, turn this command off. Alternatively, if you want it to move in another direction,\\nyou can add \\/ subtract from X End and\\/or Y End. Make sure any simple math you use is\\nwrapped in (). For example, if you wanted the image to move left 75 pixels,\\nX End would be: (xpos-75)\\n\\nIf you don't want the image to move at all, you can safely disable this command.\", \"v0\": 1.0 }, { \"b5\": \"(ypos-50)\", \"b1\": \"Random \\/\\/ Image\", \"b3\": \"ypos\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"xpos\", \"b2\": \"xpos\", \"b6\": \"1000\", \"v0\": 3.0 } ], \"press_type\": 0.0, \"x\": 0.83333333333333337034076748750522, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"ID351\", \"button_duration\": 1020.0, \"y\": 0.33333333333333331482961625624739, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 5385234.0, \"persistent\": 1.0, \"text\": \"Shield Mode\\nToggle\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 271.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nThis button works as a simple toggle to turn Shield Mode on and off.\\n \\nIt relies on an initial variable, which you can see by right\\nclicking on the button, then going to \\\"Edit Initial Variables\\\".\\n \\nClicking the button once will immediately turn Shield Mode ON;\\nclicking it again while SAMMI is still running will toggle\\nShield Mode OFF.\\n\\nI HIGHLY RECOMMEND testing it a few times to make sure it's\\nworking properly before going live. I sincerely hope you never\\nhave to use this, but it's a good option to have ready to go.\", \"v0\": 0.0 }, { \"cmd\": 24.0, \"obsid\": \"Main\", \"pos\": 1.0, \"v3\": { \"default\": 0.0, \"on\": 5.0, \"off\": 2.0 }, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"shieldmode\", \"v0\": 6.0 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 25.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"off\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 2.0, \"v2\": 1.0 }, { \"cmd\": 269.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 25.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL NAME HERE\", \"v0\": 0.0 }, { \"b1\": \"=\", \"cmd\": 15.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 25.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"shieldmode\", \"b2\": \"\\\"on\\\"\" }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"on\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 2.0, \"v2\": 1.0 }, { \"cmd\": 269.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 25.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL NAME HERE\", \"v0\": 1.0 }, { \"b1\": \"=\", \"cmd\": 15.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 25.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"shieldmode\", \"b2\": \"\\\"off\\\"\" } ], \"press_type\": 0.0, \"x\": 0.33333333333333331482961625624739, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"{\\n\\\"shieldmode\\\":\\\"off\\\"\\n}\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"ID352\", \"button_duration\": 25.0, \"y\": 0.25, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 2113.0, \"stretch\": 0.0 }, { \"color\": 5385234.0, \"persistent\": 1.0, \"text\": \"Run Commercial\\n(60s)\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 182.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nIf you're running scheduled ads, this should be used ONLY if you plan\\non running additional ads outside of your existing schedule. It's NOT\\na replacement for scheduled ads and won't offset an upcoming scheduled\\nad block.\\n\\nRunning an ad via this method during any other ad can, and likely will,\\nrun the ad blocks back-to-back, causing the ad block to run longer than\\nintended.\", \"v0\": 0.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 36.0, \"b0\": \"RUN COMMERCIAL (60s)\\n---\\nPull down for more info:\\nImmediately runs a 60-second commercial via SAMMI command.\\nThe Duration box can be changed.\\n\\nValid durations: 30, 60, 90, 120, 150, 180\\n\\\"length\\\" is how long the ad will run in seconds. Twitch attempts\\nto run ads in 30-second blocks. If you use a different value,\\nTwitch will round up to the next highest value.\\n\\nThe variable is optional, but can be useful for troubleshooting\\nsince it provides additional info via the Variable Window.\", \"v0\": 2.0, \"name\": \"\" }, { \"b1\": \"60\", \"cmd\": 266.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL NAME HERE\", \"b2\": \"adbreak\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"adbreak\" } ], \"press_type\": 0.0, \"x\": 0.33333333333333331482961625624739, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666671292595935938152, \"button_id\": \"ID353\", \"button_duration\": 0.0, \"y\": 0.33333333333333331482961625624739, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 5385234.0, \"persistent\": 1.0, \"text\": \"Announce Ad Break\\n& Run Commercial\\n(60s)\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 186.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nIf you're running scheduled ads, this should be used ONLY if you plan\\non running additional ads outside of your existing schedule. It's NOT\\na replacement for scheduled ads and won't offset an upcoming scheduled\\nad block.\\n\\nRunning an ad via this method during any other ad can, and likely will,\\nrun the ad blocks back-to-back, causing the ad block to run longer than\\nintended.\", \"v0\": 0.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 168.0, \"b0\": \"SEND ANNOUNCEMENT \\/ WAIT FOR TIMEOUT (60s)\\n---\\nPull down for more info:\\nSimilar to the other Announcement button, but with the option of\\na pre-set announcement message to give viewers a heads up that\\nan ad break is starting soon.\\n\\nIncludes a 60-second timeout (in milliseconds) before running\\nthe ad, which can be adjusted to your liking.\", \"v0\": 2.0, \"name\": \"\" }, { \"b1\": \"YOUR CHANNEL HERE\", \"cmd\": 241.0, \"v1\": 0.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Ad break starting in 60 seconds!\" }, { \"cmd\": 190.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"60000\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"RUN COMMERCIAL (60s)\\n---\\nPull down for more info:\\nImmediately runs a 60-second commercial via SAMMI command.\\nThe Duration box can be changed.\\n\\nValid durations: 30, 60, 90, 120, 150, 180\\n\\\"length\\\" is how long the ad will run in seconds. Twitch tends\\nto run ads in 30-second blocks, so if you use a different value,\\nTwitch will likely try to run an ad break rounded up to the next\\nhighest value.\\n\\nThe variable is optional, but can be useful for troubleshooting\\nas it provides additional info via the Variable Window.\", \"v0\": 2.0 }, { \"b1\": \"60\", \"cmd\": 266.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL NAME HERE\", \"b2\": \"adbreak\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"adbreak\" } ], \"press_type\": 0.0, \"x\": 0.33333333333333331482961625624739, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666671292595935938152, \"button_id\": \"ID354\", \"button_duration\": 0.0, \"y\": 0.41666666666666668517038374375261, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 3938340.0, \"persistent\": 1.0, \"text\": \"Auto-ban Based\\non Word or Phrase\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": false, \"dis\": 0.0, \"xpan\": 400.0, \"b0\": \"IMPORTANT: This automation requires that you use the \\\"Twitch Chat\\\" trigger\\n and wildcards to scan messages for various words and phrases.\\n For example, if you wanted to ban bots that point to a site called\\n \\\"lizardchamp\\\", regardless of where it shows up in the message they\\n send, you'll need to create a few Twitch Chat triggers and wrap them\\n in wildcards like so:\\n\\n *lizardchamp*\\n \\n This causes SAMMI to look for ANY instance of the word or phrase,\\n No matter where it is in a message. Wildcards are powerful, and the automation\\n won't discriminate who's being banned, so be careful in how you use them!\\n\\n Note that you can set multiple triggers for one button, and this will\\n also work for variations like \\\"lizardchamp dot net\\\". I strongly recommend\\n reading up on how wildcards work before you set up this automation:\\n https:\\/\\/sammi.solutions\\/docs\\/triggers\\/introduction#wildcards\", \"v0\": 0.0 }, { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": false, \"dis\": 0.0, \"xpan\": 358.0, \"b0\": \"IMPORTANT: The primary purpose of this automation is to quickly ban those\\n periodic accounts that post annoying spam messages, such as ones\\n trying to sell follwers, views, and the like.\\n You can also use this to ban specific, targeted harassment if a\\n particular word or phrase is used across messages, i.e. someone is\\n using hate speech that AutoMod doesn't catch, someone is evading\\n a ban to post the same thing over and over, you pull a specific line\\n from ASCII spam so the whole thing is blocked, etc.\\n \\n I *do not* recommend relying on this method as a way to counteract\\n potential hate raids. There's a delay, however small, between when a\\n message is sent, when SAMMI reads it, and when it runs a set of actions,\\n so that delay may allow messages to slip through. Multiple messages may\\n also trigger the same automation, causing it to loop back to the start and\\n not finish.\\n I hope you never have to deal with a hate raid, but if you do,\\n please use Shield Mode or similar emergency automations that can lock down\\n chat via followers only mode, emote only mode, clearing chat, etc.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": false, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"PULL USER NAME\\n---\\nPull down for more info:\\nWhen a new message matching a trigger is read, this deletes any existing variable - in\\nthis case, the last username pulled - and pulls the latest username, saving it as a\\nvariable. Once SAMMI sees that the variable exists, it proceeds to the next command.\\nThis ensures that only the latest username to trigger the button is hit with a ban.\", \"v0\": 3.0 }, { \"cmd\": 78.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": false, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"autobanUsername\" }, { \"b1\": \"user_name\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": false, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"autobanUsername\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": false, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"autobanUsername\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": false, \"dis\": 0.0, \"xpan\": 33.0, \"b0\": \"AUTOMATIC BAN\\n---\\nPull down for more info:\\nIssues a ban to the account that was pulled via the above commands. The \\\"Reason\\\" field\\nis optional, but will print to chat so moderators can see it.\", \"v0\": 1.0 }, { \"b1\": \"\\/$autobanUsername$\\/\", \"cmd\": 273.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": false, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL NAME HERE\", \"b2\": \"Automated spam message\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": false, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"UPDATE BAN LOG (OPTIONAL)\\n---\\nPull down for more info:\\nGets the current date and time, creates an alert in SAMMI (yellow\\ntext at the lower left of the screen), and saves the time (24-hr format)\\nwith the name of the banned user and reason in a text file.\\n\\nI recommend having a log in the off-chance that a regular gets caught in\\nthe crossfire.\\n\\nIn the example below, it'll be saved to a sub-folder of your SAMMI install\\ndirectory named \\\"sftltestlab\\\" as \\\"banlog.txt\\\".\", \"v0\": 3.0 }, { \"b1\": \"\\/$time$\\/\", \"cmd\": 247.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": false, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"[{YY}-{MM}-{DD}] [{HH}:{mm}]\" }, { \"cmd\": 142.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": false, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Banned \\/$autobanUsername$\\/. Reason: Automated spam message.\" }, { \"b1\": \"\\n\\/$time$\\/ Banned \\/$autobanUsername$\\/. Reason: Automated spam message.\", \"cmd\": 255.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": false, \"dis\": 0.0, \"xpan\": 19.0, \"b0\": \"sftltestlab\\/banlog.txt\" } ], \"press_type\": 0.0, \"x\": 0.83333333333333337034076748750522, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"ID355\", \"button_duration\": 0.0, \"y\": 0.75, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 12632256.0, \"persistent\": 1.0, \"text\": \" Twitch Alerts \", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ ], \"press_type\": 0.0, \"x\": 0.0, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666668517038374375261, \"button_id\": \"ID314\", \"button_duration\": 0.0, \"y\": 0.083333333333333342585191871876305, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 64.0, \"stretch\": 0.0 }, { \"color\": 12632256.0, \"persistent\": 1.0, \"text\": \"Gearworks\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ ], \"press_type\": 0.0, \"x\": 0.83333333333333337034076748750522, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"ID356\", \"button_duration\": 0.0, \"y\": 0.083333333333333328707404064061848, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 64.0, \"stretch\": 0.0 }, { \"color\": 12632256.0, \"persistent\": 1.0, \"text\": \"Twitch Commands\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ ], \"press_type\": 0.0, \"x\": 0.33333333333333337034076748750522, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666668517038374375261, \"button_id\": \"ID359\", \"button_duration\": 0.0, \"y\": 0.083333333333333342585191871876305, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 64.0, \"stretch\": 0.0 }, { \"color\": 5385234.0, \"persistent\": 0.0, \"text\": \"Send\\nAnnouncement\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 142.0, \"b0\": \"SEND ANNOUNCEMENT\\n---\\nPull down for more info:\\nBrings up a dialogue box in SAMMI to enter your own announcement message, which\\nis then saved as a variable and sent to chat.\\n\\nSimple stuff, but a good example of how Wait for User Input works and how it can\\nbe used to interact directly with Twitch.\", \"v0\": 2.0, \"name\": \"\" }, { \"b1\": \"\", \"cmd\": 214.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Enter Announcement:\", \"b2\": \"announcement\" }, { \"b1\": \"YOUR CHANNEL HERE\", \"cmd\": 241.0, \"v1\": 0.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$announcement$\\/\" } ], \"press_type\": 0.0, \"x\": 0.33333333333333331482961625624739, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666668517038374375261, \"button_id\": \"ID360\", \"button_duration\": 10.0, \"y\": 0.1666666666666666574148081281237, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 1.0, \"stretch\": 0.0 }, { \"color\": 10764644.0, \"persistent\": 1.0, \"text\": \"Endless Twitch\\nSub Goal\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 186.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nyou either die a hero or live long enough to become\\nthe villain. Just what it says on the tin, creates an\\n\\\"endless\\\" sub goal where your goal is always one more\\nthan the current number of subscribers you have. \\n\\nYou'll need to set the trigger(s) for this one yourself,\\nsince it uses the same source as the normal Subscriber Goal\\nbutton.\", \"v0\": 0.0, \"name\": \"\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 148.0, \"b0\": \"ENDLESS LIKE THE BREADSTICKS AT OLIVE GARDEN\\n---\\nPull down for more info:\\nRuns \\\"Twitch: Get Subscribers\\\" at SAMMI launch. Whenever\\na new subscriber event happens while SAMMI is active, SAMMI\\npulls your current subscribers, adds one to it, and then changes\\na text source to show that your current sub count (\\\"subStatus\\\")\\nis just one away from goal (\\\"subGoal\\\").\", \"v0\": 0.0, \"name\": \"\" }, { \"b1\": \"subStatus\", \"cmd\": 177.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\" }, { \"b1\": \"3000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subStatus\" }, { \"b1\": \"=\", \"cmd\": 15.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subGoal\", \"b2\": \"(subStatus+1)\" }, { \"b1\": \"Sub Goal: \\/$subStatus$\\/ \\/ \\/$subGoal$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Subscribers\" } ], \"press_type\": 0.0, \"x\": 0.1666666666666666574148081281237, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666668517038374375261, \"button_id\": \"ID348\", \"button_duration\": 20.0, \"y\": 0.33333333333333331482961625624739, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 9551906.0, \"persistent\": 0.0, \"text\": \"Rarity\\nRoller\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 315.0, \"b0\": \"RARITY ROLLER\\n---\\nCreates and then pulls from a weighted array, then uses that information to\\ntrigger a Case Statement that prints an alert to SAMMI (the yellow message\\nin the bottom left of SAMMI Core). You can use this method to trigger any\\nnumber of things, including random images, messages to chat, videos to play,\\nand changing a source, just to name a few common scenarios.\\n\\nThis is secretly me tricking you - yes, you reading this now, thanks for reading,\\nappreciate you - into using arrays and Switch \\/ Case Statements.\\nThis is a pretty simiple use case of replacing If Statements for complex switches,\\nand Switch Statements can be used for just about anything where you want different outcomes\\nto happen based on different inputs. While If Statements are useful for binary situations\\nwhere you need one thing or the other to happen (IF this, ELSE that), Switch and Case\\nStatements allow you to have as many outcomes as you want from a single input.\\nEnjoy a new, irresponsible amount of power!\", \"v0\": 0.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"ARRAYS AND WEIGHTS\\n---\\nPull down for more info:\\nThese commands create two arrays. The first will be the values that we want to\\nreference later. These can be nearly anything you want, so use a naming scheme\\nthat makes sense to you.\\n\\nA second array and additional inserts with \\\"_weight\\\" added for each array insert are\\nrequired to add weights. In the example below, if Rare is the first insert and you\\nwant it to have a weight of 50, the first weight should be 50.\\n\\nWeights do not need to add up to 100! You're only setting the odds of how likely\\nany given option will come up compared to the others. Arrays are cumulative, so\\nthe example below clears the array before re-creating it to keep things tidy.\", \"v0\": 13.0 }, { \"cmd\": 234.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarity\" }, { \"cmd\": 234.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarity_weight\" }, { \"cmd\": 17.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarity\" }, { \"cmd\": 17.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarity_weight\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 15.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarity\", \"b2\": \"\\\"Rare\\\"\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 15.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarity\", \"b2\": \"\\\"SuperRare\\\"\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 15.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarity\", \"b2\": \"\\\"SuperSuperRare\\\"\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 15.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarity\", \"b2\": \"\\\"SuperSuperRareIITurbo\\\"\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 15.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarity_weight\", \"b2\": \"50\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 15.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarity_weight\", \"b2\": \"35\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 1.0, \"ms\": 15.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarity_weight\", \"b2\": \"10\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 15.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarity_weight\", \"b2\": \"5\" }, { \"b1\": \"arrayRarityVar\", \"cmd\": 101.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 15.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarity\", \"b2\": \"\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 0.0, \"ms\": 15.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 31.0, \"b0\": \"SWITCH AND CASE STATEMENTS\\n---\\nPull down for more info:\\nUses the value pulled from the array above (stored as arrayRarityVar in this example)\\nto run a set of commands based on the value pulled.\\n\\nYou can also have a Case Statement called \\\"default\\\" to run a set of commands if the\\nvalue pulled from the array doesn't match any of the other Case Statements. This can\\nbe used in a variety of ways; for example, if the end result is to send a message to\\nchat, you can have a default message that SAMMI will automatically fall back on\\ninstead of sending a message that only says \\\"undefined\\\". If you have an image roller,\\nyou can set an image that will display as so that you don't end up with a blank source.\", \"v0\": 11.0 }, { \"cmd\": 24.0, \"obsid\": \"Main\", \"pos\": 16.0, \"v3\": { \"SuperSuperRareIITurbo\": 23.0, \"default\": 25.0, \"SuperSuperRare\": 21.0, \"Rare\": 17.0, \"undefined\": 25.0, \"SuperRare\": 19.0 }, \"vis\": 1.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayRarityVar\", \"v0\": 10.0 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 17.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"Rare\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"cmd\": 142.0, \"obsid\": \"Main\", \"pos\": 18.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"You got a Rare!\" }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 19.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"SuperRare\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"cmd\": 142.0, \"obsid\": \"Main\", \"pos\": 20.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"You got a Super Rare! Nice!\" }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 21.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"SuperSuperRare\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"cmd\": 142.0, \"obsid\": \"Main\", \"pos\": 22.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"You got a Super Super Rare! WAOW SUGOI\" }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 23.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"SuperSuperRareIITurbo\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"cmd\": 142.0, \"obsid\": \"Main\", \"pos\": 24.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"You got a Super Super Rare II Turbo! You have the Heart of a Chamion.\" }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"undefined\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 25.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 25.0, \"b16\": \"\", \"b0\": \"default\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 2.0 }, { \"cmd\": 142.0, \"obsid\": \"Main\", \"pos\": 26.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"This is a fallback if SAMMI returns an \\\"undefined\\\" or pulls a value that isn't one of the above somehow.\" } ], \"press_type\": 0.0, \"x\": 0.83333333333333337034076748750522, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"ID112\", \"button_duration\": 20.0, \"y\": 0.25, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 1.0, \"stretch\": 0.0 }, { \"color\": 24761.0, \"persistent\": 1.0, \"text\": \"Chat\\nUnlock\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 188.0, \"b0\": \"AUTO CHAT UNLOCK\\n---\\nPull down for more info:\\nA simple set of SAMMI commands that automatically turns off\\nUnique Chatters Mode, Emote Only Mode, and Followers Only Mode. It also\\nclears any previous chat.\\n\\nYou can make this an automation by right clicking on this button, going to\\n\\\"Edit Trigger\\\", then selecting \\\"OBS Trigger\\\" and Update Type \\\"StreamStarted\\\".\\nThis will automatically \\\"unlock\\\" chat when you start streaming in OBS.\", \"v0\": 4.0 }, { \"b1\": \"\", \"cmd\": 263.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\" }, { \"cmd\": 301.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\", \"v0\": 1.0 }, { \"cmd\": 290.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\", \"v0\": 1.0 }, { \"cmd\": 287.0, \"v1\": 0.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\", \"v0\": 1.0 } ], \"press_type\": 0.0, \"x\": 0.83333333333333337034076748750522, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"ID121\", \"button_duration\": 0.0, \"y\": 0.91666666666666662965923251249478, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 24761.0, \"persistent\": 1.0, \"text\": \"Chat\\nLock\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 146.0, \"b0\": \"AUTO CHAT LOCK\\n---\\nA simple set of SAMMI commands that automatically turns on\\nUnique Chatters Mode, Emote Only Mode, and Followers Only Mode.\\n\\nYou can make this an automation by right clicking on this button, going to\\n\\\"Edit Trigger\\\", then selecting \\\"OBS Trigger\\\" and Update Type \\\"StreamStopped\\\".\\nThis will automatically \\\"lock\\\" chat when you've stopped streaming in OBS.\", \"v0\": 3.0 }, { \"cmd\": 301.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\", \"v0\": 0.0 }, { \"cmd\": 290.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\", \"v0\": 0.0 }, { \"cmd\": 287.0, \"v1\": 7.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\", \"v0\": 0.0 } ], \"press_type\": 0.0, \"x\": 0.83333333333333337034076748750522, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"ID122\", \"button_duration\": 0.0, \"y\": 0.83333333333333337034076748750522, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 12632256.0, \"persistent\": 1.0, \"text\": \"Persistent Thing\\nCounter\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ ], \"press_type\": 0.0, \"x\": 0.66666666666666662965923251249478, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666668517038374375261, \"button_id\": \"ID316\", \"button_duration\": 0.0, \"y\": 0.083333333333333328707404064061848, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 64.0, \"stretch\": 0.0 }, { \"color\": 2098242.0, \"persistent\": 1.0, \"text\": \"+1\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 185.0, \"b0\": \"PERSISTENT THING COUNTER (+1)\\n---\\nIncreases a number by 1 each time the button is pressed, and updates a text\\nsource to match using a variable.\\n\\nRun the \\\"Initialize SFTL Test Lab\\\" button first to see it in action.\\n\\nRelies on an existing INI file to load from and write to; if the INI is missing\\nor otherwise modified in a way that SAMMI can't pull the number, you'll get an\\nerror and\\/or a result of \\\"undefined\\\".\", \"v0\": 5.0 }, { \"b1\": \"counter\", \"b3\": \"varInitial\", \"cmd\": 125.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftltestlab\\/sftlsettings\", \"b2\": \"number\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varInitial\" }, { \"b1\": \"=\", \"cmd\": 15.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varCurrent\", \"b2\": \"(varInitial+1)\" }, { \"b1\": \"counter\", \"b3\": \"varCurrent\", \"cmd\": 124.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftltestlab\\/sftlsettings\", \"b2\": \"number\" }, { \"b1\": \"Thing Counter: \\/$varCurrent$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Thing Counter\" } ], \"press_type\": 0.0, \"x\": 0.66666666666666662965923251249478, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.083333333333333342585191871876305, \"button_id\": \"ID442\", \"button_duration\": 0.0, \"y\": 0.1666666666666666574148081281237, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 2098242.0, \"persistent\": 1.0, \"text\": \"-1\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 182.0, \"b0\": \"PERSISTENT THING COUNTER (-1)\\n---\\nDecreases a number by 1 each time the button is pressed, and updates a text\\nsource to match using a variable.\\n\\nRun the \\\"Initialize SFTL Test Lab\\\" button first to see it in action.\\n\\nRelies on an existing INI file to load from and write to; if the INI is missing\\nor otherwise modified in a way that SAMMI can't pull the number, you'll get an\\nerror and\\/or a result of \\\"undefined\\\".\", \"v0\": 5.0 }, { \"b1\": \"counter\", \"b3\": \"varInitial\", \"cmd\": 125.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftltestlab\\/sftlsettings\", \"b2\": \"number\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varInitial\" }, { \"b1\": \"=\", \"cmd\": 15.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varCurrent\", \"b2\": \"(varInitial-1)\" }, { \"b1\": \"counter\", \"b3\": \"varCurrent\", \"cmd\": 124.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftltestlab\\/sftlsettings\", \"b2\": \"number\" }, { \"b1\": \"Thing Counter: \\/$varCurrent$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Thing Counter\" } ], \"press_type\": 0.0, \"x\": 0.66666666666666662965923251249478, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.083333333333333342585191871876305, \"button_id\": \"ID443\", \"button_duration\": 0.0, \"y\": 0.25, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 2098242.0, \"persistent\": 1.0, \"text\": \" Set to 0 \", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 163.0, \"b0\": \"PERSISTENT THING COUNTER (O)\\n---\\nSets the counter to 0 and updates a text source to match using a variable.\\n\\nRun the \\\"Initialize SFTL Test Lab\\\" button first to see it in action.\\n\\nRelies on an existing INI file to load from and write to; if the INI is missing\\nor otherwise modified in a way that SAMMI can't pull the number, you'll get an\\nerror and\\/or a result of \\\"undefined\\\".\", \"v0\": 4.0 }, { \"b1\": \"counter\", \"b3\": \"0\", \"cmd\": 124.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftltestlab\\/sftlsettings\", \"b2\": \"number\" }, { \"b1\": \"=\", \"cmd\": 15.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varCurrent\", \"b2\": \"0\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varCurrent\" }, { \"b1\": \"Thing Counter: \\/$varCurrent$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Thing Counter\" } ], \"press_type\": 0.0, \"x\": 0.75, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.083333333333333342585191871876305, \"button_id\": \"ID445\", \"button_duration\": 0.0, \"y\": 0.1666666666666666574148081281237, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 2098242.0, \"persistent\": 1.0, \"text\": \" Set to # \", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 189.0, \"b0\": \"PERSISTENT THING COUNTER (Set to #)\\n---\\nBrings up a pop-up prompt from SAMMI to enter a custom number, then\\nupdates a text source to that new number.\\n\\nRun the \\\"Initialize SFTL Test Lab\\\" button first to see it in action.\\n\\nRelies on an existing INI file to load from and write to; if the INI is missing\\nor otherwise modified in a way that SAMMI can't pull the number, you'll get an\\nerror and\\/or a result of \\\"undefined\\\".\", \"v0\": 0.0 }, { \"b1\": \"\", \"cmd\": 214.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Set number to:\", \"b2\": \"varCustom\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varCustom\" }, { \"b1\": \"counter\", \"b3\": \"varCustom\", \"cmd\": 124.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftltestlab\\/sftlsettings\", \"b2\": \"number\" }, { \"b1\": \"Thing Counter: \\/$varCustom$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Thing Counter\" } ], \"press_type\": 0.0, \"x\": 0.75, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.083333333333333342585191871876305, \"button_id\": \"ID446\", \"button_duration\": 0.0, \"y\": 0.25, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 0.0, \"persistent\": 1.0, \"text\": \"Initialize\\nSFTL Test Lab\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 188.0, \"b0\": \"INITIALIZE SFTL TEST LAB\\n---\\n!!Run this button first while OBS is running before using any other buttons!!\\n\\nAlso make sure you've grabbed \\\"SFTLTestPack.zip\\\" and unzipped it directly to your SAMMI\\ninstallation directory.\\n\\nThis will ensure that scenes, sources, and INI files are made and that the right\\nfiles are being used. If the file names or folder structures have been changed,\\ncertain parts of this will fail.\", \"v0\": 49.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Scene \\/\\/ SFTL Test Lab\", \"v0\": 1.0 }, { \"cmd\": 50.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Overlay\", \"v0\": 1.0 }, { \"b1\": \"image_source\", \"b3\": \"{\\\"file\\\":\\\"\\/$global.main_directory_slash$\\/sftltestlab\\/images\\/overlay.png\\\"} \", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 100.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Overlay \\/\\/ 16:9\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 0.0, \"ms\": 100.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Image\", \"v0\": 2.0 }, { \"b1\": \"image_source\", \"b3\": \"{\\\"file\\\":\\\"\\/$global.main_directory_slash$\\/\\/SFTLTestLab\\/images\\/monitor.png\\\"}\", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 300.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Image\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 350.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"-300\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 0.0, \"ms\": 300.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 3\", \"v0\": 3.0 }, { \"b1\": \"text_gdiplus_v2\", \"b3\": \"{}\", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 500.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 3\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"b1\": \"{\\n \\\"outline\\\": true,\\n \\\"text\\\": \\\"Line 3\\\",\\n \\\"font\\\": {\\n \\\"face\\\": \\\"Arial\\\",\\n \\\"size\\\": 48,\\n \\\"style\\\": \\\"Regular\\\",\\n \\\"flags\\\": 1,\\n },\\n \\\"outline_size\\\": 12,\\n \\\"outline_color\\\": 4278190080\\n}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 550.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 3\" }, { \"b1\": \"Alert \\/\\/ Line 3\", \"b3\": \"360\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 550.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"-450\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 0.0, \"ms\": 300.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 2\", \"v0\": 3.0 }, { \"b1\": \"text_gdiplus_v2\", \"b3\": \"{}\", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 700.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 2\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"b1\": \"{\\n \\\"outline\\\": true,\\n \\\"text\\\": \\\"Line 2\\\",\\n \\\"font\\\": {\\n \\\"face\\\": \\\"Arial\\\",\\n \\\"size\\\": 48,\\n \\\"style\\\": \\\"Regular\\\",\\n \\\"flags\\\": 1,\\n },\\n \\\"outline_size\\\": 12,\\n \\\"outline_color\\\": 4278190080\\n}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 750.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 2\" }, { \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 750.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"-450\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 0.0, \"ms\": 450.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 1\", \"v0\": 3.0 }, { \"b1\": \"text_gdiplus_v2\", \"b3\": \"{}\", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 17.0, \"vis\": 1.0, \"ms\": 900.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 1\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"b1\": \"{\\n \\\"outline\\\": true,\\n \\\"text\\\": \\\"Line 1\\\",\\n \\\"font\\\": {\\n \\\"face\\\": \\\"Arial\\\",\\n \\\"size\\\": 48,\\n \\\"style\\\": \\\"Regular\\\",\\n \\\"flags\\\": 1,\\n },\\n \\\"outline_size\\\": 12,\\n \\\"outline_color\\\": 4278190080\\n}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 18.0, \"vis\": 1.0, \"ms\": 950.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 1\" }, { \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"240\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 19.0, \"vis\": 1.0, \"ms\": 950.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"-450\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 20.0, \"vis\": 0.0, \"ms\": 450.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Subscribers\", \"v0\": 3.0 }, { \"b1\": \"text_gdiplus_v2\", \"b3\": \"{}\", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 21.0, \"vis\": 1.0, \"ms\": 1100.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Subscribers\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"b1\": \"{\\n \\\"outline\\\": true,\\n \\\"text\\\": \\\"Subscribers: ABC \\/ XYZ\\\",\\n \\\"font\\\": {\\n \\\"face\\\": \\\"Arial\\\",\\n \\\"size\\\": 48,\\n \\\"style\\\": \\\"Regular\\\",\\n \\\"flags\\\": 1,\\n },\\n \\\"outline_size\\\": 12,\\n \\\"outline_color\\\": 4278190080\\n}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 22.0, \"vis\": 1.0, \"ms\": 1150.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Subscribers\" }, { \"b1\": \"Tracker \\/\\/ Subscribers\", \"b3\": \"1020\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 23.0, \"vis\": 1.0, \"ms\": 1150.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"460\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 24.0, \"vis\": 0.0, \"ms\": 450.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Followers\", \"v0\": 3.0 }, { \"b1\": \"text_gdiplus_v2\", \"b3\": \"{}\", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 25.0, \"vis\": 1.0, \"ms\": 1300.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Followers\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"b1\": \"{\\n \\\"outline\\\": true,\\n \\\"text\\\": \\\"Followers: ABC \\/ XYZ\\\",\\n \\\"font\\\": {\\n \\\"face\\\": \\\"Arial\\\",\\n \\\"size\\\": 48,\\n \\\"style\\\": \\\"Regular\\\",\\n \\\"flags\\\": 1,\\n },\\n \\\"outline_size\\\": 12,\\n \\\"outline_color\\\": 4278190080\\n}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 26.0, \"vis\": 1.0, \"ms\": 1350.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Followers\" }, { \"b1\": \"Tracker \\/\\/ Followers\", \"b3\": \"960\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 27.0, \"vis\": 1.0, \"ms\": 1350.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"460\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 28.0, \"vis\": 0.0, \"ms\": 450.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Thing Counter\", \"v0\": 3.0 }, { \"b1\": \"text_gdiplus_v2\", \"b3\": \"{}\", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 29.0, \"vis\": 1.0, \"ms\": 1500.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Thing Counter\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"b1\": \"{\\n \\\"outline\\\": true,\\n \\\"text\\\": \\\"Thing Counter: 0\\\",\\n \\\"font\\\": {\\n \\\"face\\\": \\\"Arial\\\",\\n \\\"size\\\": 48,\\n \\\"style\\\": \\\"Regular\\\",\\n \\\"flags\\\": 1,\\n },\\n \\\"outline_size\\\": 12,\\n \\\"outline_color\\\": 4278190080\\n}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 30.0, \"vis\": 1.0, \"ms\": 1550.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Thing Counter\" }, { \"b1\": \"Tracker \\/\\/ Thing Counter\", \"b3\": \"1020\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 31.0, \"vis\": 1.0, \"ms\": 1550.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"1200\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 32.0, \"vis\": 0.0, \"ms\": 550.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Random \\/\\/ Image\", \"v0\": 2.0 }, { \"b1\": \"image_source\", \"b3\": \"{}\", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 33.0, \"vis\": 1.0, \"ms\": 1700.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Random \\/\\/ Image\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"b1\": \"Random \\/\\/ Image\", \"b3\": \"780\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 34.0, \"vis\": 1.0, \"ms\": 1750.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"1620\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 35.0, \"vis\": 0.0, \"ms\": 550.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 5\", \"v0\": 2.0 }, { \"b1\": \"image_source\", \"b3\": \"{}\", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 36.0, \"vis\": 1.0, \"ms\": 1800.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 5\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"b1\": \"Chaos \\/\\/ Source 5\", \"b3\": \"0\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 37.0, \"vis\": 1.0, \"ms\": 1850.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"0\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 38.0, \"vis\": 0.0, \"ms\": 550.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 4\", \"v0\": 2.0 }, { \"b1\": \"image_source\", \"b3\": \"{}\", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 39.0, \"vis\": 1.0, \"ms\": 1900.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 4\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"b1\": \"Chaos \\/\\/ Source 4\", \"b3\": \"0\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 40.0, \"vis\": 1.0, \"ms\": 1950.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"0\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 41.0, \"vis\": 0.0, \"ms\": 550.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 3\", \"v0\": 2.0 }, { \"b1\": \"image_source\", \"b3\": \"{}\", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 42.0, \"vis\": 1.0, \"ms\": 2000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 3\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"b1\": \"Chaos \\/\\/ Source 3\", \"b3\": \"0\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 43.0, \"vis\": 1.0, \"ms\": 2050.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"0\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 44.0, \"vis\": 0.0, \"ms\": 550.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 2\", \"v0\": 2.0 }, { \"b1\": \"image_source\", \"b3\": \"{}\", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 45.0, \"vis\": 1.0, \"ms\": 2100.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 2\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"b1\": \"Chaos \\/\\/ Source 2\", \"b3\": \"0\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 46.0, \"vis\": 1.0, \"ms\": 2150.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"0\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 47.0, \"vis\": 0.0, \"ms\": 550.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 1\", \"v0\": 2.0 }, { \"b1\": \"image_source\", \"b3\": \"{}\", \"cmd\": 47.0, \"obsid\": \"Main\", \"pos\": 48.0, \"vis\": 1.0, \"ms\": 2200.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 1\", \"b2\": \"SFTL Test Lab\", \"v0\": 1.0 }, { \"b1\": \"Chaos \\/\\/ Source 1\", \"b3\": \"0\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 49.0, \"vis\": 1.0, \"ms\": 2250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"0\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 50.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"INI Creation\", \"v0\": 1.0 }, { \"b1\": \"counter\", \"b3\": \"0\", \"cmd\": 126.0, \"obsid\": \"Main\", \"pos\": 51.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 68.0, \"b0\": \"sftltestlab\\/sftlsettings\", \"b2\": \"number\" } ], \"press_type\": 0.0, \"x\": 0.83333333333333337034076748750522, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"ID422\", \"button_duration\": 2250.0, \"y\": 0.0, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 16747008.0, \"persistent\": 0.0, \"text\": \"Follow\\nAlert\", \"release_duration\": 0.0, \"queueable\": 1.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 210.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nThis is a basic follow alert that has an image and text slide in and out,\\ncomplete with an audio jingle. It's similar to something you might see\\nfrom StreamLabs, StreamElements, or Twitch's new Alert Box widget, but\\ninfinitely more customizable. You have complete control over every last\\nbit of what happens when you get a new follower!\\n\\nMake sure you've unzipped the apropriate files to your SAMMI installation\\nfolder and run the \\\"Initial File Creation\\\" button, or SAMMI will give you\\na bunch of errors.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 33.0, \"b0\": \"GET NEW FOLLOWER INFO\\n---\\nPull down for more info:\\nPulls the name of the latest follower and saves it as a variable.\\nIf you want to set this yourself, make sure you use the drop-down\\nto select Twitch Follow > Display Name. Simply typing in \\\"display_name\\\"\\nwon't work, as SAMMI won't know what it's supposed to pull.\\n\\nThe follower name will only show in places you specify via the\\nvariable. If you don't want to pull this information *at all*,\\nyou can safely disable or delete this set of commands. In the\\ncase that it's disabled, make sure the \\/$followName$\\/ variable\\nis removed or disabled elsewhere, or it'll be replaced with\\n\\\"undefined\\\".\", \"v0\": 2.0 }, { \"b1\": \"display_name\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"followName\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"followName\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"ALERT ACTIONS\\n---\\nPull down for more info:\\nA simple random image example that will play out in the SFTL Test Lab is\\nincluded below. This is SAMMI - if you can dream it up, you can make it\\nhappen, so don't be afraid to experiment! (Just make a backup of what\\nyou're working on first.)\", \"v0\": 12.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 36.0, \"b0\": \"UPDATE TEXT SOURCES\\n---\\nPull down for more info:\\nLine 1 will display a pre-set message, while Line 2 uses the\\n\\\"followName\\\" variable that was pulled earlier to display the\\nname that was pulled. If you don't want to display a follower\\nname, you can disable Line 2.\", \"v0\": 2.0 }, { \"b1\": \"Thanks for the follow,\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 1\" }, { \"b1\": \"\\/$followName$\\/!\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 2\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 32.0, \"b0\": \"SLIDE IN \\/ OUT\\n---\\nPull down for more info:\\nA set of actions that will have an image slide in from the left of\\nthe screen followed by text, stay on screen for a few seconds, then\\nslide out.\\n\\n(As an additional note, for your own alerts, you'll need to go to\\nthe Transform tool and make some additional adjustments to the\\nBounding Box Type, Alignment in Bounding Box, and Bounding Box Size.\\nLonger names will bleed over into the visible area if you leave the\\nsettings as-is, so experiment to see what works best for your layout.\\n\\nI tried to do this as part of the \\\"Initialize SFTL Test Lab\\\" button, I\\nreally, truly did, but JSON is NOT my passion in life and OBS absolutely\\nrefused to import the settings I wanted for sources.\\nSame goes for fading in and out - you'll need to add that yourself via\\n\\\"Motion: Alpha Filter\\\" [in OBS v28 and above] or \\\"Motion: Filter Settings\\\"\\n[in OBS v27 and below]. Despite my best efforts, I wasn't able to import\\nthis via JSON.)\", \"v0\": 6.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-300\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"260\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"260\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 360.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"5\", \"b2\": \"-435\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"105\", \"b2\": \"-215\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 1.0, \"ms\": 4010.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-215\", \"b2\": \"105\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"260\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"260\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 4360.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-435\", \"b2\": \"5\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 4660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-300\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 0.0, \"ms\": 4660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"SOUND EFFECT\\n---\\nPull down for more info:\\nPlays a sound effect. SAMMI requires that sounds be in .ogg format.\\nYou can use a free tool like Audacity or ocenaudio to convert most\\nfiles to .ogg without much fuss.\", \"v0\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/tada.ogg\", \"v0\": 0.64893617021276595036027856622241 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 17.0, \"vis\": 1.0, \"ms\": 7250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"CHAT MESSAGE\\n---\\nPull down for more info:\\nJust what it says on the tin, sends a message to chat.\\n\\/$followName$\\/ can be used to auto-fill the follower name.\", \"v0\": 1.0, \"comment_color\": 10830180.0 }, { \"b1\": \"YOUR CHANNEL HERE\", \"cmd\": 148.0, \"obsid\": \"Main\", \"pos\": 18.0, \"vis\": 1.0, \"ms\": 4000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Thank you for the follow, \\/$followName$\\/!\" } ], \"press_type\": 0.0, \"x\": 0.0, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"group_id\": \"alert\", \"button_id\": \"ID95\", \"trg\": 6.0 } ], \"group_id\": \"alert\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.1666666666666666574148081281237, \"button_id\": \"ID95\", \"button_duration\": 5160.0, \"y\": 0.1666666666666666574148081281237, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 147.0, \"stretch\": 0.0 }, { \"color\": 16747008.0, \"persistent\": 0.0, \"text\": \"Gift Sub\\nAlert\", \"release_duration\": 0.0, \"queueable\": 1.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 162.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nThis follows the same principles outlined in the Follow Alert button.\\nI'd recommend taking a look at that first before getting into setting\\none up for Subscribers, but I'm not a cop. You do you.\\n\\nMake sure you've unzipped the apropriate files to your SAMMI installation\\nfolder and run the \\\"Initial File Creation\\\" button, or SAMMI will give you\\na bunch of errors.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"GET NEW SUBSCRIBER INFO\\n---\\nPull down for more info:\\nPulls various bits of data related to the latest subscriber and saves\\nthem as variables. \\nIf you want to set this yourself, make sure you use the drop-down.\\nSimply typing in \\\"display_name\\\", etc. won't work, as SAMMI won't\\nknow what it's supposed to pull.\\n\\nThse variables will only show in places you specify via the\\nvariable.\", \"v0\": 6.0 }, { \"b1\": \"display_name\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subName\" }, { \"b1\": \"gifted_display_name\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subGift\" }, { \"b1\": \"amount\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subAmount\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subName\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subGift\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subAmount\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"ALERT ACTIONS\\n---\\nPull down for more info:\\nA simple random image example that will play out in the SFTL Test Lab is\\nincluded below. This is SAMMI - if you can dream it up, you can make it\\nhappen, so don't be afraid to experiment! (Just make a backup of what\\nyou're working on first.)\", \"v0\": 15.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"UPDATE TEXT SOURCES\\n---\\nPull down for more info:\\nLine 1 will display a pre-set message, while Line 2 uses the\\n\\\"subName\\\" variable that was pulled earlier to display the\\nname that was pulled.\", \"v0\": 3.0 }, { \"b1\": \"\\/$subName$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 1\" }, { \"b1\": \"gifted a sub to\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 2\" }, { \"b1\": \"\\/$subGift$\\/!\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 3\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"SLIDE IN \\/ OUT\\n---\\nPull down for more info:\\nA set of actions that will have an image slide in from the left of\\nthe screen followed by text, stay on screen for a few seconds, then\\nslide out.\\n\\n(As an additional note, for your own alerts, you'll need to go to\\nthe Transform tool and make some additional adjustments to the\\nBounding Box Type, Alignment in Bounding Box, and Bounding Box Size.\\nLonger names will bleed over into the visible area if you leave the\\nsettings as-is, so experiment to see what works best for your layout.\\n\\nI tried to do this as part of the \\\"Initialize SFTL Test Lab\\\" button, I\\nreally, truly did, but JSON is NOT my passion in life and OBS absolutely\\nrefused to import the settings I wanted for sources.\\nSame goes for fading in and out - you'll need to add that yourself via\\n\\\"Motion: Alpha Filter\\\" [in OBS v28 and above] or \\\"Motion: Filter Settings\\\"\\n[in OBS v27 and below]. Despite my best efforts, I wasn't able to import\\nthis via JSON.)\", \"v0\": 8.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-300\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"240\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"240\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 360.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 1.0, \"ms\": 660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"360\", \"b1\": \"Alert \\/\\/ Line 3\", \"b3\": \"360\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 17.0, \"vis\": 1.0, \"ms\": 960.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"360\", \"b1\": \"Alert \\/\\/ Line 3\", \"b3\": \"360\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 18.0, \"vis\": 1.0, \"ms\": 4960.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 19.0, \"vis\": 1.0, \"ms\": 5260.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"240\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"240\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 20.0, \"vis\": 1.0, \"ms\": 5560.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 21.0, \"vis\": 1.0, \"ms\": 5860.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-300\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 22.0, \"vis\": 0.0, \"ms\": 4660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"SOUND EFFECT\\n---\\nPull down for more info:\\nPlays a sound effect. SAMMI requires that sounds be in .ogg format.\\nYou can use a free tool like Audacity or ocenaudio to convert most\\nfiles to .ogg without much fuss.\", \"v0\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 23.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/tada.ogg\", \"v0\": 0.64893617021276595036027856622241 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 24.0, \"vis\": 1.0, \"ms\": 7250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 33.0, \"b0\": \"CHAT MESSAGE\\n---\\nPull down for more info:\\n\\/$subName$\\/ can be used to auto-fill the gift-giver.\\n\\/$subGift$\\/ can be used to auto-fill the recipient.\", \"v0\": 1.0, \"comment_color\": 10830180.0 }, { \"b1\": \"YOUR CHANNEL HERE\", \"cmd\": 148.0, \"obsid\": \"Main\", \"pos\": 25.0, \"vis\": 1.0, \"ms\": 4000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$subName$\\/ gifted a sub to \\/$subGift$\\/! Thank you!\" } ], \"press_type\": 0.0, \"x\": 0.0, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"anonsubgift\": 1.0, \"tier2\": 1.0, \"subgift\": 1.0, \"normalsub\": 0.0, \"monthmax\": 2.0, \"prime\": 0.0, \"group_id\": \"alert\", \"allowcommunity\": 0.0, \"tier3\": 1.0, \"tier1\": 1.0, \"button_id\": \"ID3\", \"trg\": 1.0, \"monthrange\": 0.0, \"monthmin\": 1.0 } ], \"group_id\": \"alert\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.1666666666666666574148081281237, \"button_id\": \"ID3\", \"button_duration\": 6360.0, \"y\": 0.33333333333333331482961625624739, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 147.0, \"stretch\": 0.0 }, { \"color\": 16747008.0, \"persistent\": 0.0, \"text\": \"Subscriber\\nAlert\", \"release_duration\": 0.0, \"queueable\": 1.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 256.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nThis follows the same principles outlined in the Follow Alert button.\\nI'd recommend taking a look at that first before getting into setting\\none up for Subscribers, but I'm not a cop. You do you.\\n\\nMake sure you've unzipped the apropriate files to your SAMMI installation\\nfolder and run the \\\"Initial File Creation\\\" button, or SAMMI will give you\\na bunch of errors.\\n\\nAdditional settings can be set by right clicking on the button and going\\nto Edit Triggers - for example, you can create separate Subscriber alerts\\nfor new and returning subs.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 33.0, \"b0\": \"GET NEW SUBSCRIBER INFO\\n---\\nPull down for more info:\\nPulls various bits of data related to the latest subscriber and saves\\nthem as variables. \\\"subGift\\\" and \\\"subAmount\\\" aren't strictly necessary,\\nbut it makes for a nice template for alerts that DO use those things.\\nIf you want to set this yourself, make sure you use the drop-down\\nto select Twitch Subscriber > Display Name. Simply typing in \\\"display_name\\\"\\nwon't work, as SAMMI won't know what it's supposed to pull.\\n\\nThse variables will only show in places you specify via the\\nvariable. If you don't want to pull this information *at all*,\\nyou can safely disable or delete this set of commands. In the\\ncase that it's disabled, make sure the variables are removed\\nor disabled elsewhere, or they'll be replaced with\\n\\\"undefined\\\".\", \"v0\": 6.0 }, { \"b1\": \"display_name\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subName\" }, { \"b1\": \"gifted_display_name\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subGift\" }, { \"b1\": \"amount\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subAmount\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subName\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subGift\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subAmount\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"ALERT ACTIONS\\n---\\nPull down for more info:\\nA simple random image example that will play out in the SFTL Test Lab is\\nincluded below. This is SAMMI - if you can dream it up, you can make it\\nhappen, so don't be afraid to experiment! (Just make a backup of what\\nyou're working on first.)\", \"v0\": 12.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"UPDATE TEXT SOURCES\\n---\\nPull down for more info:\\nLine 1 will display a pre-set message, while Line 2 uses the\\n\\\"subName\\\" variable that was pulled earlier to display the\\nname that was pulled.\", \"v0\": 2.0 }, { \"b1\": \"Thanks for the sub,\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 1\" }, { \"b1\": \"\\/$subName$\\/!\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 2\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"SLIDE IN \\/ OUT\\n---\\nPull down for more info:\\nA set of actions that will have an image slide in from the left of\\nthe screen followed by text, stay on screen for a few seconds, then\\nslide out.\\n\\n(As an additional note, for your own alerts, you'll need to go to\\nthe Transform tool and make some additional adjustments to the\\nBounding Box Type, Alignment in Bounding Box, and Bounding Box Size.\\nLonger names will bleed over into the visible area if you leave the\\nsettings as-is, so experiment to see what works best for your layout.\\n\\nI tried to do this as part of the \\\"Initialize SFTL Test Lab\\\" button, I\\nreally, truly did, but JSON is NOT my passion in life and OBS absolutely\\nrefused to import the settings I wanted for sources.\\nSame goes for fading in and out - you'll need to add that yourself via\\n\\\"Motion: Alpha Filter\\\" [in OBS v28 and above] or \\\"Motion: Filter Settings\\\"\\n[in OBS v27 and below]. Despite my best efforts, I wasn't able to import\\nthis via JSON.)\", \"v0\": 6.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-300\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"240\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"240\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 360.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 1.0, \"ms\": 5260.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"240\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"240\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 17.0, \"vis\": 1.0, \"ms\": 5560.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 18.0, \"vis\": 1.0, \"ms\": 5860.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-300\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 19.0, \"vis\": 0.0, \"ms\": 4660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"SOUND EFFECT\\n---\\nPull down for more info:\\nPlays a sound effect. SAMMI requires that sounds be in .ogg format.\\nYou can use a free tool like Audacity or ocenaudio to convert most\\nfiles to .ogg without much fuss.\", \"v0\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 20.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/tada.ogg\", \"v0\": 0.64893617021276595036027856622241 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 21.0, \"vis\": 1.0, \"ms\": 7250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 30.0, \"b0\": \"CHAT MESSAGE\\n---\\nPull down for more info:\\nJust what it says on the tin, sends a message to chat.\\n\\/$subName$\\/ can be used to auto-fill the subscriber name.\", \"v0\": 1.0, \"comment_color\": 10830180.0 }, { \"b1\": \"YOUR CHANNEL HERE\", \"cmd\": 148.0, \"obsid\": \"Main\", \"pos\": 22.0, \"vis\": 1.0, \"ms\": 4000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Thank you for the sub, \\/$subName$\\/!\" } ], \"press_type\": 0.0, \"x\": 0.0, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"anonsubgift\": 0.0, \"tier2\": 1.0, \"subgift\": 0.0, \"normalsub\": 1.0, \"monthmax\": 600000000.0, \"prime\": 1.0, \"group_id\": \"alert\", \"allowcommunity\": 0.0, \"tier3\": 0.0, \"tier1\": 1.0, \"button_id\": \"ID110\", \"trg\": 1.0, \"monthrange\": 0.0, \"monthmin\": 1.0 } ], \"group_id\": \"alert\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.1666666666666666574148081281237, \"button_id\": \"ID110\", \"button_duration\": 6360.0, \"y\": 0.25, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 147.0, \"stretch\": 0.0 }, { \"color\": 16747008.0, \"persistent\": 0.0, \"text\": \"Community Gift Sub\\nAlert\", \"release_duration\": 0.0, \"queueable\": 1.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 162.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nThis follows the same principles outlined in the Follow Alert button.\\nI'd recommend taking a look at that first before getting into setting\\none up for Subscribers, but I'm not a cop. You do you.\\n\\nMake sure you've unzipped the apropriate files to your SAMMI installation\\nfolder and run the \\\"Initial File Creation\\\" button, or SAMMI will give you\\na bunch of errors.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 36.0, \"b0\": \"GET NEW SUBSCRIBER INFO\\n---\\nPull down for more info:\\nPulls various bits of data related to the latest subscriber and saves\\nthem as variables. \\nIf you want to set this yourself, make sure you use the drop-down.\\nSimply typing in \\\"display_name\\\", etc. won't work, as SAMMI won't\\nknow what it's supposed to pull.\\n\\nThse variables will only show in places you specify via the\\nvariable.\", \"v0\": 6.0 }, { \"b1\": \"display_name\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subName\" }, { \"b1\": \"gifted_display_name\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subGift\" }, { \"b1\": \"amount\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subAmount\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subName\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subGift\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subAmount\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"ALERT ACTIONS\\n---\\nPull down for more info:\\nA simple random image example that will play out in the SFTL Test Lab is\\nincluded below. This is SAMMI - if you can dream it up, you can make it\\nhappen, so don't be afraid to experiment! (Just make a backup of what\\nyou're working on first.)\", \"v0\": 15.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"UPDATE TEXT SOURCES\\n---\\nPull down for more info:\\nLine 1 will display a pre-set message, while Line 2 uses the\\n\\\"subName\\\" variable that was pulled earlier to display the\\nname that was pulled.\", \"v0\": 3.0 }, { \"b1\": \"\\/$subName$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 1\" }, { \"b1\": \"gifted \\/$subAmount$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 2\" }, { \"b1\": \"community subs!\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 3\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"SLIDE IN \\/ OUT\\n---\\nPull down for more info:\\nA set of actions that will have an image slide in from the left of\\nthe screen followed by text, stay on screen for a few seconds, then\\nslide out.\\n\\n(As an additional note, for your own alerts, you'll need to go to\\nthe Transform tool and make some additional adjustments to the\\nBounding Box Type, Alignment in Bounding Box, and Bounding Box Size.\\nLonger names will bleed over into the visible area if you leave the\\nsettings as-is, so experiment to see what works best for your layout.\\n\\nI tried to do this as part of the \\\"Initialize SFTL Test Lab\\\" button, I\\nreally, truly did, but JSON is NOT my passion in life and OBS absolutely\\nrefused to import the settings I wanted for sources.\\nSame goes for fading in and out - you'll need to add that yourself via\\n\\\"Motion: Alpha Filter\\\" [in OBS v28 and above] or \\\"Motion: Filter Settings\\\"\\n[in OBS v27 and below]. Despite my best efforts, I wasn't able to import\\nthis via JSON.)\", \"v0\": 8.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-300\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"240\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"240\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 360.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 1.0, \"ms\": 660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"360\", \"b1\": \"Alert \\/\\/ Line 3\", \"b3\": \"360\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 17.0, \"vis\": 1.0, \"ms\": 960.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"360\", \"b1\": \"Alert \\/\\/ Line 3\", \"b3\": \"360\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 18.0, \"vis\": 1.0, \"ms\": 4960.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 19.0, \"vis\": 1.0, \"ms\": 5260.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"240\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"240\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 20.0, \"vis\": 1.0, \"ms\": 5560.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 21.0, \"vis\": 1.0, \"ms\": 5860.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-300\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 22.0, \"vis\": 0.0, \"ms\": 4660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"SOUND EFFECT\\n---\\nPull down for more info:\\nPlays a sound effect. SAMMI requires that sounds be in .ogg format.\\nYou can use a free tool like Audacity or ocenaudio to convert most\\nfiles to .ogg without much fuss.\", \"v0\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 23.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/tada.ogg\", \"v0\": 0.64893617021276595036027856622241 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 24.0, \"vis\": 1.0, \"ms\": 7250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 55.0, \"b0\": \"CHAT MESSAGE\\n---\\nPull down for more info:\\nJust what it says on the tin, sends a message to chat.\\n\\/$subName$\\/ can be used to auto-fill the gift-giver.\\n\\/$subAmount$\\/ can be used to auto-fill the amount given.\", \"v0\": 1.0, \"comment_color\": 10830180.0 }, { \"b1\": \"YOUR CHANNEL HERE\", \"cmd\": 148.0, \"obsid\": \"Main\", \"pos\": 25.0, \"vis\": 1.0, \"ms\": 4000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$subName$\\/ gifted \\/$subAmount$\\/ subs to the community! Thank you!\" } ], \"press_type\": 0.0, \"x\": 0.0, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"tier2\": 1.0, \"minimum\": 1.0, \"group_id\": \"alert\", \"tier3\": 1.0, \"tier1\": 1.0, \"button_id\": \"ID425\", \"trg\": 2.0, \"maximum\": 500.0 } ], \"group_id\": \"alert\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.1666666666666666574148081281237, \"button_id\": \"ID425\", \"button_duration\": 6360.0, \"y\": 0.41666666666666668517038374375261, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 147.0, \"stretch\": 0.0 }, { \"color\": 12632256.0, \"persistent\": 1.0, \"text\": \" Security Center \", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ ], \"press_type\": 0.0, \"x\": 0.83333333333333337034076748750522, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"ID350\", \"button_duration\": 0.0, \"y\": 0.66666666666666662965923251249478, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 64.0, \"stretch\": 0.0 }, { \"color\": 12632256.0, \"persistent\": 1.0, \"text\": \"Twitch Goal\\nTrackers\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ ], \"press_type\": 0.0, \"x\": 0.1666666666666666574148081281237, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666668517038374375261, \"button_id\": \"ID358\", \"button_duration\": 0.0, \"y\": 0.083333333333333328707404064061848, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 64.0, \"stretch\": 0.0 }, { \"color\": 12590996.0, \"persistent\": 1.0, \"text\": \"Twitch Points\\nCost Randomizer\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 214.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nTakes Twitch channel point redeems to the next, or previous, or same\\nlevel by randomizing the cost each time it's triggered. You can either\\nuse an array for pre-set values, or go full CHAOS MODE by using a Random\\ncommand.\\n(If you run both at once, or Option 2: Random will take priority.)\\n\\nThis is intended to be used in tandem with a trigger for\\nEdit Triggers > Twitch Channel Points so that the point redemption itself\\ntriggers the randomizer, making it fully automated.\", \"v0\": 0.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 33.0, \"b0\": \"OPTION 1: ARRAYS\\n---\\nPull down for more info:\\nCreates an array that's used for the cooldown in a later step, then pulls one of\\nthe values at random.\\n\\nThe values that we'll be using are in milliseconds, so 60000 ms = 60 seconds.\\nYou can have as many or as few values as you want, just make sure you're converting\\nmilliseconds to second properly!\", \"v0\": 7.0 }, { \"cmd\": 234.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayCost\" }, { \"cmd\": 17.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayCost\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayCost\", \"b2\": \"500\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayCost\", \"b2\": \"800\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayCost\", \"b2\": \"1200\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayCost\", \"b2\": \"3000\" }, { \"b1\": \"varCost\", \"cmd\": 101.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayCost\", \"b2\": \"\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 1.0, \"xpan\": 33.0, \"b0\": \"OPTION 2: RANDOM\\n---\\nPull down for more info:\\nUses a single Random command to roll a number from the lowest to highest possible\\nvalues. \", \"v0\": 1.0 }, { \"b1\": \"500\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varCost\", \"b2\": \"5000\", \"v0\": 0.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"TWITCH: EDIT REWARD\\n---\\nPull down for more info:\\nChanges the cost to the varCost variable from either the Array or Random\\nmethod, and sets the reward to that new value. You'll need to add the\\nreward yourself.\\n\\nSAMMI *must* already \\\"own\\\" a reward for this to work properly (via the\\nTwitch Connections > Edit Rewards window). Once the reward is owned by\\nSAMMI, you'll be able to find it in the Reward drop-down.\", \"v0\": 2.0 }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varCost\" }, { \"b1\": \"\", \"b1Name\": \"\", \"b3\": \"varCost\", \"cmd\": 186.0, \"v1\": 2.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL NAME HERE\", \"b2\": \"\", \"v0\": 2.0 } ], \"press_type\": 0.0, \"x\": 0.0, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"requireinput\": 0.0, \"user_name\": \"\", \"case_sensitive\": 0.0, \"message\": \"*\", \"group_id\": \"\", \"redeemname\": \"\", \"button_id\": \"ID109\", \"trg\": 3.0, \"allow_empty_wildcard\": 0.0 } ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"ID109\", \"button_duration\": 10.0, \"y\": 0.83333333333333337034076748750522, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 81.0, \"stretch\": 0.0 }, { \"color\": 12590996.0, \"persistent\": 1.0, \"text\": \"Twitch Points\\nCooldown Randomizer\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 382.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nAre the cooldowns on your Twitch points too predictable? Got people\\nhovering over the redeem button watching the seconds left, making it\\ndifficult for other people to redeem them?\\n\\nThese commands pause and then unpause a reward based on set times pulled\\nat random from an array, creating a silent timer with no visible cooldown.\\nIf you want the time to be even more random, you can use a Random\\ncommand instead.\\n(If both are on, Option 2: Random will take priority since it's later.)\\n\\nThis is intended to be used in tandem with a trigger for\\nEdit Triggers > Twitch Channel Points so that the point redemption itself\\ntriggers the cooldown, making it fully automated.\\n\\nIMPORTANT: If an array is paused when SAMMI is exited, it'll *stay* paused. You may\\n want to consider a separate automation that unpauses all rewards when you\\n start a stream, start SAMMI, or similar.\", \"v0\": 0.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"OPTION 1: ARRAYS\\n---\\nPull down for more info:\\nCreates an array that's used for the cooldown in a later step, then pulls one of\\nthe values at random.\\n\\nThe values that we'll be using are in milliseconds, so 60000 ms = 60 seconds.\\nYou can have as many or as few values as you want, just make sure you're converting\\nmilliseconds to second properly!\", \"v0\": 6.0 }, { \"cmd\": 234.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayCooldown\" }, { \"cmd\": 17.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayCooldown\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayCooldown\", \"b2\": \"120000\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayCooldown\", \"b2\": \"180000\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayCooldown\", \"b2\": \"240000\" }, { \"b1\": \"varCooldown\", \"cmd\": 101.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"arrayCooldown\", \"b2\": \"\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 1.0, \"xpan\": 79.0, \"b0\": \"OPTION 2: RANDOM\\n---\\nPull down for more info:\\nUses a single Random command to roll a number from the lowest to highest possible\\nvalues. \", \"v0\": 1.0 }, { \"b1\": \"500\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varCooldown\", \"b2\": \"5000\", \"v0\": 0.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"TWITCH: EDIT REWARD\\n---\\nPull down for more info:\\nPauses a reward, waits for an amount of time (in milliseconds) based on\\nthe value pulled from the array above, then unpauses the reward. Name and\\nCost boxes left empty will not have an effect on the reward.\\n\\nPausing a reward will say \\\"Reward is temporarily unavailable. Check back for it soon.\\\"\\non Twitch, while unpausing it will make it available again nearly instantly.\\n\\nSAMMI has to \\\"own\\\" a reward for this to work properly (via the\\nTwitch Connections > Edit Rewards window). Once the reward is owned by\\nSAMMI, you'll be able to find it in the Reward drop-down.\", \"v0\": 4.0 }, { \"b1\": \"\", \"b1Name\": \"\", \"b3\": \"\", \"cmd\": 186.0, \"v1\": 1.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL NAME HERE\", \"b2\": \"\", \"v0\": 2.0 }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varCooldown\" }, { \"cmd\": 190.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varCooldown\" }, { \"b1\": \"\", \"b1Name\": \"\", \"b3\": \"\", \"cmd\": 186.0, \"v1\": 0.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL NAME HERE\", \"b2\": \"\", \"v0\": 2.0 } ], \"press_type\": 0.0, \"x\": 0.0, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"requireinput\": 0.0, \"user_name\": \"\", \"case_sensitive\": 0.0, \"message\": \"*\", \"group_id\": \"\", \"redeemname\": \"\", \"button_id\": \"ID361\", \"trg\": 3.0, \"allow_empty_wildcard\": 0.0 } ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"ID361\", \"button_duration\": 10.0, \"y\": 0.91666666666666662965923251249478, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 81.0, \"stretch\": 0.0 }, { \"color\": 12632256.0, \"persistent\": 1.0, \"text\": \" Twitch Points \", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ ], \"press_type\": 0.0, \"x\": 0.0, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.1666666666666666574148081281237, \"button_id\": \"ID362\", \"button_duration\": 0.0, \"y\": 0.75, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 64.0, \"stretch\": 0.0 }, { \"color\": 16747008.0, \"persistent\": 1.0, \"text\": \"Raid\\nAlert\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 233.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nThis follows the same principles outlined in the Follow Alert button.\\nI'd recommend taking a look at that first before getting into setting\\none up for Subscribers, but I'm not a cop. You do you.\\n\\nMake sure you've unzipped the apropriate files to your SAMMI installation\\nfolder and run the \\\"Initial File Creation\\\" button, or SAMMI will give you\\na bunch of errors.\\n\\nAdditional settings can be set by right clicking on the button and going\\nto Edit Triggers, including setting minimum and maximum number of raiders.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"GET RAID INFO\\n---\\nPull down for more info:\\nPulls various bits of data related to the raid and saves\\nthem as variables. \\nIf you want to set this yourself, make sure you use the drop-down\\nto select Twitch Raid > Display Name and Twitch Raid > Amount.\\nSimply typing in \\\"display_name\\\" and \\\"amount\\\" won't work, as SAMMI\\nwon't know what it's supposed to pull.\", \"v0\": 4.0 }, { \"b1\": \"display_name\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"raidName\" }, { \"b1\": \"amount\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"raidAmount\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"raidName\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"raidAmount\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 33.0, \"b0\": \"ALERT ACTIONS\\n---\\nPull down for more info:\\nA simple image example that will play out in the SFTL Test Lab is\\nincluded below. This is SAMMI - if you can dream it up, you can make it\\nhappen, so don't be afraid to experiment! (Just make a backup of what\\nyou're working on first.)\", \"v0\": 15.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"UPDATE TEXT SOURCES\\n---\\nPull down for more info:\\nLine 1 will display a pre-set message, while Line 2 uses the\\n\\\"subName\\\" variable that was pulled earlier to display the\\nname that was pulled.\", \"v0\": 3.0 }, { \"b1\": \"\\/$raidName$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 1\" }, { \"b1\": \"raided with \\/$raidAmount$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 2\" }, { \"b1\": \"viewers!\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 3\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"SLIDE IN \\/ OUT\\n---\\nPull down for more info:\\nA set of actions that will have an image slide in from the left of\\nthe screen followed by text, stay on screen for a few seconds, then\\nslide out.\\n\\n(As an additional note, for your own alerts, you'll need to go to\\nthe Transform tool and make some additional adjustments to the\\nBounding Box Type, Alignment in Bounding Box, and Bounding Box Size.\\nLonger names will bleed over into the visible area if you leave the\\nsettings as-is, so experiment to see what works best for your layout.\\n\\nI tried to do this as part of the \\\"Initialize SFTL Test Lab\\\" button, I\\nreally, truly did, but JSON is NOT my passion in life and OBS absolutely\\nrefused to import the settings I wanted for sources.\\nSame goes for fading in and out - you'll need to add that yourself via\\n\\\"Motion: Alpha Filter\\\" [in OBS v28 and above] or \\\"Motion: Filter Settings\\\"\\n[in OBS v27 and below]. Despite my best efforts, I wasn't able to import\\nthis via JSON.)\", \"v0\": 8.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-300\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"240\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"240\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 360.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"360\", \"b1\": \"Alert \\/\\/ Line 3\", \"b3\": \"360\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 960.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"360\", \"b1\": \"Alert \\/\\/ Line 3\", \"b3\": \"360\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 1.0, \"ms\": 4960.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 17.0, \"vis\": 1.0, \"ms\": 5260.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"240\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"240\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 18.0, \"vis\": 1.0, \"ms\": 5560.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 19.0, \"vis\": 1.0, \"ms\": 5860.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-300\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 20.0, \"vis\": 0.0, \"ms\": 4660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"SOUND EFFECT\\n---\\nPull down for more info:\\nPlays a sound effect. SAMMI requires that sounds be in .ogg format.\\nYou can use a free tool like Audacity or ocenaudio to convert most\\nfiles to .ogg without much fuss.\", \"v0\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 21.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/tada.ogg\", \"v0\": 0.64893617021276595036027856622241 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 22.0, \"vis\": 1.0, \"ms\": 7250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"CHAT MESSAGE\\n---\\nPull down for more info:\\nJust what it says on the tin, sends a message to chat.\\n\\/$raidName$\\/ can be used to auto-fill the name of the channel that raided.\\n\\/$raidAmount$\\/ can be used to auto-fill the amount of raiders that came with them.\\n\\n(You can have some fun with this and create custom messages if you're\\ncomfortable with Switch and Case Statements, but maybe that's for\\nanother time.)\", \"v0\": 1.0, \"comment_color\": 10830180.0 }, { \"b1\": \"YOUR CHANNEL HERE\", \"cmd\": 148.0, \"obsid\": \"Main\", \"pos\": 23.0, \"vis\": 1.0, \"ms\": 4000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$raidName$\\/ raided with \\/$raidAmount$\\/ viewers!\" } ], \"press_type\": 0.0, \"x\": 0.0, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"minimum\": 1.0, \"group_id\": \"\", \"button_id\": \"ID447\", \"trg\": 4.0, \"maximum\": 1000000000.0 } ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.1666666666666666574148081281237, \"button_id\": \"ID447\", \"button_duration\": 6360.0, \"y\": 0.5, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 83.0, \"stretch\": 0.0 }, { \"color\": 16747008.0, \"persistent\": 1.0, \"text\": \"Bits\\nAlert\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 229.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nThis follows the same principles outlined in the Follow Alert button.\\nI'd recommend taking a look at that first before getting into setting\\none up for Subscribers, but I'm not a cop. You do you.\\n\\nMake sure you've unzipped the apropriate files to your SAMMI installation\\nfolder and run the \\\"Initial File Creation\\\" button, or SAMMI will give you\\na bunch of errors.\\n\\nAdditional settings can be set by right clicking on the button and going\\nto Edit Triggers, including setting minimum and maximum number of raiders.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"GET BITS INFO\\n---\\nPull down for more info:\\nPulls various bits of data related to the cheer, including who and\\nhow much, and saves them as variables. \\n\\nIf you want to set this yourself, make sure you use the drop-down\\nto select Twitch Raid > Display Name and Twitch Raid > Amount.\\nSimply typing in \\\"display_name\\\" and \\\"amount\\\" won't work, as SAMMI\\nwon't know what it's supposed to pull.\", \"v0\": 4.0 }, { \"b1\": \"user_name\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"bitsName\" }, { \"b1\": \"amount\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"bitsAmount\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"bitsName\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"bitsAmount\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 33.0, \"b0\": \"ALERT ACTIONS\\n---\\nPull down for more info:\\nA simple image example that will play out in the SFTL Test Lab is\\nincluded below. This is SAMMI - if you can dream it up, you can make it\\nhappen, so don't be afraid to experiment! (Just make a backup of what\\nyou're working on first.)\", \"v0\": 15.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"UPDATE TEXT SOURCES\\n---\\nPull down for more info:\\nLine 1 will display a pre-set message, while Line 2 uses the\\n\\\"subName\\\" variable that was pulled earlier to display the\\nname that was pulled.\", \"v0\": 3.0 }, { \"b1\": \"\\/$bitsName$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 1\" }, { \"b1\": \"cheered \\/$bitsAmount$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 2\" }, { \"b1\": \"bits!\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 3\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"SLIDE IN \\/ OUT\\n---\\nPull down for more info:\\nA set of actions that will have an image slide in from the left of\\nthe screen followed by text, stay on screen for a few seconds, then\\nslide out.\\n\\n(As an additional note, for your own alerts, you'll need to go to\\nthe Transform tool and make some additional adjustments to the\\nBounding Box Type, Alignment in Bounding Box, and Bounding Box Size.\\nLonger names will bleed over into the visible area if you leave the\\nsettings as-is, so experiment to see what works best for your layout.\\n\\nI tried to do this as part of the \\\"Initialize SFTL Test Lab\\\" button, I\\nreally, truly did, but JSON is NOT my passion in life and OBS absolutely\\nrefused to import the settings I wanted for sources.\\nSame goes for fading in and out - you'll need to add that yourself via\\n\\\"Motion: Alpha Filter\\\" [in OBS v28 and above] or \\\"Motion: Filter Settings\\\"\\n[in OBS v27 and below]. Despite my best efforts, I wasn't able to import\\nthis via JSON.)\", \"v0\": 8.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-300\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"240\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"240\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 360.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"360\", \"b1\": \"Alert \\/\\/ Line 3\", \"b3\": \"360\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 960.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"360\", \"b1\": \"Alert \\/\\/ Line 3\", \"b3\": \"360\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 1.0, \"ms\": 4960.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 17.0, \"vis\": 1.0, \"ms\": 5260.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"240\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"240\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 18.0, \"vis\": 1.0, \"ms\": 5560.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 19.0, \"vis\": 1.0, \"ms\": 5860.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-300\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 20.0, \"vis\": 0.0, \"ms\": 4660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"SOUND EFFECT\\n---\\nPull down for more info:\\nPlays a sound effect. SAMMI requires that sounds be in .ogg format.\\nYou can use a free tool like Audacity or ocenaudio to convert most\\nfiles to .ogg without much fuss.\", \"v0\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 21.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/tada.ogg\", \"v0\": 0.64893617021276595036027856622241 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 22.0, \"vis\": 1.0, \"ms\": 7250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 32.0, \"b0\": \"CHAT MESSAGE\\n---\\nPull down for more info:\\n\\/$bitsName$\\/ can be used to auto-fill the name of the person who cheered.\\n\\/$bitsAmount$\\/ can be used to auto-fill the amount of bits.\", \"v0\": 1.0, \"comment_color\": 10830180.0 }, { \"b1\": \"YOUR CHANNEL HERE\", \"cmd\": 148.0, \"obsid\": \"Main\", \"pos\": 23.0, \"vis\": 1.0, \"ms\": 4000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$bitsName$\\/ cheered \\/$bitsAmount$\\/ bits!\" } ], \"press_type\": 0.0, \"x\": 0.0, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"minimum\": 1.0, \"group_id\": \"\", \"button_id\": \"ID449\", \"trg\": 5.0, \"maximum\": 10000000000.0 } ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.1666666666666666574148081281237, \"button_id\": \"ID449\", \"button_duration\": 6360.0, \"y\": 0.66666666666666662965923251249478, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 83.0, \"stretch\": 0.0 }, { \"color\": 12632256.0, \"persistent\": 1.0, \"text\": \"The\\nChaos Roller\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ ], \"press_type\": 0.0, \"x\": 0.5, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666674068153497501044, \"button_id\": \"ID119\", \"button_duration\": 0.0, \"y\": 0.083333333333333328707404064061848, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 64.0, \"stretch\": 0.0 }, { \"color\": 47373.0, \"persistent\": 1.0, \"text\": \"CHAOS\\nCONTROL\", \"release_duration\": 0.0, \"queueable\": 1.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 334.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nThis can require some advanced knowledge of SAMMI to fix\\nthings if any part of it is changed. Also note that this\\nwas tested on v29 and v30 of OBS; v27 or earlier may run\\nin to problems.\\n\\nChaos Control and the Chaos Buttons use a specific naming\\nscheme to work properly. If any of the variable names or\\nbutton IDs are changed, you'll need to adjust Chaos Control\\nand the Chaos Buttons to match.\\n\\nTriggering the button too frequently will cause a brief \\\"stutter\\\"\\neffect since it causes SAMMI to try to run multiple commands at\\nonce. It's recommended to add a short delay (either \\\"Wait for\\nTimeout\\\", \\\"Overtime\\\", or a few seconds of delay for Twitch\\nChannel Points) to avoid this.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 400.0, \"b0\": \"THE CHAOS CONTROL CENTER\\n---\\n\\\"It's a roller that rolls rollers.\\\"\\n- CodeChannel@Twitch.tv, 2023\\n\\nThink of this as a button that pushes other buttons in sequence.\\nBy using a SAMMI trigger, such as a Twitch point redeem, this\\nbutton will push a series of Chaos Buttons in order. Once it\\nruns out of buttons, it starts from the beginning again.\\n\\nEach Chaos Button queues with itself, meaing that the buttons\\nrun independently and can overlap with other buttons so you can\\nhave a train of actions in rapid succession, but still ensure\\neach redeem is triggered since it's part of an ongoing queue.\\n\\nIt's a great option for making trains of just about any randomized\\nimage, video, and audio combo you can think of. You shouldn't have\\nto touch anything in this control button unless you want more \\/\\nfewer buttons, or if you feel comfortable modifying this on your own.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"THE CHAOS CONTROL ARRAY AND SWITCH\\/CASE STATEMENTS\\n---\\nPull down for more info:\\nAs noted above, you *shouldn't* need to touch anything here unless\\nyou want to see how the sausage is made and\\/or you feel comfortable\\nmodifying the arrays and statements yourself.\\n\\nIn essence, when the array is empty, such as when the button is\\ntriggered after SAMMI starts up, it will create an array due to the\\nvariable returned being \\\"undefined\\\". The same thing happens when all\\ninserts have been pulled from the array. After the array has been\\ncreated, it pulls a variable, and presses the Chaos Button related\\nto that variable.\\nIf the array already exists, it runs the default action, which in this case\\nis only pressing the Chaos Button related to the variable that was pulled.\", \"v0\": 13.0 }, { \"b1\": \"top\", \"cmd\": 98.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chaosArray\", \"b2\": \"chaosVar\" }, { \"cmd\": 24.0, \"obsid\": \"Main\", \"pos\": 4.0, \"v3\": { \"default\": 5.0, \"undefined\": 6.0 }, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chaosVar\", \"v0\": 9.0 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"default\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 0.0, \"v2\": 1.0 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"undefined\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 7.0, \"v2\": 1.0 }, { \"cmd\": 17.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chaosArray\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chaosArray\", \"b2\": \"\\\"chaosButton5\\\"\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chaosArray\", \"b2\": \"\\\"chaosButton4\\\"\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chaosArray\", \"b2\": \"\\\"chaosButton3\\\"\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chaosArray\", \"b2\": \"\\\"chaosButton2\\\"\" }, { \"b1\": \"top\", \"cmd\": 96.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chaosArray\", \"b2\": \"\\\"chaosButton1\\\"\" }, { \"b1\": \"top\", \"cmd\": 98.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chaosArray\", \"b2\": \"chaosVar\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chaosVar\" }, { \"b1\": \"0\", \"cmd\": 132.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$chaosVar$\\/\", \"v0\": 1.0 } ], \"press_type\": 0.0, \"x\": 0.5, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.083333333333333328707404064061848, \"button_id\": \"chaosControl\", \"button_duration\": 0.0, \"y\": 0.1666666666666666574148081281237, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 193.0, \"stretch\": 0.0 }, { \"color\": 39616.0, \"persistent\": 1.0, \"text\": \"Chaos\\nButton 1\", \"release_duration\": 0.0, \"queueable\": 1.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 204.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nThis can require some advanced knowledge of SAMMI to fix\\nthings if any part of it is changed. Also note that this\\nwas tested on v29 and v30 of OBS; v27 or earlier may run\\nin to problems.\\n\\nChaos Control and the Chaos Buttons use a specific naming\\nscheme to work properly. If any of the variable names or\\nbutton IDs are changed, you'll need to adjust Chaos Control\\nand the Chaos Buttons to match.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 186.0, \"b0\": \"THE CHAOS BUTTONS\\n---\\nAs with all things SAMMI, you can program anything you want\\nfor each button to activate. This was originally put together\\nwith images with complementary sound effects in mind, so the\\nexample below will focus on that.\\n\\nNote that this will cause the images to show, but they won't\\ndisappear - you'll need to apply your own fade-out effect via\\na Motion: Alpha Filter command or other method.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"RANDOMIZE X \\/ Y VALUES AND CHANGE SOURCE POSITION\\n---\\nPull down for more info:\\nSets two variables - xpos and ypos - that will be used to determine\\nthe horizontal and vertical coordinates of the source in OBS.\\n\\nOBS defaults to the positional alignment being the top left of an\\nimage, meaning that 0,0 will make something perfectly aligned to\\nthe top left of the screen.\\n\\nIf images are different sizes, determine which ones have the\\nlargest width (X) and height (Y), and subtract those values from\\nthe Maximum Value Allowed for that particular variable. That should\\nkeep the images from being cut off, though you may need to play\\nwith the values a bit.\\n\\nFor this example, images will be 300x300, so the minimum xpos is\\n1620 while the minimum ypos is 780.\", \"v0\": 3.0, \"name\": \"\" }, { \"b1\": \"0\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"xpos\", \"b2\": \"1620\", \"v0\": 0.0 }, { \"b1\": \"0\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"ypos\", \"b2\": \"780\", \"v0\": 0.0 }, { \"b1\": \"Chaos \\/\\/ Source 1\", \"b3\": \"ypos\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"xpos\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 2000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"APPLY ALPHA FILTER\\n---\\nPull down for more info:\\nUses \\\"Motion: Alpha Filter\\\" to apply a fade-in and fade-out\\neffect. I recommend applying a \\\"Color Correction\\\" filter with\\ndefault settings.\\n\\nThe filter should be applied in the SFTL Test Lab already, but\\nif SAMMI Core gives you error messages, it may mean you need to\\napply the filters yourself.\", \"v0\": 2.0 }, { \"b1\": \"Color Correction\", \"b3\": \"1\", \"cmd\": 40.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 1\", \"b4\": \"250\", \"b2\": \"0\", \"v0\": 3.0 }, { \"b1\": \"Color Correction\", \"b3\": \"0\", \"cmd\": 40.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 2000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 1\", \"b4\": \"250\", \"b2\": \"1\", \"v0\": 3.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"Random Number Roll and Source Change\\n---\\nPull down for more info:\\nRolls a random number and saves it to a variable. The variable is then used as\\npart of a file path that's then sent to OBS as the source for an image.\\n\\nThere's two methods you can use here - you can either have all files in a folder\\nbe a number:\\n1.gif, 2.gif, 3.gif ... 27.gif, 28.gif, 29.gif, etc.\\n(Your file path would be similar to \\\"C:\\/file\\/path\\/goes\\/here\\/chaos\\/\\/$pull$\\/.gif\\\")\\n\\nOr have all files in a folder use a consistent name and number, if you're storing\\nmultiple files in one place:\\n\\nimage1.gif, image2.gif ... image28.gif, image29.gif, etc.\\n(Your file path would be similar to \\\"C:\\/file\\/path\\/goes\\/here\\/chaos\\/image\\/$pull$\\/.gif)\\n\\nFile paths need to use \\/forward slashes\\/, not \\\\back slashes\\\\, or OBS won't\\nrecognize the file path, resulting in images not displaying. Variables *also* use forward slashes, so be careful that you're not adding a\\nforward slash or confusing a variable for a file path.\", \"v0\": 2.0 }, { \"b1\": \"1\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varChaos\", \"b2\": \"4\", \"v0\": 0.0 }, { \"b1\": \"{\\\"file\\\":\\\"\\/$global.main_directory_slash$\\/\\/sftltestlab\\/chaosroller\\/\\/$varChaos$\\/.png\\\"}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 1\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 1.0, \"xpan\": 32.0, \"b0\": \"SOUND EFFECT BASED ON NUMBER ROLLED (OPTIONAL)\\n---\\nPull down for more info:\\nPlays a unique sound effect if a specific number is rolled. Useful if\\nyou need a specific sound to play alongside a specific image while the\\nrest use a default sound. There's no real limit on case statements, so\\nyou can have as many as you want.\\n\\nFor any numbers that don't have a match, SAMMI will default to the commands\\nunder the \\\"default\\\" case statement.\", \"v0\": 5.0 }, { \"cmd\": 24.0, \"obsid\": \"Main\", \"pos\": 13.0, \"v3\": { \"default\": 16.0, \"1\": 14.0 }, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varChaos\", \"v0\": 4.0 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"1\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/tada.ogg\", \"v0\": 0.6007194244604316946123390152934 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"default\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 17.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/alarm.ogg\", \"v0\": 0.6043165467625899456294291667291 } ], \"press_type\": 0.0, \"x\": 0.58333333333333337034076748750522, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.083333333333333328707404064061848, \"button_id\": \"chaosButton1\", \"button_duration\": 2000.0, \"y\": 0.1666666666666666574148081281237, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 195.0, \"stretch\": 0.0 }, { \"color\": 11272896.0, \"persistent\": 1.0, \"text\": \"Chaos\\nButton 2\", \"release_duration\": 0.0, \"queueable\": 1.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 39.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nSee Chaos Button 1 for more info!\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"RANDOMIZE X \\/ Y VALUES AND CHANGE SOURCE POSITION\\n---\\nPull down for more info:\\nSets two variables - xpos and ypos - that will be used to determine\\nthe horizontal and vertical coordinates of the source in OBS.\\n\\nOBS defaults to the positional alignment being the top left of an\\nimage, meaning that 0,0 will make something perfectly aligned to\\nthe top left of the screen.\\n\\nIf images are different sizes, determine which ones have the\\nlargest width (X) and height (Y), and subtract those values from\\nthe Maximum Value Allowed for that particular variable. That should\\nkeep the images from being cut off, though you may need to play\\nwith the values a bit.\\n\\nFor this example, images will be 300x300, so the minimum xpos is\\n1620 while the minimum ypos is 780.\", \"v0\": 3.0, \"name\": \"\" }, { \"b1\": \"0\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"xpos\", \"b2\": \"1620\", \"v0\": 0.0 }, { \"b1\": \"0\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"ypos\", \"b2\": \"780\", \"v0\": 0.0 }, { \"b1\": \"Chaos \\/\\/ Source 2\", \"b3\": \"ypos\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"xpos\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 2000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"APPLY ALPHA FILTER\\n---\\nPull down for more info:\\nUses \\\"Motion: Alpha Filter\\\" to apply a fade-in and fade-out\\neffect. I recommend applying a \\\"Color Correction\\\" filter with\\ndefault settings.\\n\\nThe filter should be applied in the SFTL Test Lab already, but\\nif SAMMI Core gives you error messages, it may mean you need to\\napply the filters yourself.\", \"v0\": 2.0 }, { \"b1\": \"Color Correction\", \"b3\": \"1\", \"cmd\": 40.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 2\", \"b4\": \"250\", \"b2\": \"0\", \"v0\": 3.0 }, { \"b1\": \"Color Correction\", \"b3\": \"0\", \"cmd\": 40.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 2000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 2\", \"b4\": \"250\", \"b2\": \"1\", \"v0\": 3.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"RANDOM NUMBER ROLL AND SOURCE CHANGE\\n---\\nPull down for more info:\\nRolls a random number and saves it to a variable. The variable is then used as\\npart of a file path that's then sent to OBS as the source for an image.\\n\\nThere's two methods you can use here - you can either have all files in a folder\\nbe a number:\\n1.gif, 2.gif, 3.gif ... 27.gif, 28.gif, 29.gif, etc.\\n(Your file path would be similar to \\\"C:\\/file\\/path\\/goes\\/here\\/chaos\\/\\/$pull$\\/.gif\\\")\\n\\nOr have all files in a folder use a consistent name and number, if you're storing\\nmultiple files in one place:\\n\\nimage1.gif, image2.gif ... image28.gif, image29.gif, etc.\\n(Your file path would be similar to \\\"C:\\/file\\/path\\/goes\\/here\\/chaos\\/image\\/$pull$\\/.gif)\\n\\nFile paths need to use \\/forward slashes\\/, not \\\\back slashes\\\\, or OBS won't\\nrecognize the file path, resulting in images not displaying. Variables *also* use forward slashes, so be careful that you're not adding a\\nforward slash or confusing a variable for a file path.\", \"v0\": 2.0 }, { \"b1\": \"1\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varChaos\", \"b2\": \"4\", \"v0\": 0.0 }, { \"b1\": \"{\\\"file\\\":\\\"\\/$global.main_directory_slash$\\/\\/sftltestlab\\/chaosroller\\/\\/$varChaos$\\/.png\\\"}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 2\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 1.0, \"xpan\": 36.0, \"b0\": \"SOUND EFFECT BASED ON NUMBER ROLLED (OPTIONAL)\\n---\\nDrag down for more info:\\nPlays a unique sound effect if a specific number is rolled. Useful if\\nyou need a specific sound to play alongside a specific image while the\\nrest use a default sound. There's no real limit on case statements, so\\nyou can have as many as you want.\\n\\nFor any numbers that don't have a match, SAMMI will default to the commands\\nunder the \\\"default\\\" case statement.\", \"v0\": 5.0 }, { \"cmd\": 24.0, \"obsid\": \"Main\", \"pos\": 12.0, \"v3\": { \"default\": 15.0, \"1\": 13.0 }, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varChaos\", \"v0\": 4.0 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"1\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/tada.ogg\", \"v0\": 0.6007194244604316946123390152934 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"default\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/alarm.ogg\", \"v0\": 0.6043165467625899456294291667291 } ], \"press_type\": 0.0, \"x\": 0.5, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.083333333333333328707404064061848, \"button_id\": \"chaosButton2\", \"button_duration\": 2000.0, \"y\": 0.25, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 195.0, \"stretch\": 0.0 }, { \"color\": 1644992.0, \"persistent\": 1.0, \"text\": \"Chaos\\nButton 3\", \"release_duration\": 0.0, \"queueable\": 1.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 39.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nSee Chaos Button 1 for more info!\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"RANDOMIZE X \\/ Y VALUES AND CHANGE SOURCE POSITION\\n---\\nPull down for more info:\\nSets two variables - xpos and ypos - that will be used to determine\\nthe horizontal and vertical coordinates of the source in OBS.\\n\\nOBS defaults to the positional alignment being the top left of an\\nimage, meaning that 0,0 will make something perfectly aligned to\\nthe top left of the screen.\\n\\nIf images are different sizes, determine which ones have the\\nlargest width (X) and height (Y), and subtract those values from\\nthe Maximum Value Allowed for that particular variable. That should\\nkeep the images from being cut off, though you may need to play\\nwith the values a bit.\\n\\nFor this example, images will be 300x300, so the minimum xpos is\\n1620 while the minimum ypos is 780.\", \"v0\": 3.0 }, { \"b1\": \"0\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"xpos\", \"b2\": \"1620\", \"v0\": 0.0 }, { \"b1\": \"0\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"ypos\", \"b2\": \"780\", \"v0\": 0.0 }, { \"b1\": \"Chaos \\/\\/ Source 3\", \"b3\": \"ypos\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"xpos\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 2000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"APPLY ALPHA FILTER\\n---\\nPull down for more info:\\nUses \\\"Motion: Alpha Filter\\\" to apply a fade-in and fade-out\\neffect. I recommend applying a \\\"Color Correction\\\" filter with\\ndefault settings.\\n\\nThe filter should be applied in the SFTL Test Lab already, but\\nif SAMMI Core gives you error messages, it may mean you need to\\napply the filters yourself.\", \"v0\": 2.0 }, { \"b1\": \"Color Correction\", \"b3\": \"1\", \"cmd\": 40.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 3\", \"b4\": \"250\", \"b2\": \"0\", \"v0\": 3.0 }, { \"b1\": \"Color Correction\", \"b3\": \"0\", \"cmd\": 40.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 2000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 3\", \"b4\": \"250\", \"b2\": \"1\", \"v0\": 3.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"RANDOM NUMBER ROLL AND SOURCE CHANGE\\n---\\nPull down for more info:\\nRolls a random number and saves it to a variable. The variable is then used as\\npart of a file path that's then sent to OBS as the source for an image.\\n\\nThere's two methods you can use here - you can either have all files in a folder\\nbe a number:\\n1.gif, 2.gif, 3.gif ... 27.gif, 28.gif, 29.gif, etc.\\n(Your file path would be similar to \\\"C:\\/file\\/path\\/goes\\/here\\/chaos\\/\\/$pull$\\/.gif\\\")\\n\\nOr have all files in a folder use a consistent name and number, if you're storing\\nmultiple files in one place:\\n\\nimage1.gif, image2.gif ... image28.gif, image29.gif, etc.\\n(Your file path would be similar to \\\"C:\\/file\\/path\\/goes\\/here\\/chaos\\/image\\/$pull$\\/.gif)\\n\\nFile paths need to use \\/forward slashes\\/, not \\\\back slashes\\\\, or OBS won't\\nrecognize the file path, resulting in images not displaying. Variables *also* use forward slashes, so be careful that you're not adding a\\nforward slash or confusing a variable for a file path.\", \"v0\": 2.0 }, { \"b1\": \"1\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varChaos\", \"b2\": \"4\", \"v0\": 0.0 }, { \"b1\": \"{\\\"file\\\":\\\"\\/$global.main_directory_slash$\\/\\/sftltestlab\\/chaosroller\\/\\/$varChaos$\\/.png\\\"}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 3\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 1.0, \"xpan\": 36.0, \"b0\": \"SOUND EFFECT BASED ON NUMBER ROLLED (OPTIONAL)\\n---\\nPull down for more info:\\nPlays a unique sound effect if a specific number is rolled. Useful if\\nyou need a specific sound to play alongside a specific image while the\\nrest use a default sound. There's no real limit on case statements, so\\nyou can have as many as you want.\\n\\nFor any numbers that don't have a match, SAMMI will default to the commands\\nunder the \\\"default\\\" case statement.\", \"v0\": 5.0 }, { \"cmd\": 24.0, \"obsid\": \"Main\", \"pos\": 12.0, \"v3\": { \"default\": 15.0, \"1\": 13.0 }, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varChaos\", \"v0\": 4.0 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"1\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/tada.ogg\", \"v0\": 0.6007194244604316946123390152934 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"default\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/alarm.ogg\", \"v0\": 0.6043165467625899456294291667291 } ], \"press_type\": 0.0, \"x\": 0.58333333333333337034076748750522, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.083333333333333328707404064061848, \"button_id\": \"chaosButton3\", \"button_duration\": 2000.0, \"y\": 0.25, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 195.0, \"stretch\": 0.0 }, { \"color\": 16103424.0, \"persistent\": 1.0, \"text\": \"Chaos\\nButton 4\", \"release_duration\": 0.0, \"queueable\": 1.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 39.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nSee Chaos Button 1 for more info!\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"RANDOMIZE X \\/ Y VALUES AND CHANGE SOURCE POSITION\\n---\\nPull down for more info:\\nSets two variables - xpos and ypos - that will be used to determine\\nthe horizontal and vertical coordinates of the source in OBS.\\n\\nOBS defaults to the positional alignment being the top left of an\\nimage, meaning that 0,0 will make something perfectly aligned to\\nthe top left of the screen.\\n\\nIf images are different sizes, determine which ones have the\\nlargest width (X) and height (Y), and subtract those values from\\nthe Maximum Value Allowed for that particular variable. That should\\nkeep the images from being cut off, though you may need to play\\nwith the values a bit.\\n\\nFor this example, images will be 300x300, so the minimum xpos is\\n1620 while the minimum ypos is 780.\", \"v0\": 3.0 }, { \"b1\": \"0\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"xpos\", \"b2\": \"1620\", \"v0\": 0.0 }, { \"b1\": \"0\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"ypos\", \"b2\": \"780\", \"v0\": 0.0 }, { \"b1\": \"Chaos \\/\\/ Source 4\", \"b3\": \"ypos\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"xpos\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 2000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"APPLY ALPHA FILTER\\n---\\nPull down for more info:\\nUses \\\"Motion: Alpha Filter\\\" to apply a fade-in and fade-out\\neffect. I recommend applying a \\\"Color Correction\\\" filter with\\ndefault settings.\\n\\nThe filter should be applied in the SFTL Test Lab already, but\\nif SAMMI Core gives you error messages, it may mean you need to\\napply the filters yourself.\", \"v0\": 2.0 }, { \"b1\": \"Color Correction\", \"b3\": \"1\", \"cmd\": 40.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 4\", \"b4\": \"250\", \"b2\": \"0\", \"v0\": 3.0 }, { \"b1\": \"Color Correction\", \"b3\": \"0\", \"cmd\": 40.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 2000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 4\", \"b4\": \"250\", \"b2\": \"1\", \"v0\": 3.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"RANDOM NUMBER ROLL AND SOURCE CHANGE\\n---\\nPull down for more info:\\nRolls a random number and saves it to a variable. The variable is then used as\\npart of a file path that's then sent to OBS as the source for an image.\\n\\nThere's two methods you can use here - you can either have all files in a folder\\nbe a number:\\n1.gif, 2.gif, 3.gif ... 27.gif, 28.gif, 29.gif, etc.\\n(Your file path would be similar to \\\"C:\\/file\\/path\\/goes\\/here\\/chaos\\/\\/$pull$\\/.gif\\\")\\n\\nOr have all files in a folder use a consistent name and number, if you're storing\\nmultiple files in one place:\\n\\nimage1.gif, image2.gif ... image28.gif, image29.gif, etc.\\n(Your file path would be similar to \\\"C:\\/file\\/path\\/goes\\/here\\/chaos\\/image\\/$pull$\\/.gif)\\n\\nFile paths need to use \\/forward slashes\\/, not \\\\back slashes\\\\, or OBS won't\\nrecognize the file path, resulting in images not displaying. Variables *also* use forward slashes, so be careful that you're not adding a\\nforward slash or confusing a variable for a file path.\", \"v0\": 2.0 }, { \"b1\": \"1\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varChaos\", \"b2\": \"4\", \"v0\": 0.0 }, { \"b1\": \"{\\\"file\\\":\\\"\\/$global.main_directory_slash$\\/\\/sftltestlab\\/chaosroller\\/\\/$varChaos$\\/.png\\\"}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 4\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 1.0, \"xpan\": 36.0, \"b0\": \"SOUND EFFECT BASED ON NUMBER ROLLED (OPTIONAL)\\n---\\nPull down for more info:\\nPlays a unique sound effect if a specific number is rolled. Useful if\\nyou need a specific sound to play alongside a specific image while the\\nrest use a default sound. There's no real limit on case statements, so\\nyou can have as many as you want.\\n\\nFor any numbers that don't have a match, SAMMI will default to the commands\\nunder the \\\"default\\\" case statement.\", \"v0\": 5.0 }, { \"cmd\": 24.0, \"obsid\": \"Main\", \"pos\": 12.0, \"v3\": { \"default\": 15.0, \"1\": 13.0 }, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varChaos\", \"v0\": 4.0 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"1\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/tada.ogg\", \"v0\": 0.6007194244604316946123390152934 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"default\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/alarm.ogg\", \"v0\": 0.6043165467625899456294291667291 } ], \"press_type\": 0.0, \"x\": 0.5, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.083333333333333328707404064061848, \"button_id\": \"chaosButton4\", \"button_duration\": 2000.0, \"y\": 0.33333333333333331482961625624739, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 195.0, \"stretch\": 0.0 }, { \"color\": 8325639.0, \"persistent\": 1.0, \"text\": \"Chaos\\nButton 5\", \"release_duration\": 0.0, \"queueable\": 1.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 39.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nSee Chaos Button 1 for more info!\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"RANDOMIZE X \\/ Y VALUES AND CHANGE SOURCE POSITION\\n---\\nPull down for more info:\\nSets two variables - xpos and ypos - that will be used to determine\\nthe horizontal and vertical coordinates of the source in OBS.\\n\\nOBS defaults to the positional alignment being the top left of an\\nimage, meaning that 0,0 will make something perfectly aligned to\\nthe top left of the screen.\\n\\nIf images are different sizes, determine which ones have the\\nlargest width (X) and height (Y), and subtract those values from\\nthe Maximum Value Allowed for that particular variable. That should\\nkeep the images from being cut off, though you may need to play\\nwith the values a bit.\\n\\nFor this example, images will be 300x300, so the minimum xpos is\\n1620 while the minimum ypos is 780.\", \"v0\": 3.0 }, { \"b1\": \"0\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"xpos\", \"b2\": \"1620\", \"v0\": 0.0 }, { \"b1\": \"0\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"ypos\", \"b2\": \"780\", \"v0\": 0.0 }, { \"b1\": \"Chaos \\/\\/ Source 5\", \"b3\": \"ypos\", \"cmd\": 22.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b2\": \"xpos\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 2000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"APPLY ALPHA FILTER\\n---\\nPull down for more info:\\nUses \\\"Motion: Alpha Filter\\\" to apply a fade-in and fade-out\\neffect. I recommend applying a \\\"Color Correction\\\" filter with\\ndefault settings.\\n\\nThe filter should be applied in the SFTL Test Lab already, but\\nif SAMMI Core gives you error messages, it may mean you need to\\napply the filters yourself.\", \"v0\": 2.0 }, { \"b1\": \"Color Correction\", \"b3\": \"1\", \"cmd\": 40.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 5\", \"b4\": \"250\", \"b2\": \"0\", \"v0\": 3.0 }, { \"b1\": \"Color Correction\", \"b3\": \"0\", \"cmd\": 40.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 2000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 5\", \"b4\": \"250\", \"b2\": \"1\", \"v0\": 3.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"RANDOM NUMBER ROLL AND SOURCE CHANGE\\n---\\nPull down for more info:\\nRolls a random number and saves it to a variable. The variable is then used as\\npart of a file path that's then sent to OBS as the source for an image.\\n\\nThere's two methods you can use here - you can either have all files in a folder\\nbe a number:\\n1.gif, 2.gif, 3.gif ... 27.gif, 28.gif, 29.gif, etc.\\n(Your file path would be similar to \\\"C:\\/file\\/path\\/goes\\/here\\/chaos\\/\\/$pull$\\/.gif\\\")\\n\\nOr have all files in a folder use a consistent name and number, if you're storing\\nmultiple files in one place:\\n\\nimage1.gif, image2.gif ... image28.gif, image29.gif, etc.\\n(Your file path would be similar to \\\"C:\\/file\\/path\\/goes\\/here\\/chaos\\/image\\/$pull$\\/.gif)\\n\\nFile paths need to use \\/forward slashes\\/, not \\\\back slashes\\\\, or OBS won't\\nrecognize the file path, resulting in images not displaying. Variables *also* use forward slashes, so be careful that you're not adding a\\nforward slash or confusing a variable for a file path.\", \"v0\": 2.0 }, { \"b1\": \"1\", \"cmd\": 77.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varChaos\", \"b2\": \"4\", \"v0\": 0.0 }, { \"b1\": \"{\\\"file\\\":\\\"\\/$global.main_directory_slash$\\/\\/sftltestlab\\/chaosroller\\/\\/$varChaos$\\/.png\\\"}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Chaos \\/\\/ Source 5\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 1.0, \"xpan\": 36.0, \"b0\": \"SOUND EFFECT BASED ON NUMBER ROLLED (OPTIONAL)\\n---\\nPull down for more info:\\nPlays a unique sound effect if a specific number is rolled. Useful if\\nyou need a specific sound to play alongside a specific image while the\\nrest use a default sound. There's no real limit on case statements, so\\nyou can have as many as you want.\\n\\nFor any numbers that don't have a match, SAMMI will default to the commands\\nunder the \\\"default\\\" case statement.\", \"v0\": 5.0 }, { \"cmd\": 24.0, \"obsid\": \"Main\", \"pos\": 12.0, \"v3\": { \"default\": 15.0, \"1\": 13.0 }, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"varChaos\", \"v0\": 4.0 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"1\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/tada.ogg\", \"v0\": 0.6007194244604316946123390152934 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"default\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/alarm.ogg\", \"v0\": 0.6043165467625899456294291667291 } ], \"press_type\": 0.0, \"x\": 0.58333333333333337034076748750522, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.083333333333333328707404064061848, \"button_id\": \"chaosButton5\", \"button_duration\": 2000.0, \"y\": 0.33333333333333331482961625624739, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 195.0, \"stretch\": 0.0 }, { \"color\": 10764644.0, \"persistent\": 1.0, \"text\": \"Twitch\\nFollower Goal\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 209.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nRuns a Twitch data pull when you start SAMMI as well as when a\\nnew follower event happens to update a text source that keeps\\ntrack of your follower goal.\\n\\nThere are two options available: \\\"Basic\\\" will display the current\\nnumber even if you've met or exceeded your goal. \\\"Fancy\\\" will\\ndisplay a new message when you've met or exceeded your goal.\\n\\nKeep in mind that if both are active, \\\"Fancy\\\" will take priority.\", \"v0\": 0.0, \"name\": \"\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 1.0, \"xpan\": 34.0, \"b0\": \"OPTION 1: BASIC\\n---\\nPull down for more info:\\nUses a variable to display your current number of followers within\\na text source. You're free to modify the text however you want, just\\nmake sure the variable is inserted correctly!\", \"v0\": 3.0 }, { \"b1\": \"followStatus\", \"cmd\": 178.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\" }, { \"b1\": \"3000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"followStatus\" }, { \"b1\": \"Follower Goal: \\/$followStatus$\\/ \\/ XYZ\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Followers\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"OPTION 2: FANCY\\n---\\nPull down for more info:\\nUses a variable to display your current number of followers within\\na text source with the addition that, once you hit your target (the\\nnumber value in the If Statement command), the text will change instead\\nof continuing to display the goal. Just like with Basic, you're free to\\nchange this text however you like - just make sure the variable is inserted\\ncorrectly.\", \"v0\": 5.0 }, { \"b1\": \"followStatus\", \"cmd\": 178.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\" }, { \"b1\": \"3000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"followStatus\" }, { \"b53\": \"\", \"b5\": \"\", \"b13\": \"==\", \"v14\": 0.0, \"b36\": \"\", \"b38\": \"\", \"v10\": 0.0, \"b32\": \"\", \"b19\": \"==\", \"b57\": \"\", \"b59\": \"\", \"b17\": \"\", \"b1\": \">=\", \"v18\": 0.0, \"v16\": 0.0, \"b34\": \"==\", \"b7\": \"==\", \"b11\": \"\", \"b9\": \"\", \"b51\": \"\", \"b15\": \"\", \"b3\": \"\", \"b55\": \"==\", \"v12\": 0.0, \"cmd\": 7.0, \"b30\": \"\", \"b43\": \"==\", \"v21\": 0.0, \"v1\": 1.0, \"b26\": \"\", \"b28\": \"==\", \"obsid\": \"Main\", \"b22\": \"==\", \"pos\": 8.0, \"v5\": 0.0, \"b47\": \"\", \"b49\": \"==\", \"v3\": 0.0, \"vis\": 1.0, \"b24\": \"\", \"ms\": 20.0, \"b41\": \"\", \"sel\": 0.0, \"b45\": \"\", \"v9\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b20\": \"\", \"v7\": 0.0, \"b33\": \"\", \"v11\": 0.0, \"b16\": \"==\", \"b0\": \"followStatus\", \"b58\": \"==\", \"b56\": \"\", \"b18\": \"\", \"b4\": \"==\", \"b12\": \"\", \"b52\": \"==\", \"b39\": \"\", \"b37\": \"==\", \"v15\": 0.0, \"b54\": \"\", \"b14\": \"\", \"b2\": \"9001\", \"b31\": \"==\", \"v13\": 0.0, \"b35\": \"\", \"v17\": 0.0, \"v19\": 0.0, \"b50\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"==\", \"b23\": \"\", \"v4\": 0.0, \"b48\": \"\", \"b46\": \"==\", \"v20\": 0.0, \"b42\": \"\", \"b29\": \"\", \"v0\": 1.0, \"b27\": \"\", \"b44\": \"\", \"b21\": \"\", \"v6\": 0.0, \"v8\": 0.0, \"v2\": 1.0, \"b25\": \"==\", \"b40\": \"==\", \"v22\": 0.0 }, { \"b1\": \"Follower Goal Achieved!\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Followers\" }, { \"b1\": \"Follower Goal: \\/$followStatus$\\/ \\/ XYZ\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Followers\" } ], \"press_type\": 0.0, \"x\": 0.1666666666666666574148081281237, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"group_id\": \"\", \"type\": \"SAMMI Startup\", \"button_id\": \"ID439\", \"trg\": 10.0 }, { \"group_id\": \"\", \"button_id\": \"ID439\", \"trg\": 6.0 } ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666668517038374375261, \"button_id\": \"ID439\", \"button_duration\": 20.0, \"y\": 0.1666666666666666574148081281237, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 81.0, \"stretch\": 0.0 }, { \"color\": 10764644.0, \"persistent\": 1.0, \"text\": \"Twitch\\nSubscriber Goal\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 209.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nRuns a Twitch data pull when you start SAMMI as well as when a\\nnew subscriber event happens to update a text source that keeps\\ntrack of your subscriber goal.\\n\\nThere are two options available: \\\"Basic\\\" will display the current\\nnumber even if you've met or exceeded your goal. \\\"Fancy\\\" will\\ndisplay a new message when you've met or exceeded your goal.\\n\\nKeep in mind that if both are active, \\\"Fancy\\\" will take priority.\", \"v0\": 0.0, \"name\": \"\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 1.0, \"xpan\": 34.0, \"b0\": \"OPTION 1: BASIC\\n---\\nPull down for more info:\\nUses a variable to display your current number of followers within\\na text source. You're free to modify the text however you want, just\\nmake sure the variable is inserted correctly!\", \"v0\": 3.0 }, { \"b1\": \"subStatus\", \"cmd\": 310.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\" }, { \"b1\": \"3000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subStatus\" }, { \"b1\": \"Subscriber Goal: \\/$subStatus$\\/ \\/ XYZ\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Subscribers\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 0.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 32.0, \"b0\": \"OPTION 2: FANCY\\n---\\nPull down for more info:\\nUses a variable to display your current number of followers within\\na text source with the addition that, once you hit your target (the\\nnumber value in the If Statement command), the text will change instead\\nof continuing to display the goal. Just like with Basic, you're free to\\nchange this text however you like - just make sure the variable is inserted\\ncorrectly.\", \"v0\": 5.0 }, { \"b1\": \"subStatus\", \"cmd\": 177.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\" }, { \"b1\": \"3000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"subStatus\" }, { \"b53\": \"\", \"b5\": \"\", \"b13\": \"==\", \"v14\": 0.0, \"b36\": \"\", \"b38\": \"\", \"v10\": 0.0, \"b32\": \"\", \"b19\": \"==\", \"b57\": \"\", \"b59\": \"\", \"b17\": \"\", \"b1\": \">=\", \"v18\": 0.0, \"v16\": 0.0, \"b34\": \"==\", \"b7\": \"==\", \"b11\": \"\", \"b9\": \"\", \"b51\": \"\", \"b15\": \"\", \"b3\": \"\", \"b55\": \"==\", \"v12\": 0.0, \"cmd\": 7.0, \"b30\": \"\", \"b43\": \"==\", \"v21\": 0.0, \"v1\": 1.0, \"b26\": \"\", \"b28\": \"==\", \"obsid\": \"Main\", \"b22\": \"==\", \"pos\": 8.0, \"v5\": 0.0, \"b47\": \"\", \"b49\": \"==\", \"v3\": 0.0, \"vis\": 1.0, \"b24\": \"\", \"ms\": 20.0, \"b41\": \"\", \"sel\": 0.0, \"b45\": \"\", \"v9\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b20\": \"\", \"v7\": 0.0, \"b33\": \"\", \"v11\": 0.0, \"b16\": \"==\", \"b0\": \"subStatus\", \"b58\": \"==\", \"b56\": \"\", \"b18\": \"\", \"b4\": \"==\", \"b12\": \"\", \"b52\": \"==\", \"b39\": \"\", \"b37\": \"==\", \"v15\": 0.0, \"b54\": \"\", \"b14\": \"\", \"b2\": \"9001\", \"b31\": \"==\", \"v13\": 0.0, \"b35\": \"\", \"v17\": 0.0, \"v19\": 0.0, \"b50\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"==\", \"b23\": \"\", \"v4\": 0.0, \"b48\": \"\", \"b46\": \"==\", \"v20\": 0.0, \"b42\": \"\", \"b29\": \"\", \"v0\": 1.0, \"b27\": \"\", \"b44\": \"\", \"b21\": \"\", \"v6\": 0.0, \"v8\": 0.0, \"v2\": 1.0, \"b25\": \"==\", \"b40\": \"==\", \"v22\": 0.0 }, { \"b1\": \"Subscriber Goal Achieved!\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Subscribers\" }, { \"b1\": \"Subscriber Goal: \\/$followStatus$\\/ \\/ XYZ\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 1.0, \"ms\": 20.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Tracker \\/\\/ Subscribers\" } ], \"press_type\": 0.0, \"x\": 0.1666666666666666574148081281237, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"group_id\": \"\", \"type\": \"SAMMI Startup\", \"button_id\": \"ID357\", \"trg\": 10.0 }, { \"anonsubgift\": 1.0, \"tier2\": 1.0, \"subgift\": 1.0, \"normalsub\": 1.0, \"monthmax\": 2.0, \"prime\": 1.0, \"group_id\": \"\", \"allowcommunity\": 1.0, \"tier3\": 1.0, \"tier1\": 1.0, \"button_id\": \"ID357\", \"trg\": 1.0, \"monthrange\": 0.0, \"monthmin\": 1.0 } ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666668517038374375261, \"button_id\": \"ID357\", \"button_duration\": 20.0, \"y\": 0.25, \"switch_deck\": \"\", \"height\": 0.083333333333333342585191871876305, \"release_list\": [ ], \"functions\": 81.0, \"stretch\": 0.0 }, { \"color\": 16747008.0, \"persistent\": 1.0, \"text\": \"Raid Alert w\\/\\nGame Title + Shoutout\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 233.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nThis follows the same principles outlined in the Follow Alert button.\\nI'd recommend taking a look at that first before getting into setting\\none up for Subscribers, but I'm not a cop. You do you.\\n\\nMake sure you've unzipped the apropriate files to your SAMMI installation\\nfolder and run the \\\"Initial File Creation\\\" button, or SAMMI will give you\\na bunch of errors.\\n\\nAdditional settings can be set by right clicking on the button and going\\nto Edit Triggers, including setting minimum and maximum number of raiders.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"GET RAID INFO\\n---\\nPull down for more info:\\nPulls various bits of data related to the raid and saves\\nthem as variables. \\nIf you want to set this yourself, make sure you use the drop-down\\nto select Twitch Raid > Display Name and Twitch Raid > Amount.\\nSimply typing in \\\"display_name\\\" and \\\"amount\\\" won't work, as SAMMI\\nwon't know what it's supposed to pull.\", \"v0\": 4.0 }, { \"b1\": \"display_name\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"raidName\" }, { \"b1\": \"amount\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"raidAmount\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"raidName\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"raidAmount\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"GET GAME INFO\\n---\\nPull down for more info:\\nUses the raidName variable from the Trigger Pull Data command in the\\nblock above to get current stream info from the channel. This is stored\\nin an object that we'll be using in a moment.\\n(There's quite a bit of info that's pulled and stored in an object,\\nso if you want to dig in to it, try changing this to any channel you want,\\ngo to the Variable Window, and click the arrow next to raidName.)\\n\\nUses the most recent category set for the raider (i.e. game name, Just\\nChatting, etc.)\", \"v0\": 2.0 }, { \"b1\": \"raidInfo\", \"cmd\": 312.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 4000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$raidName$\\/\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 4000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"raidInfo\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 33.0, \"b0\": \"ALERT ACTIONS\\n---\\nPull down for more info:\\nA simple image example that will play out in the SFTL Test Lab is\\nincluded below. This is SAMMI - if you can dream it up, you can make it\\nhappen, so don't be afraid to experiment! (Just make a backup of what\\nyou're working on first.)\", \"v0\": 15.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 10.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"UPDATE TEXT SOURCES\\n---\\nPull down for more info:\\nLine 1 will display a pre-set message, while Line 2 uses the\\n\\\"subName\\\" variable that was pulled earlier to display the\\nname that was pulled.\", \"v0\": 3.0 }, { \"b1\": \"\\/$raidName$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 1\" }, { \"b1\": \"raided with \\/$raidAmount$\\/\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 2\" }, { \"b1\": \"viewers!\", \"cmd\": 35.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Alert \\/\\/ Line 3\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"SLIDE IN \\/ OUT\\n---\\nPull down for more info:\\nA set of actions that will have an image slide in from the left of\\nthe screen followed by text, stay on screen for a few seconds, then\\nslide out.\\n\\n(As an additional note, for your own alerts, you'll need to go to\\nthe Transform tool and make some additional adjustments to the\\nBounding Box Type, Alignment in Bounding Box, and Bounding Box Size.\\nLonger names will bleed over into the visible area if you leave the\\nsettings as-is, so experiment to see what works best for your layout.\\n\\nI tried to do this as part of the \\\"Initialize SFTL Test Lab\\\" button, I\\nreally, truly did, but JSON is NOT my passion in life and OBS absolutely\\nrefused to import the settings I wanted for sources.\\nSame goes for fading in and out - you'll need to add that yourself via\\n\\\"Motion: Alpha Filter\\\" [in OBS v28 and above] or \\\"Motion: Filter Settings\\\"\\n[in OBS v27 and below]. Despite my best efforts, I wasn't able to import\\nthis via JSON.)\", \"v0\": 8.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 15.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-300\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"240\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"240\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 16.0, \"vis\": 1.0, \"ms\": 360.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 17.0, \"vis\": 1.0, \"ms\": 660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 1.0 }, { \"b5\": \"360\", \"b1\": \"Alert \\/\\/ Line 3\", \"b3\": \"360\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 18.0, \"vis\": 1.0, \"ms\": 960.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"0\", \"b2\": \"-450\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"360\", \"b1\": \"Alert \\/\\/ Line 3\", \"b3\": \"360\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 19.0, \"vis\": 1.0, \"ms\": 4960.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"300\", \"b1\": \"Alert \\/\\/ Line 2\", \"b3\": \"300\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 20.0, \"vis\": 1.0, \"ms\": 5260.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"240\", \"b1\": \"Alert \\/\\/ Line 1\", \"b3\": \"240\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 21.0, \"vis\": 1.0, \"ms\": 5560.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-450\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"b5\": \"0\", \"b1\": \"Alert \\/\\/ Image\", \"b3\": \"0\", \"cmd\": 23.0, \"obsid\": \"Main\", \"pos\": 22.0, \"vis\": 1.0, \"ms\": 5860.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"SFTL Test Lab\", \"b4\": \"-300\", \"b2\": \"0\", \"b6\": \"500\", \"v0\": 2.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 23.0, \"vis\": 0.0, \"ms\": 4660.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"SOUND EFFECT\\n---\\nPull down for more info:\\nPlays a sound effect. SAMMI requires that sounds be in .ogg format.\\nYou can use a free tool like Audacity or ocenaudio to convert most\\nfiles to .ogg without much fuss.\", \"v0\": 1.0 }, { \"b1\": \"\", \"cmd\": 2.0, \"obsid\": \"Main\", \"pos\": 24.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$global.main_directory_slash$\\/sftltestlab\\/audio\\/tada.ogg\", \"v0\": 0.64893617021276595036027856622241 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 25.0, \"vis\": 1.0, \"ms\": 7250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 36.0, \"b0\": \"CHAT MESSAGE (OPTIONAL)\\n---\\nPull down for more info:\\nJust what it says on the tin, sends a message to chat.\\n\\/$raidName$\\/ can be used to auto-fill the name of the channel that raided.\\n\\/$raidAmount$\\/ can be used to auto-fill the amount of raiders that came with them.\\n\\/$raidInfo.game_name$\\/ can be used to auto-fill the category they were streaming under.\\n\\nA Switch \\/ Case Statement can also be used to return different types of messages based\\non the category - for example, if you want a custom message for \\\"Just Chatting\\\", you\\ncan add a Case Statement for \\\"Just Chatting\\\" (no quotes).\\n\\nThe \\\"undefined\\\" Case Statement will provide a message without the title in case SAMMI\\ncan't pull a title, while \\\"default\\\" will run commands that don't match any other Case\\nStatements.\", \"v0\": 5.0, \"comment_color\": 10830180.0 }, { \"cmd\": 24.0, \"obsid\": \"Main\", \"pos\": 26.0, \"v3\": { \"default\": 29.0, \"undefined\": 27.0 }, \"vis\": 1.0, \"ms\": 4000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"raidInfo.game_name\", \"v0\": 4.0 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 27.0, \"vis\": 0.0, \"ms\": 7250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"undefined\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"b1\": \"YOUR CHANNEL HERE\", \"cmd\": 148.0, \"obsid\": \"Main\", \"pos\": 28.0, \"vis\": 1.0, \"ms\": 4000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$raidName$\\/ raided with \\/$raidAmount$\\/ viewers!\" }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 29.0, \"vis\": 0.0, \"ms\": 7250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"default\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 1.0, \"v2\": 1.0 }, { \"b1\": \"YOUR CHANNEL HERE\", \"cmd\": 148.0, \"obsid\": \"Main\", \"pos\": 30.0, \"vis\": 1.0, \"ms\": 4000.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"\\/$raidName$\\/ raided with \\/$raidAmount$\\/ viewers, and was last seen playing \\/$raidInfo.game_name$\\/!\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 31.0, \"vis\": 1.0, \"ms\": 4000.0, \"sel\": 0.0, \"dis\": 1.0, \"xpan\": 34.0, \"b0\": \"TWITCH SHOUTOUT (OPTIONAL)\\n---\\nPull down for more info:\\nExactly what you'd think - uses Twitch's \\\"Shoutout\\\" feature to\\nautomatically shout out the raider based on the raidName variable\\nwe pulled earlier. Make sure to include your channel name in the\\nfist box!\\n\", \"v0\": 1.0 }, { \"b1\": \"\\/$raidName$\\/\", \"cmd\": 295.0, \"obsid\": \"Main\", \"pos\": 32.0, \"vis\": 1.0, \"ms\": 4200.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL NAME HERE\" } ], \"press_type\": 0.0, \"x\": 0.0, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"minimum\": 1.0, \"group_id\": \"\", \"button_id\": \"ID111\", \"trg\": 4.0, \"maximum\": 1000000000.0 } ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.1666666666666666574148081281237, \"button_id\": \"ID111\", \"button_duration\": 7250.0, \"y\": 0.58333333333333337034076748750522, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 83.0, \"stretch\": 0.0 }, { \"color\": 12632256.0, \"persistent\": 1.0, \"text\": \"Random Video\\nRoller\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ ], \"press_type\": 0.0, \"x\": 0.5, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"ID113\", \"button_duration\": 0.0, \"y\": 0.41666666666666668517038374375261, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 64.0, \"stretch\": 0.0 }, { \"color\": 5987163.0, \"persistent\": 1.0, \"text\": \" Video Roller \", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 208.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nWorks in tandem with the Video Loop button to run a series of local\\nvideos without repeating the same video twice by using a String Array.\\n\\nKeep in mind that this isn't quite an \\\"out of the box\\\" solution, it's\\nmore building blocks for your own setup. You'll need to adjust your\\nsources and how videos start and stop.\\n\\nDesigned with AFK screens in mind, but as always, the possibilities are\\nendless for how you can use this!\", \"v0\": 0.0, \"name\": \"\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 32.0, \"b0\": \"ARRAYS \\/ PARSING\\n---\\nPull down for more info:\\nClears the existing array in case it already exists, then creates a new,\\nclean array to pull from.\", \"v0\": 2.0 }, { \"cmd\": 234.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftlVideoRoll\" }, { \"cmd\": 17.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftlVideoRoll\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 206.0, \"b0\": \"PARSE ARRAY \\/ OBJECT\\n---\\nFor every video you have, incriment the string by 1.\\n\\nThis will be necessary for the Video Loop button to work properly. If\\nyou have a lot of videos, this may take some time to set up since you\\nneed to type each number in manually, but it allows you to have literally\\nhundreds of videos if you want.\\n\\n(If you know how to use JSON you can use that, too. I don't know how\\nto, though, so this example is a String Array.)\", \"v0\": 1.0, \"name\": \"\" }, { \"b1\": \"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\", \"cmd\": 168.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftlVideoRoll\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"ARRAY SHUFFLE \\/ TRIGGER BUTTON\\n---\\nPull down for more info:\\nShuffles the array that we created earlier, then presses a button that will\\nstart the video loop.\", \"v0\": 2.0 }, { \"cmd\": 102.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftlVideoRoll\" }, { \"b1\": \"0\", \"cmd\": 132.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftlVideoLoop\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 33.0, \"b0\": \"NOW PLAYING CHECK\\n---\\nPull down for more info:\\nChecks to see if the sftlVideoPlay variable has been created in the\\nsftlVideoLoop button to determine if a video should play or not.\", \"v0\": 5.0 }, { \"cmd\": 24.0, \"obsid\": \"Main\", \"pos\": 10.0, \"v3\": { \"default\": 11.0, \"undefined\": 14.0 }, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftlVideoLoop\", \"v0\": 4.0 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 11.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"default\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 2.0, \"v2\": 1.0 }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 12.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftlVideoLoop.sftlVideoPlay\" }, { \"b1\": \"0\", \"cmd\": 132.0, \"obsid\": \"Main\", \"pos\": 13.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftlVideoStartup\", \"v0\": 0.0 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 14.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"undefined\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 0.0, \"v2\": 1.0 } ], \"press_type\": 0.0, \"x\": 0.5, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"sftlVideoStartup\", \"button_duration\": 0.0, \"y\": 0.5, \"switch_deck\": \"\", \"height\": 0.083333333333333370340767487505218, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 5987163.0, \"persistent\": 1.0, \"text\": \" Video Loop \", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 271.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nWorks in tandem with the Video Roller button to play a randomized\\nseries of videos without playing the same video twice in the same\\nsession.\\n\\nKeep in mind that this isn't quite an \\\"out of the box\\\" solution, it's\\nmore building blocks for your own setup. You'll need to adjust your\\nsources and how videos start and stop. An OBS \\\"MediaEnded\\\" trigger has\\nbeen set for this button by default, but you may have a different trigger\\ntype that works better for your setup.\\n\\nDesigned with AFK screens in mind, but as always, the possibilities are\\nendless for how you can use this!\", \"v0\": 0.0, \"name\": \"\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 165.0, \"b0\": \"VIDEO LOOP\\n---\\nUses a Switch Statement and Case Statements to determine if a video\\nis already playing via variables set in the sftlVideoStartup button.\\n\\nMake sure you're setting the correct source under \\\"Source Change\\nSettings\\\". File names should also be named video1, video2, video3,\\nand so on to make sure the variable pulled from sftlVideoStartup\\nworks correctly.\", \"v0\": 7.0, \"name\": \"\" }, { \"cmd\": 24.0, \"obsid\": \"Main\", \"pos\": 2.0, \"v3\": { \"default\": 8.0, \"on\": 3.0, \"null\": 8.0, \"undefined\": 8.0, \"off\": 8.0 }, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"toggle\", \"v0\": 6.0 }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b16\": \"\", \"b0\": \"on\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 4.0, \"v2\": 1.0 }, { \"b1\": \"top\", \"cmd\": 98.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 500.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftlVideoStartup.sftlVideoRoll\", \"b2\": \"sftlVideoPlay\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"sftlVideoPlay\" }, { \"b1\": \"{\\\"local_file\\\":\\\"C:\\/file\\/path\\/here\\/video\\/$afkVideoPlay$\\/.mp4\\\"}\", \"cmd\": 34.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"APNG \\/\\/ Bun-E03 \\/\\/ Standing By \\/\\/ Bouncy\" }, { \"cmd\": 142.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Now playing: Video #\\/$sftlVideoPlay$\\/\" }, { \"b5\": \"\", \"b13\": \"\", \"b19\": \"\", \"b17\": \"\", \"b1\": \"default\", \"b7\": \"\", \"b11\": \"\", \"b9\": \"\", \"b15\": \"\", \"b3\": \"undefined\", \"cmd\": 26.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 75.0, \"b16\": \"\", \"b0\": \"off\", \"b18\": \"\", \"b4\": \"\", \"b12\": \"\", \"b14\": \"\", \"b2\": \"null\", \"b8\": \"\", \"b6\": \"\", \"b10\": \"\", \"v0\": 0.0, \"v2\": 4.0 } ], \"press_type\": 0.0, \"x\": 0.5, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"turntorealm\": 0.0, \"updatetype\": \"MediaEnded\", \"obs\": \"4.9 Compat\", \"group_id\": \"\", \"button_id\": \"sftlVideoLoop\", \"trg\": 9.0 } ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666662965923251249478, \"button_id\": \"sftlVideoLoop\", \"button_duration\": 500.0, \"y\": 0.58333333333333337034076748750522, \"switch_deck\": \"\", \"height\": 0.083333333333333259318465024989564, \"release_list\": [ ], \"functions\": 81.0, \"stretch\": 0.0 }, { \"color\": 12632256.0, \"persistent\": 1.0, \"text\": \"Bot Commands\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ ], \"press_type\": 0.0, \"x\": 0.1666666666666666574148081281237, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.1666666666666666574148081281237, \"button_id\": \"ID489\", \"button_duration\": 0.0, \"y\": 0.41666666666666668517038374375261, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 64.0, \"stretch\": 0.0 }, { \"color\": 14095312.0, \"persistent\": 1.0, \"text\": \"!lurk\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 228.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nA basic chat command that responds to \\\"!lurk\\\" in chat with\\na chat message from whichever account is set as \\\"Join chat\\nunder this account\\\" in SAMMI.\\n\\nRelies on a Twitch Chat trigger in SAMMI to fire, which has\\nalready been set for this button.\\n\\nThink of this as a basic building block for creating a second\\naccount as a \\\"bot\\\" that can replace services like StreamLabs,\\nNightbot, etc.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"GET CHATTER INFO\\n---\\nPull down for more info:\\nPulls the name of the latest chatter and saves it as a variable.\\nIf you want to set this yourself, make sure you use the drop-down\\nto select Twitch Chat > Display Name. Simply typing in \\\"display_name\\\"\\nwon't work, as SAMMI won't know what it's supposed to pull.\", \"v0\": 1.0 }, { \"b1\": \"display_name\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chatName\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"SEND CHAT MESSAGE\\n---\\nPull down for more info:\\nJust what it says on the tin. Make sure you're using the variable from earlier.\\nIncludes \\\"Wait Until Variable Exists\\\" to account for any delays between the data\\npull and sending the message to chat.\", \"v0\": 2.0, \"name\": \"\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chatName\" }, { \"b1\": \"\", \"cmd\": 148.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Enjoy lurking, \\/$chatName$\\/!\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"OVERTIME (Optional)\\n---\\nPull down for more info:\\nAdds an artificial delay to the button so it can't be triggered immediately.\\nOvertime starts when the button is triggered, NOT when the delay is set.\\n30000 ms = 30 seconds.\\n\", \"v0\": 1.0, \"name\": \"\" }, { \"cmd\": 137.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"30000\" } ], \"press_type\": 0.0, \"x\": 0.1666666666666666574148081281237, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"sub\": 0.0, \"user_name\": \"\", \"case_sensitive\": 0.0, \"founder\": 0.0, \"message\": \"!lurk\", \"moderator\": 0.0, \"group_id\": \"\", \"vip\": 0.0, \"button_id\": \"ID491\", \"broadcaster\": 0.0, \"trg\": 0.0, \"allow_empty_wildcard\": 0.0 } ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.1666666666666666574148081281237, \"button_id\": \"ID491\", \"button_duration\": 30000.0, \"y\": 0.5, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 81.0, \"stretch\": 0.0 }, { \"color\": 14095312.0, \"persistent\": 1.0, \"text\": \"!game\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 379.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nA basic chat command that responds to \\\"!game\\\" in chat with\\na chat message with the current category that you're streaming\\nunder. The message will be sent from whichever account is set as\\n\\\"Join chat under this account\\\" in SAMMI.\\n\\nOnly works when your channel is live, since it will fail to\\npull channel category info if your channel is offline.\\n\\nIf you're familiar with Case and Switch Statements, you can\\ncreate unique messages for specific categories, too.\\n\\nRelies on a Twitch Chat trigger in SAMMI to fire, which has\\nalready been set for this button.\\n\\nThink of this as a basic building block for creating a second\\naccount as a \\\"bot\\\" that can replace services like StreamLabs,\\nNightbot, etc.\", \"v0\": 0.0 }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"GET CHATTER INFO (Optional)\\n---\\nPull down for more info:\\nPulls the name of the latest chatter and saves it as a variable.\\nIf you want to set this yourself, make sure you use the drop-down\\nto select Twitch Chat > Display Name. Simply typing in \\\"display_name\\\"\\nwon't work, as SAMMI won't know what it's supposed to pull.\", \"v0\": 1.0 }, { \"b1\": \"display_name\", \"cmd\": 66.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chatName\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"GET GAME INFO\\n---\\nPull down for more info:\\nUses a Twitch: Get Channel Info command to pull the current category that\\nyour channel is streaming under. \", \"v0\": 1.0, \"name\": \"\" }, { \"b1\": \"twitchInfo\", \"cmd\": 312.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"SEND CHAT MESSAGE\\n---\\nPull down for more info:\\nJust what it says on the tin. Make sure you're using the variable from earlier.\\nIncludes \\\"Wait Until Variable Exists\\\" to account for any delays between the data\\npull and sending the message to chat.\", \"v0\": 2.0, \"name\": \"\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 6.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"chatName\" }, { \"b1\": \"YOUR CHANNEL HERE\", \"cmd\": 148.0, \"obsid\": \"Main\", \"pos\": 7.0, \"vis\": 1.0, \"ms\": 250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"The current game is \\/$twitchInfo.game_name$\\/!\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 8.0, \"vis\": 1.0, \"ms\": 250.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"OVERTIME (Optional)\\n---\\nPull down for more info:\\nAdds an artificial delay to the button so it can't be triggered immediately.\\nOvertime starts when the button is triggered, NOT when the delay is set.\\n30000 ms = 30 seconds.\\n\", \"v0\": 1.0, \"name\": \"\" }, { \"cmd\": 137.0, \"obsid\": \"Main\", \"pos\": 9.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"30000\" } ], \"press_type\": 0.0, \"x\": 0.1666666666666666574148081281237, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"sub\": 0.0, \"user_name\": \"\", \"case_sensitive\": 0.0, \"founder\": 0.0, \"message\": \"!game\", \"moderator\": 0.0, \"group_id\": \"\", \"vip\": 0.0, \"button_id\": \"ID492\", \"broadcaster\": 0.0, \"trg\": 0.0, \"allow_empty_wildcard\": 0.0 } ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.1666666666666666574148081281237, \"button_id\": \"ID492\", \"button_duration\": 30000.0, \"y\": 0.58333333333333337034076748750522, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 81.0, \"stretch\": 0.0 }, { \"color\": 14095312.0, \"persistent\": 1.0, \"text\": \"15-minute\\nMessage\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 303.0, \"b0\": \"SETUP \\/ ABOUT THIS BUTTON\\n---\\nYou'll need to add your own trigger for this to work:\\n\\nOBS Trigger > OBSwsv4.9 > Stream Started\\n(Or a different trigger of your choice)\\n\\nSends a message to chat on a loop every 15 minutes after\\na stream has started, and will continue to do so until\\nSAMMI has shut down.\\n\\nSAMMI measures time in milliseconds, so you can fine-tune\\nhow often the message is sent to chat, or, if you want\\nmultiple messages, put them on different timers. It's\\nup to you!\", \"v0\": 0.0 }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 35.0, \"b0\": \"TIME BEFORE FIRST MESSAGE IS SENT\\n---\\nPull down for more info:\\nUses a \\\"Wait for Timeout\\\" command before sending the first chat message\\n(in this case, 60000 ms = 1 minute). Useful if you have a \\\"now live\\\" message\\nfor chat but don't want messages to all overlap each other.\", \"v0\": 1.0, \"name\": \"\" }, { \"cmd\": 190.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"60000\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 167.0, \"b0\": \"SET REPEAT INTERVAL AND SEND CHAT MESSAGE\\n---\\nPull down for more info:\\nUses the \\\"Re-enable\\\" block and \\\"Twitch: Send Chat Message\\\" command\\nto send a message to the stream every 900000 ms \\/ 15 minutes.\\n\\nKeep in mind that SAMMI uses milliseconds (ms), so make sure the Repeat\\nInterval is properly converted to ms so that your messages are going out\\nas intended.\", \"v0\": 2.0, \"name\": \"\" }, { \"b1\": \"-1\", \"cmd\": 8.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"900000\", \"v0\": 1.0 }, { \"b1\": \"YOUR CHANNEL HERE\", \"cmd\": 148.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Hope you're enjoying the show! Here's where you can donate if you like what I do: [link]\" } ], \"press_type\": 0.0, \"x\": 0.1666666666666666574148081281237, \"border\": 2.0, \"image\": \"\", \"triggers\": [ ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.1666666666666666574148081281237, \"button_id\": \"ID6\", \"button_duration\": 0.0, \"y\": 0.66666666666666662965923251249478, \"switch_deck\": \"\", \"height\": 0.083333333333333328707404064061848, \"release_list\": [ ], \"functions\": 65.0, \"stretch\": 0.0 }, { \"color\": 5385234.0, \"persistent\": 1.0, \"text\": \"Set Twitch Category\\nand Title\", \"release_duration\": 0.0, \"queueable\": 0.0, \"command_list\": [ { \"cmd\": 4.0, \"obsid\": \"Main\", \"pos\": 0.0, \"vis\": 1.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 250.0, \"b0\": \"SET CHANNEL CATEGORY AND TITLE\\n---\\nCreates a pop-up in SAMMI that prompts you to enter the name of the\\ncategory you want to stream under. SAMMI will then auto-fill the stream\\ncategory and stream title for you.\\n\\nIf you have categories you regularly stream under, you can also skip the\\ntext entry and create a button where SAMMI sets this automatically via\\nthe \\\"Twitch: Modify Channel Info\\\" command.\\n\\nKeep in mind that the Stream Information tab in OBS will need to be refreshed\\nafter updating stream info via SAMMI. The Twitch Dashboard and your page on\\nTwitch will typically update automatically after a few seconds.\", \"v0\": 0.0, \"name\": \"\" }, { \"cmd\": 6.0, \"obsid\": \"Main\", \"pos\": 1.0, \"vis\": 0.0, \"ms\": 0.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 33.0, \"b0\": \"TEXT ENTRY AND CATEGORY POP-UP\\n---\\nPull down for more info:\\nCreates a pop-up in SAMMI that prompts you to enter text.\\nThis text will be used for both the Category and Title section\\nbelow (unless you remove one of them).\", \"v0\": 2.0, \"name\": \"\" }, { \"b1\": \"\", \"cmd\": 214.0, \"obsid\": \"Main\", \"pos\": 2.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"Enter category:\", \"b2\": \"category\" }, { \"b1\": \"1000\", \"cmd\": 153.0, \"obsid\": \"Main\", \"pos\": 3.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"category\" }, { \"cmd\": 5.0, \"obsid\": \"Main\", \"pos\": 4.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 34.0, \"b0\": \"MODIFY CHANNEL INFO\\n---\\nPull down for more info:\\nSets the current category you're streaming under as well as\\nthe stream title based on the pop-up from earlier. Tags can\\nalso be set as a stringified array, which is particularly useful\\nif you have a specific set of tags you always use and want to revert\\nto each time you update your stream info.\\n\\nMake sure tags are following the correct format:\\n[\\\"Tag1\\\", \\\"Tag2,\\\" \\\"Tag3\\\"]\\n\\nYou can have more than 3 tags, but each should be enclosed in quotes,\\nfollowed by a comma (except for the final one), and the whole thing\\nshould be wrapped in [brackets].\\n\\nIf you don't want one of these items (Category, Title, Tags) to be\\nupdated, simply leave it blank.\", \"v0\": 1.0, \"name\": \"\" }, { \"b1\": \"\\/$category$\\/\", \"b3\": \"\\/$category$\\/\", \"cmd\": 293.0, \"obsid\": \"Main\", \"pos\": 5.0, \"vis\": 1.0, \"ms\": 10.0, \"sel\": 0.0, \"dis\": 0.0, \"xpan\": 0.0, \"b0\": \"YOUR CHANNEL HERE\", \"b4\": \"[\\\"Tag1\\\", \\\"Tag2\\\", \\\"Tag3\\\"]\", \"b2\": \"English\" } ], \"press_type\": 0.0, \"x\": 0.33333333333333331482961625624739, \"border\": 2.0, \"image\": \"\", \"triggers\": [ { \"message\": \"Pepper set channel to art\", \"group_id\": \"\", \"button_id\": \"ID490\", \"trg\": 29.0, \"allow_empty_wildcard\": 0.0 } ], \"group_id\": \"\", \"overlappable\": 0.0, \"init_variable\": \"\", \"deck\": 16.0, \"width\": 0.16666666666666668517038374375261, \"button_id\": \"ID490\", \"button_duration\": 10.0, \"y\": 0.5, \"switch_deck\": \"\", \"height\": 0.083333333333333370340767487505218, \"release_list\": [ ], \"functions\": 81.0, \"stretch\": 0.0 } ], \"deck_name\": \"SFTL Stream Deck v2.4a\", \"grid_x\": 12.0, \"stretch\": 0.0 }",
"unique_id": "20230403200051570050702",
"deck_verification_code": "e2eb31ab7cac2551a8f0835e482df8435a460336",
"include_image": {}
}