Skip to content
Discord Download

Lists

Lists for raffles and wheels, plus maps and tables of rows that macros look things up in, such as a bits-to-effect table.

A list is a named collection that viewers join and CroStream picks from: a raffle, a giveaway, “who plays next”, the slices of a prize wheel. A chat command adds the viewer, a Pick button or a macro step chooses a winner at random, and a trigger can announce it.

Lists come in three kinds. A List is the one above. A Map holds a value for each key, such as a nickname for each viewer. A Table holds rows with typed columns, such as a label, a range of bits and a duration, that your macros search and loop over. CroStream stores the data and gives macros the steps to read it; what the data means is up to your macros. See Maps and tables.

Lists are built in; they need no connection.

Open Lists in the sidebar (under Automate). Each list is a card showing:

  • its label, how many entries it holds and a copy chip for {list.<name>.count};
  • its entries, each with a button to take it off, and a box to add one by hand (a viewer’s name, for a list of viewers);
  • Pick, with two switches next to it, Remove the winner and Avoid repeats. A Winner of … box opens with who was picked, and buttons to Take off the list or Pick again;
  • Shuffle, Clear… (it asks first, and keeps the last pick), Edit and Delete.

A map or table card shows its rows as a grid instead; see The table editor.

Setting What it does
Kind List, Map or Table. Choose it when you make the list; it can’t change afterwards.
Name The list’s key, used in {list.<name>.count}. Lowercase letters, digits, - and _, up to 40 characters. It can’t change after you create the list; to rename it for display, change the label.
Label The name people see, such as Raffle.
Description A note for yourself.
Entries are viewers The value of each entry is a viewer’s login and its label their display name. A step that adds with no value then adds whoever ran the macro.
No duplicates On by default. Refuses a value that’s already on the list, so a viewer joins once. Values are compared ignoring capitals.
Largest size How many entries it holds, up to 1,000, which is also what empty means.
Keep entries across restarts On by default. Off: the list is emptied each time CroStream starts, for a raffle you run in one sitting.

You can have up to 200 lists, maps and tables together.

Each entry has a value (what makes it unique), a label (how it’s shown), the viewer’s ID when it has one, when it was added and who added it.

  1. On the Lists page, make a list named raffle, labeled Raffle, with Entries are viewers and No duplicates on.

  2. Make a macro Join the raffle with one Add to a list step named join, List raffle, and the value left empty. An empty value adds the chatter who ran the command.

  3. Make a trigger on Chat command !join that runs the macro. Viewers who type !join are on the list; typing it again changes nothing.

  4. To pick, click Pick on the Lists page. To pick from chat or a button instead, make a macro with a Pick from a list step named winner, List raffle, then a Send chat message step:

    CroStream The winner is @{winner.label}!

Turn on Remove the winner to give each prize to a different person, or Avoid repeats (without removing anyone) to draw again until everyone has had a turn. The two don’t combine: removing the winner already avoids repeats.

To tell a viewer they’re in, or that they already were, use the Add to a list step’s {added} output with an If step: {join.added} is false with {join.reason} set to duplicate or full.

Three values are available in any text a macro sends:

Write You get
{list.<name>.count} How many entries the list has.
{list.<name>.last} The label of the entry added last.
{list.<name>.picked} The label of the last pick; empty before the first.

The Lists group of the palette has eleven actions for lists, and five more for rows:

Action What it does Outputs
Add to a list Puts an entry on the list. A duplicate or a full list is not an error: {added} says what happened. {added}, {reason}, {count}, {value}, {label}
Remove from a list Takes an entry off by its value. {removed}, {count}
Clear a list Takes every entry off. {count}
Check a list for an entry Finds out whether an entry is on the list. {yes}
Pick from a list Chooses an entry at random. It fails when the list is empty. {value}, {label}, {user_id}, {index}, {count}
Shuffle a list Puts the entries in a random order. {count}
Read a list Reads its size and entries. {count}, {items}, {last_added}, {picked}, {label}
Create a list Makes a list. If the name exists, it fails or keeps the existing list. {count}
Change a list’s settings Edits the label, description, rules or size. The entries stay. {count}
Delete a list Removes it and its entries. {count}
List the lists Lists every list. {names}, {count}

Every setting accepts {variables}. Full details are in the Actions reference.

Event Fires when
Entry added to a list An entry joins a list. It doesn’t appear in the activity feed.
Entry removed from a list An entry leaves a list, including a winner taken off by a pick. It doesn’t appear in the activity feed.
Entry picked from a list An entry is picked at random.
List cleared A list is emptied.
List created and List deleted A list is made or removed.

