A list is an ordered collection of values, and Skript's syntax for one is the humblest possible: values separated by commas.
set channels to "whatsapp", "email", "sms" log "we have channels"
▶ example.skript — Skode Skript · local simulation ● event: script → name: Demo ✎ set channels → = ["whatsapp", "email", "sms"] • log → we have channels ✔ done in 2.1ms
Look at the set line in the trace: the stored value is shown in square brackets, ["whatsapp", "email", "sms"] — that is how traces render lists, though your program never writes brackets itself. A list can hold any mix of values: set oddities to 1, "two", true is legal, if rarely wise.
Doing something with each item
The whole point of a list is the for each loop, which runs its indented body once per item, making the item available under a name you choose:
set channels to "whatsapp", "email", "sms" for each ch in channels log "notifying via {ch}"
▶ example.skript — Skode Skript · local simulation ● event: script → name: Demo ✎ set channels → = ["whatsapp", "email", "sms"] ↻ for each ch in ["whatsapp", "email", "sms"] → 3 items • log → notifying via whatsapp • log → notifying via email • log → notifying via sms ✔ done in 2.1ms
The loop variable (ch here) is an ordinary variable — created by the loop, visible in interpolations and conditions, and still holding the final item after the loop ends. The trace announces the loop once, with the list and its size, then shows each iteration's steps in order.
You can also loop over a list literal directly, without naming it first — pleasant for small fixed sets:
for each vip in "Meera", "Tomas" log "reserved a seat for {vip}"
▶ example.skript — Skode Skript · local simulation ● event: script → name: Demo ↻ for each vip in ["Meera", "Tomas"] → 2 items • log → reserved a seat for Meera • log → reserved a seat for Tomas ✔ done in 2.1ms
Growing a list
add … to … — the type-smart sentence from Chapter 5 — pushes onto a list when its target is one:
set queue to "first", "second" add "third" to queue for each item in queue log "processing {item}"
▶ example.skript — Skode Skript · local simulation ● event: script → name: Demo ✎ set queue → = ["first", "second"] ✎ add to queue → "third" → now 3 items ↻ for each item in ["first", "second", "third"] → 3 items • log → processing first • log → processing second • log → processing third ✔ done in 2.1ms
The trace line for a list-add reports the new length, so you can watch a queue grow. Note that a list must start as a list — add to a name that is not one falls back to the scalar behaviours of Chapter 5. The companion idiom for collecting results in a loop is therefore the summary string, which grows by appending:
set matched to "" for each candidate in "Ada", "Grace", "Linus" if candidate contains "a" then add "{candidate} " to matched log "matched: {matched}"
▶ example.skript — Skode Skript · local simulation ● event: script → name: Demo ✎ set matched → = "" ↻ for each candidate in ["Ada", "Grace", "Linus"] → 3 items ✓ if candidate contains "a" → yes ✎ add to matched → = "Ada " ✓ if candidate contains "a" → yes ✎ add to matched → = "Ada Grace " ✗ if candidate contains "a" → no • log → matched: Ada Grace ✔ done in 2.1ms
(That example sneaks in contains, a condition you will meet formally in the next chapter — note it is case-insensitive, which is why both Ada and Grace matched.)
What lists are for — and not for
In an automation language, lists mostly carry plans: channels to try, tags to apply, teammates to notify, steps to log. They are short, they are built and consumed inside a single run, and for each is almost always the only tool you need.
What Skript lists are not is a database. There is no indexing (the 3rd item of…), no sorting, no removal, no searching beyond contains — and that is intentional. The moment your logic wants those operations, the data belongs in Skode itself (a segment, a view, a module) and your skript should be the thing that reacts to it, not the thing that stores it. Keeping lists primitive keeps programs sentence-shaped, and sentence-shaped programs are the ones your whole team can still read in a year.
With values, variables and lists in hand, it is time for the machinery that gives a program a mind of its own: conditions and loops, in full.