Show Twitch prediction events in OBS
Display a prediction announcement, animate the final percentages when entries lock, and reuse the message card when the prediction ends.
AlphaResult
This guide adds three OBS reactions to the prediction workflow from the previous guide:
- Prediction Begin shows a five-second message card with the prediction title.
- Prediction Lock shows the title, both outcomes, their final percentages, and two proportional color bars.
- Prediction End reuses the message card to announce the result.
Before you start
Complete Control a Twitch prediction from Stream Deck first. This guide assumes you already know how to:
- connect Twitch and OBS;
- create automations and select signals;
- add and configure actions;
- create OBS Slots and bind them to OBS sources;
- inspect signal contracts in Encyclopedia.
The downloaded folder contains the three automations. OBS scenes, sources, Slots, and Bindings are project-specific and must be created separately.
Step 1. Build the overlay scene in OBS
Create an OBS scene named:
Prediction-Overlay
Add Prediction-Overlay to each OBS scene where viewers should see prediction notifications. Place it above the scene's other sources so the overlay remains visible as the top layer.
Add the following sources:
Prediction-TitleOption-1Option-2Option-1-PercentOption-2-PercentPrediction-Color-1Prediction-Color-2- a group named
Message
Inside the Message group, add:
Message-TitleMessage-BodyMessage-Background
Prediction-Color-1 and Prediction-Color-2 should begin at the same size. The recommended size used by this example is:
600 × 60 px
The 600 × 60 px dimensions are not required. Streaming Hub changes the bars proportionally through Scale X, not by assigning absolute pixel widths. You can use another initial size as long as both color sources have the same width and height.
Step 2. Design the reusable message card
Use the Message group for both the beginning and ending announcements. Style its background and two text sources so the same card can display:
- a short status in
Message-Title; - the prediction title or result in
Message-Body.
Keep the group hidden by default. The automations show it for five seconds and hide it again.
Step 3. Create the OBS Slots
In Streaming Hub, create seven Text Slots:
| Text Slot |
|---|
Option-2-Percent |
Option-1-Percent |
Option-2 |
Option-1 |
Prediction-Title |
Message-Title |
Message-Body |
Create eight Source Slots:
| Source Slot |
|---|
Prediction-Color-2 |
Prediction-Color-1 |
Message |
Option-2-Percent |
Option-1-Percent |
Option-2 |
Option-1 |
Prediction-Title |
Some OBS items need two Slots because the automations perform two different operations:
- a Text Slot changes the displayed text;
- a Source Slot shows or hides the item.
Bind every Slot to the OBS source with the matching name.
Step 4. Add the three Twitch signals
Create three automations:
| Automation | Twitch signal |
|---|---|
Prediction Begin Message | Prediction Begin |
Prediction Lock Animation | Prediction Lock |
Prediction End Message | Prediction End |
The signal contracts provide the prediction title, outcomes, Channel Points, and result data under:
event.contract.twitch.prediction
Step 5. Announce the beginning of a prediction
In Prediction Begin Message, add:
- OBS Source Set Text
- OBS Source Set Text
- OBS Source Show
- Core Pause
- OBS Source Hide
Configure them as follows:
| Action | Slot | Value |
|---|---|---|
| Source Set Text | Message-Title | Prediction has begun! |
| Source Set Text | Message-Body | {event.contract.twitch.prediction.title} |
| Source Show | Message | — |
| Pause | — | 5 Seconds |
| Source Hide | Message | — |
When Twitch creates a prediction, OBS displays the reusable card with its title and hides it after five seconds.
Step 6. Populate the locked prediction
In Prediction Lock Animation, first update the text sources:
| Text Slot | Text |
|---|---|
Prediction-Title | {event.contract.twitch.prediction.title} |
Option-1 | {event.contract.twitch.prediction.outcomes[0].title} |
Option-2 | {event.contract.twitch.prediction.outcomes[1].title} |
Option-1-Percent and Option-2-Percent | 0% |
Add the first OBS Source Show action:
| Action | Source Slots |
|---|---|
| Source Show | Prediction-Title, Option-1, Option-2 |
This makes the prediction title and outcome names visible before the percentage calculation and number animation begin. The percentage sources and color bars remain hidden until their final values have been prepared.
The example expects two displayed outcomes. Twitch may support more outcomes, but the OBS layout and the percentage calculation shown here contain two bars.
Step 7. Calculate the total Channel Points
Initialize the total before entering the loop:
| Field | Value |
|---|---|
| Action | Math Number Operate |
| Target Path | runtime.channelPointsTotal |
| Expression | 0 |
Add Core For Each:
| Field | Value |
|---|---|
| Source Type | Variable |
| Source Path | event.contract.twitch.prediction.outcomes |
| Item Variable | item |
| Index Variable | i |
Inside the loop, add Math Number Operate:
| Field | Value |
|---|---|
| Target Path | runtime.channelPointsTotal |
| Expression | {runtime.channelPointsTotal}+{item.channelPoints} |
Initializing the Runtime value is essential. Without the 0 step, the first addition contains an unresolved path and the later percentage values cannot be calculated.
Step 8. Calculate the percentages and bar scales
After the loop, add four Math Number Operate actions:
| Target Path | Expression |
|---|---|
runtime.option1percent | Round((100*{event.contract.twitch.prediction.outcomes[0].channelPoints})/{runtime.channelPointsTotal}) |
runtime.option2percent | 100-{runtime.option1percent} |
runtime.width1 | {runtime.option1percent}/100 |
runtime.width2 | {runtime.option2percent}/100 |
The first percentage is rounded to a whole number. The second is calculated as the remainder, so the displayed values always total 100%.
Scale X in OBS WebSocket is a multiplier, not a pixel width:
1.0means the source's original width;0.5means half of its original width;0.25means one quarter of its original width.
Because both color sources begin at 600 px, percentages such as 68% and 32% use Scale X values 0.68 and 0.32.
Add two OBS Source Set Transform actions:
| Source Slot | Scale X |
|---|---|
Prediction-Color-1 | {runtime.width1} |
Prediction-Color-2 | {runtime.width2} |
After both Set Transform actions, add the second OBS Source Show action:
| Action | Source Slots |
|---|---|
| Source Show | Option-1-Percent, Option-2-Percent, Prediction-Color-1, Prediction-Color-2 |
This reveals the two percentage labels and their already-scaled color bars immediately before the changing-number animation starts.
Step 9. Animate the percentage numbers
Add Core Repeat:
| Field | Value |
|---|---|
| Count | 20 |
| Index Variable | i |
| Delay Between Iterations | 40 ms |
Inside Repeat, add Math Random:
| Field | Value |
|---|---|
| Mode | Integer |
| Target Path | vars.random |
| Minimum | 0 |
| Maximum | 100 |
Then add OBS Source Set Text for both percentage Text Slots:
{vars.random}%
After Repeat, set the actual final values:
| Text Slot | Text |
|---|---|
Option-1-Percent | {runtime.option1percent}% |
Option-2-Percent | {runtime.option2percent}% |
Repeat is not required for the calculation. It creates the fast-changing number effect shown in the video and demonstrates how the same action block can run several times.
Pause for 10 Seconds, then hide the prediction title, outcomes, percentages, and both color bars.
Step 10. Reuse the card when the prediction ends
Prediction End Message uses the same Message group as the beginning animation. The quickest way to create it is to copy the complete Prediction Begin Message automation, rename the copy, and change its signal to Twitch Prediction End.
The copied actions already contain the correct Message-Title and Message-Body Slots, Source Show, five-second Pause, and Source Hide. Add the result-selection actions before the two Source Set Text actions, then change only the displayed text.
First add Math Number Operate:
| Field | Value |
|---|---|
| Target Path | runtime.winPoints |
| Expression | 0 |
Then add Core For Each:
| Field | Value |
|---|---|
| Source Type | Variable |
| Source Path | event.contract.twitch.prediction.outcomes |
| Item Variable | item |
| Index Variable | i |
| Delay Between Iterations | 0 |
Inside For Each, add Core Set Variable:
| Field | Value |
|---|---|
| Target Path | runtime.winner |
| Value Template | {item.title} |
| Advanced run condition | {item.channelPoints}>={runtime.winPoints} |
The exported example uses this loop to select an outcome title and stores it in runtime.winner.
After the loop, adapt the two copied Source Set Text actions:
| Action | Text Slot | Text |
|---|---|---|
| Source Set Text | Message-Title | Prediction resolved! |
| Source Set Text | Message-Body | We're got it! We did {runtime.winner} |
Keep the remaining copied actions:
| Action | Setting |
|---|---|
| Source Show | Source Slot Message |
| Pause | 5 Seconds |
| Source Hide | Source Slot Message |
The complete order is therefore:
- Number Operate — initialize the comparison value.
- For Each — inspect the prediction outcomes and store a title.
- Source Set Text — update
Message-Title. - Source Set Text — update
Message-Body. - Source Show — reveal
Message. - Pause — keep it visible for five seconds.
- Source Hide — remove the card.
The configured body text in the export is:
We're got it! We did {runtime.winner}
Replace it with copy that matches your stream, for example:
The result is {runtime.winner}!
Verify the complete workflow
The fastest way to check the layout is to run all three automations manually, as shown in the video:
- Test
Prediction Begin Messageand confirm the card appears for five seconds. - Test
Prediction Lock Animationwith a preset containing Channel Points for both outcomes. - Confirm that both displayed percentages total
100%. - Confirm that the two bars use the same original width and are scaled proportionally.
- Confirm that the temporary random percentages are replaced by the final values.
- Test
Prediction End Messageand confirm that it reuses the card.
After manual testing, create, lock, and resolve a real Twitch prediction. The corresponding Twitch signals should start the same automations without manual input.
If it does not work
- An automation does not start from Twitch: confirm that the selected signal is Begin, Lock, or End and reconnect the broadcaster account.
- OBS text does not update: verify the Text Slot Binding. A Source Slot can show an item but cannot replace its text.
- An item remains hidden: bind its separate Source Slot and include it in the matching Source Show action.
- The percentage calculation fails: initialize
runtime.channelPointsTotalto0before For Each and confirm that every outcome containschannelPoints. - Scale X does not resolve to a number: confirm that all preceding Number Operate actions completed and that Set Transform receives
{runtime.width1}or{runtime.width2}. - A bar becomes enormous: pass a multiplier such as
0.68, not a pixel width such as408. - The bars do not match the displayed percentages: ensure that both original OBS color sources have the same width and have not already been scaled differently.
- The resolved outcome is incorrect: use
winningOutcomeIdrather than inferring the winner from Channel Points or array order.
Adapt it
- Use Twitch Prediction Progress to update the percentages and bars in real time while entries are still open.
- Replace the random-number Repeat with a shorter or longer animation.
- Put animation durations and Repeat count in Number variables.
- Add more outcome text and bar sources for predictions with more than two outcomes.
- Reuse the For Each total calculation for Twitch Poll choices.
- Add sounds, filters, or transitions when a prediction starts, locks, or ends.
- Turn the message group into a shared OBS component used by polls, goals, raids, and donations.
Related
Download the ready-made script
Import it into Streaming Hub, then follow this guide to add your own variables and connect the required services.
Download the prediction animation folder