Each can be limited to one list. The macro gets {list}, {list_label}, {value}, {label}, {user_id}, {added_by}, {count}, {index}, {removed} and {cause}. See the Events reference.

An If step can check the live values List size and List has entry. For the second, write the argument as list|value, such as raffle|{user_login}. See Conditions.

A map and a table hold rows instead of entries. Every row has a key, its name in the list, and fields:

  • A map has one field, its value: a key and what it stands for.
  • A table has the columns you design. Each column has a type:
Column type Holds
text Words, up to 200 characters.
number A number such as 500 or 2.5.
duration A length of time such as 30s, 2m or 1h30m.
yes/no On or off (true or false).
media An item from your media library: a sound, a video or a picture. The field holds the item’s ID (media-…), which you can pass to any step that plays or shows media, such as Set overlay media, or to your own widgets.

A row key is lowercase letters, digits, - and _, up to 60 characters, and can’t be only digits, so that a number always means a position. Keys are unique, ignoring capitals. count, keys, last and picked are reserved. CroStream checks every value against its column’s type: a step that sets abc in a number column fails with a message saying so.

A table has at most 30 columns and holds at most 1,000 rows (or the Largest size you set). Maps and tables count towards the same free-plan limit as lists. Keep rows across restarts works as it does for entries.

Choose New list, then Map or Table. For a table, the Columns panel is the column designer:

Setting What it does
Name The column’s key, such as bits_low: lowercase letters, digits and _, starting with a letter, up to 40 characters. key and index are taken. It can’t change once the table is saved; remove the column and add another to rename it.
Label The heading people see. Defaults to the name.
Type Text, number, duration, yes/no or media.
Accepts For a media column: which kinds the picker offers (pictures, sounds, videos). None ticked means any.
Default What a new row gets in this column. Empty means not set: the field stays empty until you fill it in.
Unique No two rows may have the same value in this column. You can’t turn it on, or add such a column, while rows would share a value, and a step or edit that would repeat one is refused.

The arrows move a column; the bin removes it after you confirm. Removing a column drops its values from every row, a new column gives every row its default, and a value that doesn’t fit a changed type goes back to the default.

The list’s card on the Lists page is then a grid, one line per row:

  • Click a cell to edit it, with an input that fits the column’s type (a checkbox for yes/no). The change saves when you leave the cell. A media cell shows the item’s thumbnail and name: Choose… opens the media picker and Clear empties it. An item that was deleted from the library shows File not found.
  • Type a key in New row key and click Add row.
  • The arrows move a row up or down, and the cross removes it. Row order decides the positions that {list.<name>.<n>.<field>} uses.
  • The small copy button on a column heading copies its template for the first row, and clicking a row’s key copies the template for that row’s first field.

A map’s grid has two columns, key and value.

Write You get
{list.<name>.keys} Every row’s key, separated by commas.
{list.<name>.<key>.<field>} One field of the row with that key, such as {list.sabotage.blur.label}.
{list.<name>.<n>.<field>} One field of the nth row, counting from 1.
{list.<name>.<key>.key} or {list.<name>.<n>.key} A row’s key.
{list.<name>.<key>} For a map, the key’s value.

{list.<name>.count} works as it does for lists; {list.<name>.last} and {list.<name>.picked} give the key of the row made last and of the row picked last. Fields are written as CroStream stores them: a number as plain decimal, a duration as 2m or 1m30s, a yes/no as true or false, a media field as the item’s ID. A field that isn’t set is empty, in every type: test it with is empty. An empty field isn’t a number, so number comparisons and is between don’t hold for it.

Note: Only the first 200 rows have these variables

To keep every step fast, only the first 200 rows of a table or map get {list.<name>.<key>.<field>} and {list.<name>.<n>.<field>}. For a bigger table, read a row with Read a row, or use the Table field live value, which reaches any row.

The Lists group of the palette also has actions for rows. They work on tables and maps (Find rows works on plain lists too). Each field of a row becomes an output: a step with the ID hit that reads a row with a label column gives {hit.field.label}, and {label} when no other output has that name.

Action What it does Outputs
Read a row Reads one row by its key or position. A row that isn’t there is not an error: {found} says so. {found}, {key}, {index}, {fields}, and every field
Set a row Makes a row or changes one. Only the fields you give change; a new row takes the defaults for the rest. If the row exists is upsert (make or change), create (fail when the key is taken) or update (fail when there is no row). {created}, {key}, {index}, {count}
Set a row’s field Changes one field of a row that exists. For a number column, Change can add to the value or subtract from it, such as counting how many times a row was used. {value}, {previous}, {key}, {index}
Remove a row Takes a row off by its key or position. {removed}, {key}, {count}
Find rows Looks for the rows that match a condition. See below. {found}, {count}, {key}, {index}, {keys}, {fields}, and every field of the result

