Subathon v2.3.2 (latest)
Installation
Pre-requisites
- OBS Studio
- Streamer.bot
- Subathon import code
- (optional) Source Copy plugin - for easy OBS Scene import
Importing the code
-
Download the .sb import code by purchasing through https://shop.rondhi.com
-
In Streamer.bot, open the
Import Dialog
-
Open the folder where you saved the import code then drag-and-drop the .sb file into the
Import String
box -
Click
Import
-
Upon importing, Streamer.bot will ask if you would like to auto-run an action. I designed the import to auto-run on import in order to populate the default settings. If you opt-out of auto-running the action, follow one of these two options:
- Run the test trigger for the action
Subathon 0. Code
- In the action
Subathon 0. Code
, right-click the Execute C# Code sub-action > Execute C# Code > Compile
- Run the test trigger for the action
-
Commands are disabled by default. Enable the command group
Subathon Timer
-
In the Streamer.bot window, open the Variables window so you can proceed with configuration
Streamer.bot Configuration
Any of the Set Argument sub-actions or global variables that require a duration can use the following syntax:
d
for days, h
for hours, m
for minutes, s
for seconds
Examples: 5d4h3m
, 1h30m
, 5m
, 1h
Most of the configuration options for the timer will be done in the Global Variable window and can be updated in realtime. Open the global variable window, then type subathon
in the filter window
Countdown Timer Settings
Name | Description | Default | Notes |
---|---|---|---|
subathonName | The label of the type of Subathon timer you're running used in Chat messages | Subathon | If you name it Europathon , then the chat message when timer paused will read: The Europathon has been paused at 2 minutes and 35 seconds elapsed and 1 hour, 57 minutes, and 25 seconds remaining |
subathonInitialDuration | Set to how long you want to start your stream | 2h | 6h - Indicate a starting time of six hours |
subathonMaxDuration | Set to how long you want the limit of your subathon to be | 7d | 69d - Indicate a max cap of sixty-nine days |
Twitch Hype Train / Happy Hour Settings
Multiply time added while a Twitch Hype Train or a designated Happy Hour event is live
Name | Description | Default | Notes |
---|---|---|---|
subathonHypeTrainLevelUpIncrement | If using a Twitch Hype Train triggers and the linear multiplier type, user a number to increment the multiplier. It will increment each level up until you reach subathonHypeTrainMaxMultiplier | 0.2 | 0.5 - 0.5x multiplier |
subathonHypeTrainMaxMultiplier | This is the max value the multiplier can be incremented to. Used only for multipliers that increment based on Hype Train Level | 10 | 20 |
subathonHypeTrainMultiplier | Options: # - Use a number for a constant multiplier linear - Grows at constant rate, 0.1 per level exponential - Starts slow, then accelerates rapidly sigmoidal - Starts slow, accelerates, then levels off (faster growth than exponential) | linear | 2 |
subathonHypeTrainName | Customize the name of your Hype Train/Happy Hour | Twitch Hype Train | Happy Hour |
OBS Settings
Name | Description | Default |
---|---|---|
subathonObsConnection | Set to the zero-indexed connection number found in Stream Apps > OBS | 0 |
subathonScene | Set to the name of your nested ncene that will house the text source for the timer | [NS] Subathon |
subathonSource | Set to the name of your text source that will display the countdown timer | [TS] Subathon Time |
subathonDisplayDays | Set whether or not you want to display days in the OBS countdown timer. Example: True: 5.04:03:02 False: 124:03:02 | False |
subathonIndividualTimeUnits | Set whether or not you want to use individual time units as separate text sources. There will be separate sources for days, hours, minutes, seconds, and a pause/play symbol | False |
subathonSourceDays | Set to the name of your text source that displays the days left (depends on ~subathonDisplayDays~ is set to true ) | [TS] Subathon Time Days |
subathonSourceHours | Set to the name of your text source that displays the hours left | [TS] Subathon Time Hours |
subathonSourceMinutes | Set to the name of your text source that displays the minutes left | [TS] Subathon Time Minutes |
subathonSourceSeconds | Set to the name of your text source that displays the seconds left | [TS] Subathon Time Seconds |
subathonSourcePlayPause | Set to the name of your text source that displays the play/pause symbold | [TS] Subathon Time Play Pause |
Chat Message Settings
Name | Description | Default |
---|---|---|
subathonSendMessageTo | Set to platforms you wish to send chat messages to. Any combination of twitch, youtube, trovo, all separated by commas with no spaces | twitch |
subathonSendAllPlatforms | When sending messages, send to all platforms, or just the triggering platform (from a command) | True |
subathonSendAsBot | Set to true if you want to use your bot account to send messages. False, otherwise | True |
Add Time Configuration
Add Time configuration for monetary triggers
The Action Group Subathon Countdown Timer Add Time
will have actions you can configure for adding time to the timer for each individual trigger.
For any monetary triggers, you can configure %moneyDivide%
and %timeToAdd%
. The easiest way to think about it is: for each %moneyDivide%
, add %timeToAdd%
. Example: For each $2.50 tipped, add 60s. A $5 tip would add 120s, or two minutes.
Add Time configuration for Twitch Subscription triggers
Configure the following Set Argument sub-actions in the action 'Subathon Add Time Twitch Sub':
-
timeToAddTier1
-
timeToAddTier2
-
timeToAddTier3
Add Time configuration for YouTube Membership triggers
-
Run the Test Trigger for the action 'Subathon 0b. Set YouTube Membership Tiers'. It will give you several input popups where you can input your YouTube Membership Tier Level names.
Not all membership levels are required if you are not using all the YouTube membership tier levels. If you don't use a particular level, do not edit the input, then click OK or Cancel
-
Configure the following Set Argument sub-actions in the action 'Subathon Add Time YouTube Membership':
- timeToAddYouTubeLvl1
- timeToAddYouTubeLvl2
- timeToAddYouTubeLvl3
- timeToAddYouTubeLvl4
- timeToAddYouTubeLvl5
- timeToAddYouTubeLvl6
Trigger Type | Twitch Equivalent | Description |
---|---|---|
New Sponsor | Twitch Subscription | When someone becomes a member for the first time |
Membership Milestone | Twitch Resubscription | When someone shares their membership renewal |
Gift Membership Received | Twitch Gift Sub or Twitch Gift Bomb (with Ignore Gift Subs from Gift Bombs disabled) | If you enable this, disable Membership Gift so time doesn't get added twice. When someone receives a gift (can trigger multiple times if someone gifts multiple memberships) |
Membership Gift | Twitch Gift Bomb (with Ignore Gift Subs from Gift Bombs enabled) | If you enable this, disable Gift Membership Received so time doesn't get added twice. See note below as well if you use this trigger |
A note regarding YouTube Gift Memberships (thanks, Haunter):
Event Configuration
Event Name | Description |
---|---|
Subathon Event Cancelled | Triggers when cancelling the subathon using command !subathonCancel twice in a row |
Subathon Event Completed | Triggers when timer hits zero |
Subathon Event Paused | Triggers when the timer is paused |
Subathon Event Resumed | Triggers when the timer is resumed |
Subathon Event Started | Triggers when timer is started for the first time |
Subathon Event Time Added | Triggers when time is added |
Subathon Event Time Added Limit Reached | Triggers when the limit is reached for adding time |
You can configure most messages sent by the subathon timer via Set Arguments in the according actions. You will be able to use the following arguments to customize how much time has been added/remaining/elapsed
- Most actions will be able to have a customized chat message
- Each action will show which arguments are available
- The following arguments are available with all actions that have message customization available:
Variable Name | Format |
---|---|
~subathonName~ | The name used for labeling the subathon (Default: Subathon ) |
%countdownElapsedLong% | x days, x hours, x minutes, and x seconds |
%countdownElapsedShort% | 0.00:00:00 |
%countdownRemainingLong% | x days, x hours, x minutes, and x seconds |
%countdownRemainingShort% | 0.00:00:00 |
%maxDurationLong% | x days, x hours, x minutes, and x seconds |
%maxDurationShort% | 0.00:00:00 |
Messages can then be sent to all configured platforms by setting argument %message%, then Execute C# Method SendMessageToChat
.
OBS Configuration
Ensure the timer is not running while editing any of the OBS text sources. If you edit an OBS text source while the timer is running, it will cause OBS Studio to crash due to the text source being updated by Streamer.bot every second.
(Automatic) Scene creation using OBS Plugin Source Copy
Download or copy the following source copy json and then use Load/Paste Scene from Source Copy. This json data also includes the individual time unit text sources as explained below.
After loading the scene with Source Copy, feel free to adjust the appearance of the text source(s) as you see fit.
{"sources":[{"prev_ver":520159233,"name":"[TS] Subathon Time","uuid":"9cfcec06-44b5-4b1a-aaa6-8217b7a34131","id":"text_gdiplus","versioned_id":"text_gdiplus_v3","settings":{"outline":true,"font":{"face":"Consolas","style":"Bold","size":256,"flags":1},"bk_color":4278190080,"outline_size":17,"outline_color":4278190080,"antialiasing":true,"vertical":false,"align":"right","valign":"bottom","text":"1.02:34:56"},"mixers":0,"sync":0,"flags":0,"volume":1.0,"balance":0.5,"enabled":true,"muted":false,"push-to-mute":false,"push-to-mute-delay":0,"push-to-talk":false,"push-to-talk-delay":0,"hotkeys":{},"deinterlace_mode":0,"deinterlace_field_order":0,"monitoring_type":0,"private_settings":{}},{"prev_ver":520159233,"name":"[TS] Subathon Time Days","uuid":"a30ba76c-e1d5-4b44-9aa8-6a67b1ae9360","id":"text_gdiplus","versioned_id":"text_gdiplus_v3","settings":{"outline":true,"text":"1","font":{"face":"Consolas","style":"Bold","size":256,"flags":1},"bk_color":4278190080,"outline_size":17,"outline_color":4278190080,"align":"right","valign":"center"},"mixers":0,"sync":0,"flags":0,"volume":1.0,"balance":0.5,"enabled":true,"muted":false,"push-to-mute":false,"push-to-mute-delay":0,"push-to-talk":false,"push-to-talk-delay":0,"hotkeys":{},"deinterlace_mode":0,"deinterlace_field_order":0,"monitoring_type":0,"private_settings":{}},{"prev_ver":520159233,"name":"[TS] Subathon Time Hours","uuid":"0cd20353-826c-40b1-9659-5711c80f02dc","id":"text_gdiplus","versioned_id":"text_gdiplus_v3","settings":{"outline":true,"font":{"face":"Consolas","style":"Bold","size":256,"flags":1},"bk_color":4278190080,"outline_size":17,"outline_color":4278190080,"align":"right","valign":"center","text":"2"},"mixers":0,"sync":0,"flags":0,"volume":1.0,"balance":0.5,"enabled":true,"muted":false,"push-to-mute":false,"push-to-mute-delay":0,"push-to-talk":false,"push-to-talk-delay":0,"hotkeys":{},"deinterlace_mode":0,"deinterlace_field_order":0,"monitoring_type":0,"private_settings":{}},{"prev_ver":520159233,"name":"[TS] Subathon Time Minutes","uuid":"e9b03045-92cd-4a81-97be-972bc0ed8714","id":"text_gdiplus","versioned_id":"text_gdiplus_v3","settings":{"text":"34","outline":true,"font":{"face":"Consolas","style":"Bold","size":256,"flags":1},"bk_color":4278190080,"outline_size":17,"outline_color":4278190080,"align":"right","valign":"center"},"mixers":0,"sync":0,"flags":0,"volume":1.0,"balance":0.5,"enabled":true,"muted":false,"push-to-mute":false,"push-to-mute-delay":0,"push-to-talk":false,"push-to-talk-delay":0,"hotkeys":{},"deinterlace_mode":0,"deinterlace_field_order":0,"monitoring_type":0,"private_settings":{}},{"prev_ver":520159233,"name":"[TS] Subathon Time Seconds","uuid":"a67fc72b-f511-4199-b5bf-059653432ba8","id":"text_gdiplus","versioned_id":"text_gdiplus_v3","settings":{"text":"56","outline":true,"font":{"face":"Consolas","style":"Bold","size":256,"flags":1},"bk_color":4278190080,"outline_size":17,"outline_color":4278190080,"align":"right","valign":"center"},"mixers":0,"sync":0,"flags":0,"volume":1.0,"balance":0.5,"enabled":true,"muted":false,"push-to-mute":false,"push-to-mute-delay":0,"push-to-talk":false,"push-to-talk-delay":0,"hotkeys":{},"deinterlace_mode":0,"deinterlace_field_order":0,"monitoring_type":0,"private_settings":{}},{"prev_ver":520159233,"name":"[TS] Subathon Time Play Pause","uuid":"e6d3c006-7e02-4c9b-a82e-e0917fc9ab81","id":"text_gdiplus","versioned_id":"text_gdiplus_v3","settings":{"outline":true,"text":"⏸","font":{"face":"Consolas","style":"Bold","size":256,"flags":1},"bk_color":4278190080,"outline_size":17,"outline_color":4278190080,"align":"right","valign":"center"},"mixers":0,"sync":0,"flags":0,"volume":1.0,"balance":0.5,"enabled":true,"muted":false,"push-to-mute":false,"push-to-mute-delay":0,"push-to-talk":false,"push-to-talk-delay":0,"hotkeys":{},"deinterlace_mode":0,"deinterlace_field_order":0,"monitoring_type":0,"private_settings":{}},{"prev_ver":520159233,"name":"[NS] Subathon","uuid":"9623aeba-665c-4810-98cd-34587b5b8367","id":"scene","versioned_id":"scene","settings":{"custom_size":false,"id_counter":9,"items":[{"name":"[TS] Subathon Time","source_uuid":"9cfcec06-44b5-4b1a-aaa6-8217b7a34131","visible":true,"locked":true,"rot":0.0,"scale_ref":{"x":1280.0,"y":720.0},"align":5,"bounds_type":6,"bounds_align":10,"bounds_crop":false,"crop_left":0,"crop_top":0,"crop_right":0,"crop_bottom":0,"id":2,"group_item_backup":false,"pos":{"x":0.0,"y":624.0},"pos_rel":{"x":-1.7777777910232544,"y":0.7333333492279053},"scale":{"x":1.0,"y":1.0},"scale_rel":{"x":1.0,"y":1.0},"bounds":{"x":1280.0,"y":96.0},"bounds_rel":{"x":3.555555582046509,"y":0.2666666805744171},"scale_filter":"disable","blend_method":"default","blend_type":"normal","show_transition":{"duration":0},"hide_transition":{"duration":0},"private_settings":{}},{"name":"[TS] Subathon Time Days","source_uuid":"a30ba76c-e1d5-4b44-9aa8-6a67b1ae9360","visible":false,"locked":true,"rot":0.0,"scale_ref":{"x":1280.0,"y":720.0},"align":5,"bounds_type":6,"bounds_align":10,"bounds_crop":false,"crop_left":0,"crop_top":0,"crop_right":0,"crop_bottom":0,"id":3,"group_item_backup":false,"pos":{"x":0.0,"y":0.0},"pos_rel":{"x":-1.7777777910232544,"y":-1.0},"scale":{"x":1.0,"y":1.0},"scale_rel":{"x":1.0,"y":1.0},"bounds":{"x":1280.0,"y":96.0},"bounds_rel":{"x":3.555555582046509,"y":0.2666666805744171},"scale_filter":"disable","blend_method":"default","blend_type":"normal","show_transition":{"duration":0},"hide_transition":{"duration":0},"private_settings":{}},{"name":"[TS] Subathon Time Hours","source_uuid":"0cd20353-826c-40b1-9659-5711c80f02dc","visible":false,"locked":true,"rot":0.0,"scale_ref":{"x":1280.0,"y":720.0},"align":5,"bounds_type":6,"bounds_align":10,"bounds_crop":false,"crop_left":0,"crop_top":0,"crop_right":0,"crop_bottom":0,"id":4,"group_item_backup":false,"pos":{"x":0.0,"y":96.0},"pos_rel":{"x":-1.7777777910232544,"y":-0.7333333492279053},"scale":{"x":1.0,"y":1.0},"scale_rel":{"x":1.0,"y":1.0},"bounds":{"x":1280.0,"y":96.0},"bounds_rel":{"x":3.555555582046509,"y":0.2666666805744171},"scale_filter":"disable","blend_method":"default","blend_type":"normal","show_transition":{"duration":0},"hide_transition":{"duration":0},"private_settings":{}},{"name":"[TS] Subathon Time Minutes","source_uuid":"e9b03045-92cd-4a81-97be-972bc0ed8714","visible":false,"locked":true,"rot":0.0,"scale_ref":{"x":1280.0,"y":720.0},"align":5,"bounds_type":6,"bounds_align":10,"bounds_crop":false,"crop_left":0,"crop_top":0,"crop_right":0,"crop_bottom":0,"id":5,"group_item_backup":false,"pos":{"x":0.0,"y":192.0},"pos_rel":{"x":-1.7777777910232544,"y":-0.46666663885116577},"scale":{"x":1.0,"y":1.0},"scale_rel":{"x":1.0,"y":1.0},"bounds":{"x":1280.0,"y":96.0},"bounds_rel":{"x":3.555555582046509,"y":0.2666666805744171},"scale_filter":"disable","blend_method":"default","blend_type":"normal","show_transition":{"duration":0},"hide_transition":{"duration":0},"private_settings":{}},{"name":"[TS] Subathon Time Seconds","source_uuid":"a67fc72b-f511-4199-b5bf-059653432ba8","visible":false,"locked":true,"rot":0.0,"scale_ref":{"x":1280.0,"y":720.0},"align":5,"bounds_type":6,"bounds_align":10,"bounds_crop":false,"crop_left":0,"crop_top":0,"crop_right":0,"crop_bottom":0,"id":6,"group_item_backup":false,"pos":{"x":0.0,"y":288.0},"pos_rel":{"x":-1.7777777910232544,"y":-0.19999998807907104},"scale":{"x":1.0,"y":1.0},"scale_rel":{"x":1.0,"y":1.0},"bounds":{"x":1280.0,"y":96.0},"bounds_rel":{"x":3.555555582046509,"y":0.2666666805744171},"scale_filter":"disable","blend_method":"default","blend_type":"normal","show_transition":{"duration":0},"hide_transition":{"duration":0},"private_settings":{}},{"name":"[TS] Subathon Time Play Pause","source_uuid":"e6d3c006-7e02-4c9b-a82e-e0917fc9ab81","visible":false,"locked":true,"rot":0.0,"scale_ref":{"x":1280.0,"y":720.0},"align":5,"bounds_type":6,"bounds_align":10,"bounds_crop":false,"crop_left":0,"crop_top":0,"crop_right":0,"crop_bottom":0,"id":8,"group_item_backup":false,"pos":{"x":0.0,"y":384.0},"pos_rel":{"x":-1.7777777910232544,"y":0.06666672229766846},"scale":{"x":1.0,"y":1.0},"scale_rel":{"x":1.0,"y":1.0},"bounds":{"x":1280.0,"y":96.0},"bounds_rel":{"x":3.555555582046509,"y":0.2666666805744171},"scale_filter":"disable","blend_method":"default","blend_type":"normal","show_transition":{"duration":0},"hide_transition":{"duration":0},"private_settings":{}}]},"mixers":0,"sync":0,"flags":0,"volume":1.0,"balance":0.5,"enabled":true,"muted":false,"push-to-mute":false,"push-to-mute-delay":0,"push-to-talk":false,"push-to-talk-delay":0,"hotkeys":{"OBSBasic.SelectScene":[],"libobs.show_scene_item.2":[],"libobs.hide_scene_item.2":[],"libobs.show_scene_item.3":[],"libobs.hide_scene_item.3":[],"libobs.show_scene_item.4":[],"libobs.hide_scene_item.4":[],"libobs.show_scene_item.5":[],"libobs.hide_scene_item.5":[],"libobs.show_scene_item.6":[],"libobs.hide_scene_item.6":[],"libobs.show_scene_item.8":[],"libobs.hide_scene_item.8":[]},"deinterlace_mode":0,"deinterlace_field_order":0,"monitoring_type":0,"canvas_uuid":"6c69626f-6273-4c00-9d88-c5136d61696e","private_settings":{}}]}
(Manual) Create the Scene and GDI Text Source
- Create a scene and name it what you named it in the Streamer.bot action.
[NS] Subathon
by default (NS is short for nested scene) - In that newly created scene, create a GDI text source with what you named it in the Streamer.bot action.
[TS] Subathon Time
by default (TS is short for text source)
When the timer is running, it will automatically update the text source with the time left in the subathon
- Feel free to adjust the appearance of the text source(s) as you see fit.
- For best looking results, use a mono-space font and align to the right, this way, the numbers don't jump around as they change.
- You may add this nested scene into any other scenes as a source. For more information on nested scenes, watch this video: Nutty explains OBS Nested Scenes - YouTube
(Optional) Individual text sources for each unit of time
You can now add separate text sources for each unit of time so you can further customize the look and layout of your timer. If you wish to use these, make sure to set the global variable ~subathonIndividualTimeUnits~
to True
Unit | Global Variable Name | Default Source Name | Notes |
---|---|---|---|
Days | subathonSourceDays | [TS] Subathon Time Days | Left blank if ~displayDays~ is False |
Hours | subathonSourceHours | [TS] Subathon Time Hours | Left blank if hours is zero |
Minutes | subathonSourceMinutes | [TS] Subathon Time Minutes | |
Seconds | subathonSourceSeconds | [TS] Subathon Time Seconds | |
Play/Pause | subathonSourcePlayPause | [TS] Subathon Play Pause | Display ⏵ or ⏸ whether or not timer is running |
Usage
Initializing OBS Source
If you want to have the timer display the starting time before you actually start:
- Edit the global variable
~subathonInitialDuration~
with the the initial time you want to start with - Initialize the text source(s) by running the Test Trigger for action
Subathon 0a. Initialize OBS Source
Starting/Resuming Subathon
Trigger the actions Subathon 1. Start
or Subathon 2. Resume
to start/resume the Subathon respectively. A chat message will be sent, the timer will start, and automatically start updating the configured text source.
The action Subathon Event Action Group Enable
will be triggered, causing the Action and Command Groups Subathon Add Time
are enabled while the timer is running. Time can now be added while the timer is running.
Pausing Subathon
You have the ability to pause your Subathon and resume at a later time.
The action Subathon Event Action Group Disable
will be triggered, causing the Action and Command Groups Subathon Add Time
to disable while the timer is not running.
By default, pausing the Subathon also pauses the ability to add time!
If you wish for time to be added while the timer is paused, make sure to disable the action Subathon Event Action Group Disable
Cancelling Subathon
If you decide you want to cancel and reset the timer, you can trigger the cancel command by typing !subathonCancel
. Streamer.bot will respond asking you to confirm by typing the command a second time. Upon confirmation, the action Subathon Event Cancelled
will be triggered.
The action Subathon Event Action Group Disable
will be triggered, causing the Action and Command Groups Subathon Add Time
to disable while the timer is not running.
Getting Elapsed/Remaining/Goal Progress
You can run the appropriate actions to return the time elapsed, time remaining, or the goal progress by running the appropriate command. The command will send a message in chat with the requested information.
The action Subathon Command Goal Progress
displays your progress (in percent) in regards to the total time added compared to your ~subathonMaxDuration~
setting.
Completing Subathon
When the timer hits zero, the action Subathon Event Completed
will be triggered.
The action Subathon Event Action Group Disable
will be triggered, causing the Action and Command Groups Subathon Add Time
to disable while the timer is not running.
Commands
Imported commands are disabled by default as a security measure. Please make sure to enable the !subathonStart
and !subathonResume
command. The other commands will be enabled when you start the subathon.
Usable commands while timer is not running
Command Name | Description | Note |
---|---|---|
!subathonStart | Start the subathon | You need to enter it twice to confirm overwriting an existing subathon |
!subathonResume | Resume the subathon | You can resume even if you've restarted Streamer.bot or if it crashed |
Usable commands while timer is running
Command Name | Description | Note |
---|---|---|
!subathonCancel | Cancel the subathon | You need to enter it twice to confirm overwriting an existing subathon |
!subathonPause | Pause the subathon | |
!subathonAdd x | Add time to the subathon Time can be removed by adding a hyphen - in front of the time | Use this format: d for days, h for hours, m for minutes, s for seconds Examples: 5d4h3m , 1h30m , 5m , 1h |
!subathonElapsed | Return a chat message to see subathon elapsed time | |
!subathonRemaining | Chat message to see subathon remaining time | |
!subathonProgress | Chat message to see current subathon progress | |
!subathonHappyHourStart !subathonPowerHourStart | Start a Happy Hour to apply a multiplier to time added | |
!subathonHappyHourStop !subathonPowerHourStop | Stop the Happy Hour |
Credits
- Nate1280 - for creating Streamer.bot. Please support Nate on Patreon as he builds Streamer.bot by himself and in his free time.
- Vina - for helping me get started
- Everyone who purchased the timer!
Testers and bug finders
Need help?
Join the discord to get help or provide feedback and post in the #extension-support channel: Rondhi's Discord