Steps - Membercat-Studios/Streamlabs-Integration GitHub Wiki
Steps can be used to respond to an event in many different ways, for example executing a command for displaying a message in chat. There are multiple types of steps that can be used to accomplish different things. On this page, we'll have a look through all of them and how you can use them to create awesome custom donation events!
An action has a steps
property that contains all of the steps that will be executed once the action gets triggered:
actions:
my_action:
enabled: true
action: youtube_gift_memberships
steps:
- message: "It works!"
The example above shows an action named my_action
that will trigger once someone gifts some memberships on youtube.
When that action gets triggered, it will send the message "It works" in the chat, using the message
step.
As you can see in the example above, steps follow a certain format, determining the step's type and what exactly it does:
- <step type>: <data>
<property>: value
- The step type is the type of the step, essentially determining what it will do
- The data is what the step uses to execute its action, e.g. the message to send or the command to execute
- A step can also have additional properties that can be used to further customize its execution, e.g. if a command should be executed as a player or from the console
Here's an example of a basic message
step:
- message: "This is a test message!"
In this case, message
is the step type, determining that we want to send a message, and "This is a test message!"
is the step data which is used to send that message.
A lot of steps allow you to use placeholders in their data and additional properties, to allow for full integratio of data from the Streamlabs event into the step execution.
Here's an example of an action with a command
step that gives the player as many diamonds as the amount of gifted memberships:
actions:
give_diamonds:
enabled: true
action: youtube_gift_memberships
steps:
- command: "give YourMinecraftUsername minecraft:diamond {amount}"
There can be cases where you'll need to execute the same step a few times, e.g. to send a lot of messages to the player. This can get pretty annoying quickly, since you'll have to add message:
on every new line:
- message: "This is line 1"
- message: "This is line 2"
- message: "test"
- message: "another test"
- message: "a lot of messages"
This is why the plugin allows you to use another format to execute the same step a few times:
- message:
- "This is line 1"
- "This is line 2"
- "test"
- "another test"
- "a lot of messages"
This kind of format can be used on any step, as long as the step itself doesn't already take in a list of something else (e.g. most logic steps). If you want to use the additional properties some steps provide, you can still specify them like this, and they'll apply to all of the executed sub-steps:
- command:
- "say test"
- "time set 0"
- "tp {player} 0 100 0"
- "execute at {player} run summon pig"
context: "{player}
This list will describe the function of every step, its properties and how it can be used.
Can be used to send a message in chat or as a title. MiniMessage formatting for colors etc. is supported, as well as placeholders.
- message: "[<type>]<content>"
title_fade_in: <time in ms> # Optional
title_stay: <time in ms> # Optional
title_fade_out: <time in ms> # Optional
-
<type>: The type of message to send, can be one of the following:
-
message
(default if left out): A normal message in chat -
message_centered
: A normal chat message, but automatically centered based on the default minecraft character width (@Mazurex politely reminded me that the plugin obviously needed this functionality) -
title
: A title that will be shown on screen -
subtitle
: A subtitle that will be shown below an active title. This will ONLY show up if atitle
message is also being shown!
-
- <content>: The content of the message to show, supports placeholders and MiniMessage
- title_fade_in (optional): The fade-in time for a title (in milliseconds)
- title_stay (optional): The time a title will stay on screen (in milliseconds)
- title_fade_out (optional): The fade-out time for a title (in milliseconds)
Important
The title_fade_in, title_stay and title_fade_out properties will only take effect when using the title
message type, NOT subtitle
!
Be aware that messages will also only be received by players in the affected_players
list!
Here are some examples on how this step can be used:
- message: "A normal message"
- message: "[message]Another normal message"
- message: "[message_centered]A centered message!"
- message: "<red>I am red!"
- message: "I am <b>bold</b>!"
- message: "You can click <click:open_url:https://docs.advntr.dev/minimessage><aqua>This link</aqua></click> to find out more!"
- message: "{user} just donated {amount_formatted}, <green>thanks</green>!"
- message: "[title]A title"
- message: "[subtitle]And a subtitle"
- message: "[title]Another title"
title_fade_in: 5000
- message: "[subtitle]This will take 5 seconds to fade in"
Executes any minecraft command, with support for placeholders.
- command: "<command>"
timeout: <time in ms> # Optional, default 500ms
context: <entity selector> # Optional, default = server console
cancel_on_invalid_context: <true/false> # Optional, default false
- <command>: The command to execute, supports placeholders
- timeout (optional): How long the plugin will wait for the command to finish executing (in milliseconds)
- context (optional): What is executing the command, e.g. a certain player or the server console, if left out. Supports placeholders
-
cancel_on_invalid_context (optional): Whether the plugin should cancel the command execution if an invalid context was provided. If set to
false
(and by default), the plugin will execute the command as the server console instead
This step also allows the use of a special {player}
placeholder (in the command and context), which, when used, will execute the given command for every player in the affected_players
list, with the placeholder being replaced with thier name. If the placeholder is used in the context
property, the first player from affected_players
will be used.
Tip
This step can optionally be used as a query to access the output of the command as a placeholder
Here are some examples on how this step can be used:
- command: "time set 0"
- command: "execute at {player} run summon wither"
- command: "say I'm a player"
context: YourMinecraftUsername
Waits for a certain amount of time before executing the next steps.
- delay: <delay in ms>
The delay can either be a number or a placeholder, which the plugin will attempt to parse into a number. If that fails, a message will be displayed in the console and the delay will be skipped. Note that the delay is specified in milliseconds, and can't be negative or zero.
Here are some examples on how this step can be used:
- message: "Hello!"
- delay: 1000
- message: "I will appear after 1 second!"
- message: "[title]Teleporting you in 3..."
- delay: 1000
- message: "[title]Teleporting you in 2..."
- delay: 1000
- message: "[title]Teleporting you in 1..."
- delay: 1000
- message: "[title]Teleporting now!"
- command: "tp {player} 0 100 0"
- delay: "{amount}"
Completely stops the execution of the current action.
- cancel: <true/false> # Supports placeholders
The step will only stop action execution if the provided value is true
, with that value supporting placeholders. Here are some examples on how this step can be used:
- cancel: true
- cancel: "{a_placeholder}"
Executes a function with the given parameters, can optionally be used as a query to get the function's output.
- function: <function name>
parameters: # Optional
<param name>: <param value> # value supports placeholders
output: <output placeholder> # Optional
- <function name>: The name/ID of the function to run, supports placeholders
- parameters (optional): A list of parameters that will be passed to the function
Tip
To learn more on how functions work, make sure to read this page!
Here are some examples on how this step can be used:
- function: my_function
- function: another_function
text: "this is a lot of text"
number: 69
- function: "{function_name_placeholder}"
Creates or changes an existing variable placeholder with the given value.
- set_placeholder: "[<placeholder name>]<value>"
- <placeholder name>: The name of the placeholder to create/change
- <value>: The value to set the placeholder to, supports placeholders and math expressions
Variable placeholders created by this step will look like this: {#placeholder}
. Here are some examples on how this step can be used:
- set_placeholder: "[test]Test!"
- message: "This is a {#test}"
- set_placeholder: "[amount_times_two]{amount}*2"
- message: "Amount times 2: {#amount_times_two}"
- set_placeholder: "[another_test]this is a test"
- message: "value: {#another_test}"
- set_placeholder: "[another_test]<red>now I'm red"
- message: "value: {#another_test}"
Logic Steps are special steps that take in a list of other steps as their value, and then execute them in a certain way (e.g. only if a certain condition is met or multiple times). The plugin supports the following logic steps:
Executes the given steps n amount times, with n being configurable through the amount
property.
- repeat:
<steps to execute>
amount: <repeat amount> # Defaults to 2 when left out
server_thread: <true/false> # Optional, false by default
- amount: How many times the given steps should be executed, supports placeholders
- server_thread: Whether to run all of the given steps on the server thread / "in one tick"
Warning
Incorrect usage of server_thread
can result in the entire server freezing, make sure to read this page for more information!
Here are some examples on how this step can be used:
- repeat:
- message: "I will be shown 5 times!"
amount: 5
# This example assumes you're using the youtube_gifted_memberships event type
- repeat:
- command: "execute at {player} run summon zombie"
amount: "{amount}"
server_thread: true
- set_placeholder: "[timer]10"
- repeat:
- message: "[title]Explosion in {#timer}"
- set_placeholder: "[timer]{#timer}-1"
- delay: 1000
amount: 10
- message: "[title]<red>Explosion now!"
- command: "execute at {player} run summon tnt"
Randomly chooses one of the given steps and executes it.
- random:
<steps to execute>
seed: <the random seed> # Optional
- seed: The seed used to randomly select a step, a time-based seed will be used if left out
Here are some examples on how this step can be used:
- random:
- message: "Option 1 chosen!"
- message: "Option 2 chosen!"
- message: "Option 3 chosen!"
- message: "Option 4 chosen!"
- random:
- command: "kill {player}"
- message: "<green>You survived!"
seed: 123456
Randomly selects a given amount of elements from a named collection and executes the given steps for each of them.
- bulk_random_elements:
<steps to execute>
collection: <named collection> # Required
amount: <amount of elements> # Defaults to 2 when left out
selection_behavior: <NORMAL/TRY_NO_DUPLICATES/FORCE_NO_DUPLICATES> # Optional, NORMAL by default
seed: <the random seed> # Optional
server_thread: <true/false> # Optional, false by default
- collection: The named collection to select elements from
- amount: How many elements should be selected, supports placeholders
-
selection_behavior: Determines how elements are selected, can be one of:
-
NORMAL
: Any random element from the collection will be selected for each step -
TRY_NO_DUPLICATES
: Will attempt to not select elements that have already been selected. If all elements of the collection have been selected at least once, duplicate elements may be selected -
FORCE_NO_DUPLICATES
: Will also try to avoid duplicates, but if all elements have been selected at least once, no more steps will be executed instead
-
- seed: The seed used to randomly select a step, a time-based seed will be used if left out
- server_thread: Whether to run all of the given steps on the server thread / "in one tick"
This step will execute the given steps for each of the selected elements from the collection. For each of those iterations, the step will replace the {$element_id}
and {$element_name}
placeholders with the ID and name of the selected element.
Warning
Incorrect usage of server_thread
can result in the entire server freezing, make sure to read this page for more information!
Here are some examples on how this step can be used:
# Selects 15 random items and gives them to the player
- bulk_random_elements:
- command: "give {player} {$element_id}"
- message: "<green>You have been given {$element_name}!"
collection: item
amount: 15
server_thread: true
# Selects 10 random players and spawns creepers at them
- bulk_random_elements:
- command: "execute at {$element_id} run summon creeper"
collection: player
selection_behavior: FORCE_NO_DUPLICATES
amount: 10
server_thread: true
Executes the given steps if a certain list of conditions is met.
- check:
<steps to execute when conditions are met>
else: # Optional
<steps to execute when conditions are not met>
conditions:
<conditions>
donation_conditions:
<donation conditions>
mode: <AND/OR>
This step has properties like conditions
/ donation_conditions
and mode
, which can also be found on actions and similar objects. To learn more about how they function, take a look at conditions!
Here are some examples on how this step can be used:
- check:
- message: "<aqua>Donation high enough, giving diamonds!"
- command: "give {player} diamond 10"
conditions:
- "{amount}>20"
- check:
- message: "<green>The message is: {message}"
else:
- message: "<red>Donation doesn't have a message!"
conditions:
- "!{message}=" # If message is not equal to "" (empty)
Note
The last example won't work with the /streamlabs test
command, since using message=
simply won't set the placeholder instead of setting it to an empty value. We'll rework the test command to support this behavior in a future update!
Queries are another special type of step, which can be used to qurey (obtain) a certain value from the step, and then use that value in the form of a placeholder. Every query has an output
property, used to specify the name of the output placeholder:
- a_query: <value>
input: <input data> # Only present on transformation queries
output: "placeholder_name"
The output placeholder follows this format: {$placeholder_name}
and can be used in all steps after the query step.
Some queries also support an input
property that they then transform (modify) in some way, and output the transformed value. Those queries are called transformation queries.
Here's a list of all supported queries:
Returns a random number from the given range.
- random_number: <range>
decimal: <amount of decimal places> # Optional, default 0
seed: <the random seed> # Optional
output: <output placeholder>
-
decimal: The amount of decimal places to return, e.g.
2
will return a number like0.01
and4
returns0.0058
- seed: The seed used to generate the random number, a time-based seed will be used if left out
The range is used to specify the minimum (inclusive) and maximum (exclusive) bounds for the random number. By just specifying one number, the minimum bound will be set to zero.
Optionally, you can also specify a minimum bound, by separating both numbers with a |
. For example, here's a number range from 10 to 20: 10|20
Here are some examples on how this step can be used:
- random_number: 1|11
output: "spawn_amount"
- repeat:
- command: "execute at {player} run summon zombie"
amount: "{$spawn_amount}"
server_thread: true
- random_number: 1|65 # 65 is exclusive, meaning the query will generate a value between 1 and 64
output: "amount"
- command: "give {player} minecraft:stick {$amount}"
- random_number: 2
output: "the_number"
- check:
- message: "<green>The number is 1!"
else:
- message: "<red>The number is zero!"
conditions:
- "{$the_number}=1"
Returns a random element from a named collection.
- random_element: <collection>
seed: <the random seed> # Optional
output: <output placeholder>
- seed: The seed used to pick the random element, a time-based seed will be used if left out
Here are some examples on how this step can be used:
- random_element: player
output: "the_player"
- command: "kill {$the_player}"
- random_element: living_entity_type
output: "entity"
- command: "execute at {player} run summon {$entity}"
- random_element: item
output: "item"
- random_number: 1|64
output: "amount"
- command: "give {player} {$item} {$amount}"
A transformation query that takes in a regular expression and attempts to match the input against that.
- expression: "<regex>"
input: "<input value>"
action: <MATCH/REPLACE/GROUP> # MATCH by default
use_placeholders: <true/false> # false by default
replacement: "<replacement text>" # Optional, only works with REPLACE
group: "<name of a group in the expression>" # Optional, only works with GROUP
output: <output placeholder>
- <regex>: A regular expression that is used to match the input value. If you're not familiar with regex, I'd recommend websites like regex101 or AutoRegex (I wouldn't usually recommend using AI tools in programming related scenarios, unless you know what you're doing. In this case, it can just be helpful if you don't have the time to learn how regex works!)
-
action: The action to perform on the input using the given expression:
-
MATCH
: If some part of the input matches the expression, that part will be returned -
REPLACE
: If some part of the input matches the expression, that part will be replaced with the value inreplacement
-
GROUP
: Makes the query return the value of a named capturing group in the expression
-
- use_placeholders: Whether placeholders should be enabled in the expression.
-
replacement: The replacement to use if
action
is set toREPLACE
-
group: The name of the capturing group to use if
action
is set toGROUP
If no match could be found for the given expression, the query will return an empty string (""
).
Note
Enabling use_placeholders
is not recommended if not explicitly necessary, since the plugin will compile the expression at runtime instead of doing so when the plugin reloads. Using this feature will disable all of the config reload-time checks (e.g. if the expression is valid or a chosen capturing group exists), which can lead to the query failing without proper testing.
Here are some examples on how this step can be used:
- expression: "\\d+" # Matches any digit
input: "{message}"
output: "testing"
- check:
- message: "<green>Message contains digits!"
else:
- message: "<red>Message doesn't contain any digits!"
conditions:
- "!{$testing}=" # Checks for testing not being empty, meaning the expression matches
- expression: "(?i)hi+\\s*" # Matches every occurrence of "hi" with an arbitrary amount of "i"s and spaces
input: "{message}"
output: "message_without_hi"
action: REPLACE
replacement: "" # Replaces all of the "hi" occurrences with nothing
- message: "Original: \"{message}\", without HIs: \"{$message_without_hi}\""
- expression: "(?<amount>\\d+)\\s*cats?" # Matches every occurrence of "(some number) cats / cat", and captures the number in a group named "amount"
input: "{message}"
output: "cats_amount"
action: GROUP
group: "amount"
- check:
- message: "[title]<red>No cat amount present!"
- cancel: true # Cancels the entire action if no cat amount is present in the message
conditions:
- "{$cats_amount}=" # Checks for the group being empty, meaning no match could be found
- repeat: # Spawns as many cats as the user requested in their message
- command: "execute at {player} run summon cat"
amount: "{$cats_amount}"
server_thread: true
- message: "[title]<green>Spawned <aqua>{$cats_amount}</aqua> cats!"
The command
step can optionally be used as a query to retrieve the command result as a placeholder.
- command: "<command>"
<other properties from the command step>
output: <output placeholder>
output_format: <text/json/minimessage/legacy_section/legacy_ampersand> # Optional, default text
-
output_format: The format of the outputted message, can be one of:
- text: Plain text without any formatting
- json: The JSON representation of the returned component (read more)
-
minimessage: The MiniMessage representation of the command output, can directly be used in a
message
step -
legacy_section: The legacy formatting code based representation of the command output, using the
§
character -
legacy_ampersand: The legacy formatting code based representation of the command output, using the
&
character (typically used by some plugins)
Note
If the {player}
placeholder is used in the query variant of this step, it will only run the command once, with the placeholder being replaced with the first player in the list.
Here are some examples on how this step can be used:
- command: "seed"
output_format: minimessage
output: "seed_output"
- message: "Output of the seed command: {$seed_output}"
# We're using the expression query to find all of the digits in the output of the command
# This is what we're matching exactly:
# Example: The time is 6000
# ^^^^
- command: "time query daytime"
output: "raw_command"
- expression: "\\d+" # Matches one or more digits
input: "{$raw_command}"
ouput: "daytime"
- check:
- message: "It is night!"
else:
- message: "It is day!"
conditions:
- "{$daytime}>13000" # https://minecraft.wiki/w/Daylight_cycle
A transformation query that can extract an element of a named collection from a given input.
- extract: <collection>
input: "<input value>"
output: <output placeholder>
This query can be used to extract things like the name of a player or the ID of a biome from a chat message like "Please teleport me to Player123", ignoring things like capitalization and the location of the name in the message.
Here are some examples on how this step can be used:
- extract: player
input: "{message}"
output: "the_player"
- command: "kill {$player}"
- extract: living_entity_type
input: "{message}"
output: "entity"
- command: "execute at {player} run summon {$entity}"