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!

Steps in an action

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.

Format

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.

Placeholders

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}"

Easier multi-step execution

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}

List of available steps

This list will describe the function of every step, its properties and how it can be used.

message

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 a title 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"

command

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

delay

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}"

cancel

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}"

function

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}"

set_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

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:

repeat

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"

random

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

bulk_random_elements

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

check

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

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:

random_number

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 like 0.01 and 4 returns 0.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"

random_element

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}"

expression

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 in replacement
    • 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 to REPLACE
  • group: The name of the capturing group to use if action is set to GROUP

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!"

command

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

extract

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}"
⚠️ **GitHub.com Fallback** ⚠️