Custom Types
Custom types let you bundle several related values into one object that travels through your flows together. Instead of juggling a username list and a separate score list and hoping the indexes line up, define a Player type with both fields and store a single list of players.
A custom type is a name plus a set of primitive fields. Each field is one of:
- Text — a string
- Number
- Boolean
- Color (hex) — a
#rrggbbstring - Text Style — one of your text styles. A type with Text Style fields, like a
Themewithtitle,bodyandalert, lets one variable hold a whole look. Widgets can follow each field: see Theme objects
Fields can carry an optional default value. Fields cannot hold other objects or lists — if you need many of something, make the variable a list of your custom type.
Custom types belong to your account: define one once and it's available in every flow, every overlay, and every variable store.
Defining a type
- Custom Types page — the full manager: create, edit, and delete types, with warnings before destructive changes.
- Flow editor → New Type — a quick-create dialog for when you're mid-flow and need a new type right away.
Type and field names must start with a letter and contain only letters, numbers, and underscores.
Using a type in flows
Once a type exists, two nodes appear in the add-node menu for it:
- Create
<Name>— one typed input per field. Wire values in, or type inline defaults for unconnected fields. Outputs the assembled object. - Break Apart
<Name>— takes the object and exposes one typed output per field. Wire only the fields you need.
The object flows along edges as its own type — a Player output only connects to Player inputs, and every Player edge shares one color.
Lists of custom objects
Every list node works with custom-object lists, and the nodes that look inside an item know its type. When a Player list is connected, they offer a Field dropdown with the type's fields (username, score, …). The field input lets a flow choose the field at runtime instead.
- Search and check: List Find (first match, its index, pass/fail), List Contains, List Filter (matching and not-matching lists). Find and Filter take a condition: equals, greater than, contains, and so on.
- Order and trim: List Sort by any field, List Take / List Skip for the first or last N, List Reverse, List Shuffle.
- Summarise: List Math (sum, average, min, max, plus the entry holding the min or max), List Tally (count each value, e.g. votes), List Unique (one entry per field value).
- Reshape: List Get Field (a list of one field's values), List To Text (chat-ready text), List Combine (append, or in both / only in first by field).
- Pick: List Random Item, optionally weighted by a number field for ticket raffles.
Static List and Emit List can hold custom-typed items too, edited in a spreadsheet.
Example: a leaderboard
Store a broadcaster variable leaderboard as a list of Player (username, score).
!addpoints: Update List Variable with Change Number Field, matchingusernameto the chatter and adding the points toscore. A new player gets an entry automatically.!top: Get the variable, List Sort byscoreHigh → Low, List Take the first 5, then List To Text with the format{{position}}. {{item.username}} ({{item.score}}), into Send Chat Message.!rank: List Sort byscore, then List Find whereusernameequals the chatter. The rank is itsindex+ 1.
Tips:
- For lists that many viewers change at once (queues, leaderboards), use a broadcaster variable and Update List Variable. A Get Variable → change → Set Variable chain can lose an entry when two chat commands run at the same moment; Update List Variable can't.
- To sort by two fields (score, then name), chain two sorts: sort by the tie-breaker first, then by the main field. Sorting keeps the existing order of equal entries.
Storing custom values
All four variable stores accept custom-typed values, as single objects or lists:
| Store | Scope | Persistence |
|---|---|---|
| Flow variables | one flow | reset each run |
| Overlay variables | one overlay | persistent |
| Broadcaster variables | your channel | persistent |
| Viewer (user) variables | per viewer | persistent |
The Get/Set variable nodes type their handles from the variable's type, so a Player-typed variable only accepts Player objects. The variable managers on the site include object editors, so you can inspect and edit stored values field by field.
In {{template}} tokens, fields of a custom-typed variable are addressable by path — {{viewer.stats.score}} reads the score field of a viewer's stats variable. A token for the whole object renders as JSON.
Editing a type
Edits apply everywhere at once — every stored value of the type is migrated for you:
- Adding a field is free: existing values gain the field's default the next time they're read.
- Renaming a field carries all stored data over to the new name, and updates the field chosen on list nodes and in Static/Emit List items. Text templates are not rewritten: a List To Text format that says
{{item.oldName}}must be edited by hand. - Changing a field's type converts stored values where possible (
42↔"42"), and falls back to the field's default where not. - Removing a field deletes that field from every stored value. This cannot be undone — the editor warns you with a count of affected flows and variables first.
Open flow editors reload automatically when a type edit rewrites their flow, so nothing is lost to a stale tab.
Deleting a type
A type can't be deleted while anything still uses it. The delete dialog lists the flows and variable stores that reference it; clear those out and delete again.