Skip to content

AST Recipes & Patterns

This page shows reusable AST patterns you can adapt into your own commands.

Wrong:

Terminal window
%(#wins 1)

Correct:

Terminal window
%(#wins *(%(#wins) + 1))
Terminal window
*(^(#wins) ? %(#wins) : 0)
  • use # or ## for temporary 24h data
  • use * or ** for permanent Premium / Pro data
  • respect plan limits
  • use $(break) if you can exit early

Use real event context for EventSub commands

Section titled “Use real event context for EventSub commands”
  • chat tests do not fully represent redemptions, cheers, raids, or subscriptions
PatternSyntax ideaPurpose
Initialize-or-increment*(^(**x) ? %(**x + 1) : %(**x 1))Smart counter
User selector%(**var(%(target)))Read or write another user’s state
Guard check*(^(**target) ? FAIL : ACT)Prevent an action if a condition exists
Side effect in ternary*(cond ? $(action) : "")Execute an action in a branch
Nested comparison*(a > b ? A_WIN : B_WIN)Multi-branch combat logic
State arithmetic%(winner *(%(winner) - %(loser)))Update stored state with math

This is one of the most common AST patterns.

Terminal window
*( ^(**escudos) ? %(**escudos *(%(**escudos) + 1)) : %(**escudos 1) ) $(user) ha comprado un escudo, ahora tiene %(**escudos) escudos

What it does:

  1. checks whether **escudos exists
  2. if yes, adds 1
  3. if no, creates it with value 1
  4. prints the final total

If the target has shields, the attack bounces. If not, the target gets banned and loses shields.

Terminal window
%(target $(reward.input))
*( ^(**escudos(%(target))) ?
$(ban.mod $(user) 300 true) "¡%(target) tiene escudos! El ataque rebotó hacia %(user)."
:
$(ban.mod %(target) 300 true)
%(**escudos(%(target)) 0)
"¡%(user) atacó y baneó a %(target)! Los escudos de %(target) se han perdido."
)

Key ideas used here:

  • store event input in a local variable
  • use a user selector to inspect another user’s data
  • perform an action inside a ternary branch
  • reset state after the action

Whoever has more shields wins. The loser is banned. The winner loses shields equal to the loser’s amount.

Terminal window
%(attacker %(user))
%(defender $(reward.input))
*( ^(**escudos(%(defender))) ?
*( ^(**escudos(%(attacker))) ?
*( %(**escudos(%(attacker))) > %(**escudos(%(defender))) ?
$(ban.mod %(defender) 300 true)
%(**escudos(%(defender)) 0)
%(**escudos(%(attacker)) *(%(**escudos(%(attacker))) - %(**escudos(%(defender)))))
"¡%(attacker) gana! %(defender) baneado. %(attacker) ahora tiene %(**escudos(%(attacker))) escudos."
:
$(ban.mod %(attacker) 300 true)
%(**escudos(%(attacker)) 0)
%(**escudos(%(defender)) *(%(**escudos(%(defender))) - %(**escudos(%(attacker)))))
"¡%(defender) gana! %(attacker) baneado. %(defender) ahora tiene %(**escudos(%(defender))) escudos."
)
: "¡%(defender) tiene escudos pero %(attacker) no tiene ninguno!"
:
$(ban.mod %(defender) 300 true)
"¡%(defender) no tiene escudos y fue baneado por %(user)!"
)

What makes this advanced:

  • nested ternaries
  • reading two users’ stored state
  • performing multiple writes in a branch
  • arithmetic updates based on previous state

When you design an advanced AST command, this order usually works best:

  1. define the input
  2. decide what state must be stored
  3. define guard checks
  4. define the success branch
  5. define the fail branch
  6. only then add side effects like bans, title changes, or triggers
  • loyalty systems
  • economy counters
  • collectible inventories
  • viewer battles
  • redemption-driven mini games
  • dynamic shoutouts
  • timed chat workflows