{fields} is every field as name=value lines.

Pick from a list, Shuffle a list, Clear a list and Read a list work on tables and maps too: a pick gives the row’s {key} and its fields. Remove from a list and Check a list for an entry take a row’s key. Add to a list is for plain lists and the row actions are for tables and maps; using one on the wrong kind fails with a clear message. Create a list takes a Kind and, for a table, Columns, one name:type per line such as bits_low:number. Change an existing table’s columns on the Lists page.

Find rows keeps the rows its Where condition holds for. Where is built like an If condition, and its rules can use {row.<field>}, {row.key} and {row.index} for the row being tested, besides every variable of the macro. A rule compares values, so live values such as the current scene aren’t allowed in it.

Setting What it does
Where Which rows match. Empty matches every row.
Result Whether the field outputs describe the first or the last match. {keys} and {count} always cover every match.
Sort by, Order A column to order matches by. Numbers and durations sort by size, text without regard to capitals. Empty keeps the table’s order.
At most Keep only this many matches. 0 keeps all.
Event Fires when
Row set in a table or map A row is made or changed, by a step, an edit on the Lists page or the API, and something actually changed. {created} tells which.
Row removed from a table or map A row is removed.

Neither appears in the activity feed. The macro gets {list}, {list_label}, {key}, {created} and {count}.

An If step can check Table or map has row, written list|key such as sabotage|{args}, and Table field, written list|key|field such as sabotage|{args}|label. A number field compares as a number. See Conditions.

The For each block of the macro editor runs steps once for every row of a table or list, or for values and numbers. It is the tool for “do this for each row that matches”. See For each.

Chat decides how you’re sabotaged by cheering bits. Each effect has a range of bits, a label for chat and, for some, how long it lasts. CroStream keeps the data and gives the macro the building blocks; what each effect does, and what counts as a match, is your design.

  1. Make a Table named sabotage with these columns:

    Name Type
    label text
    bits_low number
    bits_high number
    duration duration
  2. Add a few rows in the grid, one per effect, such as:

    Key label bits_low bits_high duration
    blur Blurry screen 1 99 30s
    mirror Mirrored camera 100 499 1m
    shout Shout every sentence 500 999 2m
    loadout Drop your loadout and scrounge 1000 1000000
  3. On the Timers page, make a countdown timer named effect to show how long the current effect has left (see Timers).

  4. Make a macro Sabotage with a Find rows step named hit, List sabotage. In Where, add one rule with {bits} is between {row.bits_low}..{row.bits_high}. A row matches when the cheer is within its range, ends included. You can also write it as two rules, {row.bits_low} ≤ {bits} and {row.bits_high} ≥ {bits}, with all of them holding.

  5. Add an If step on {hit.found} is true. Under Then, add a Send chat message step:

    CroStream {user} cheered {bits}: {hit.label}!

  6. Still under Then, add a second If on {hit.duration} is not empty, and under it a Start a timer step with Timer effect and Amount {hit.duration}. Rows with no duration, like loadout, have no time limit and skip the timer.

  7. Make a trigger on Cheer or power-up that runs the macro.

If several rows match, Find rows reads the first. Set Sort by bits_low and Order Descending to prefer the highest range.

To handle every row whose range holds the cheer, loop instead of finding:

  1. Add a For each block on List or table sabotage.
  2. Add a Where with {bits} is between {row.bits_low}..{row.bits_high}.
  3. Inside Do, add the Send chat message step {user} cheered {bits}: {row.label} for {row.duration}!.

Every matching row now says its piece, in table order. Add a Stop with Leave the loop after the message to stop at the first match.

Tip: Change the effects without touching the macro

The rows are the settings. To add an effect, add a row in the grid; to make one longer, edit its duration cell. The macro stays as it is.

Overlays and custom widgets read a list as the data key list.<name>, with the entries, the count and the last pick. It’s built for a spin-the-wheel widget: the widget spins when the pick changes and lands on the picked entry. A table or map is sent with its columns and rows instead, for widgets you write yourself; CroStream has no built-in widget for it. See Overlay data.

The free plan has 1 list, counting maps and tables. Subscribers to Haliebug13 on Twitch have unlimited lists.

If you’re over the limit, for example after a subscription lapses, your lists keep working: viewers can join, you can add, remove, pick, shuffle and clear. Editing a list’s settings and adding lists need a subscription. Deleting is always allowed.