Collect
In Goblin, collect evaluates an expression repeatedly and returns the results as an array. It is useful whenever you need to generate a list of values, objects, strings, rolls, or function results.
Usage
What you write
numbers | collect 5 of roll 1d6
numbers | collect 5 of roll 1d6
What it does
Goblin evaluates the expression 5 times and places each result into an array.
Example result:
[4, 1, 6, 3, 2]
[4, 1, 6, 3, 2]
Each evaluation is independent.
Function Form
Collect can also be called like a normal function:
numbers | collect(5, roll 1d6)
numbers | collect(5, roll 1d6)
This is equivalent to:
numbers | collect 5 of roll 1d6
numbers | collect 5 of roll 1d6
Use whichever style is more readable in the surrounding code.
Common Examples
Random Numbers
rolls | collect 10 of roll 1d20
rolls | collect 10 of roll 1d20
Possible result:
[7, 14, 2, 19, 5, 11, 1, 20, 8, 4]
[7, 14, 2, 19, 5, 11, 1, 20, 8, 4]
Calling an Action
sentences | collect 5 of goblin_ipsum_sentence()
sentences | collect 5 of goblin_ipsum_sentence()
Produces:
[ "Goblin words here.", "Another sentence here.", "More goblin words.", ... ]
[ "Goblin words here.", "Another sentence here.", "More goblin words.", ... ]
Creating Objects
soldiers | collect 100 of Soldier()
soldiers | collect 100 of Soldier()
Produces an array containing 100 newly-created Soldier objects. Each object is independently constructed and fully initialized — collect does not copy, it evaluates fresh each time.
The Long Way
Before collect, the same operation required manually building the array.
sentences | [] repeat 5 s | goblin_ipsum_sentence() put_last!(sentences, s) xx
sentences | [] repeat 5 s | goblin_ipsum_sentence() put_last!(sentences, s) xx
This works perfectly fine.
However, the intent is:
Run this thing 5 times and collect the results.
So Goblin allows:
sentences | collect 5 of goblin_ipsum_sentence()
sentences | collect 5 of goblin_ipsum_sentence()
The loop still happens. Collect simply removes the plumbing.
How It Differs From Pack and Unpack
Collect and Pack are related but solve different problems.
Pack
Pack takes an array and collapses it into a single value.
digits | [1, 2, 3, 4, 5] number | :pack(digits)
digits | [1, 2, 3, 4, 5] number | :pack(digits)
Result:
12345
letters | ["g", "o", "b", "l", "i", "n"] word | :pack(letters)
letters | ["g", "o", "b", "l", "i", "n"] word | :pack(letters)
Result:
"goblin"
An array of digits becomes a number. An array of characters becomes a string.
Unpack
Unpack is the inverse — it splits a single value back into an array.
digits | :unpack(12345) /// → [1, 2, 3, 4, 5] chars | :unpack("goblin") /// → ["g", "o", "b", "l", "i", "n"]
digits | :unpack(12345) /// → [1, 2, 3, 4, 5] chars | :unpack("goblin") /// → ["g", "o", "b", "l", "i", "n"]
Collect
Collect generates new values by repeatedly evaluating an expression.
rolls | collect 5 of roll 1d6 /// → [4, 1, 6, 3, 2]
rolls | collect 5 of roll 1d6 /// → [4, 1, 6, 3, 2]
Rule of Thumb
If you need to collapse an array into one value — pack. If you need to split one value into an array — unpack. If you need to generate an array from scratch — collect.
Comparison With Other Languages
Python
sentences = [] for _ in range(5): sentences.append(goblin_ipsum_sentence())
sentences = [] for _ in range(5): sentences.append(goblin_ipsum_sentence())
More commonly:
sentences = [ goblin_ipsum_sentence() for _ in range(5) ]
sentences = [ goblin_ipsum_sentence() for _ in range(5) ]
JavaScript
const sentences = Array.from( { length: 5 }, () => goblinIpsumSentence() );
const sentences = Array.from( { length: 5 }, () => goblinIpsumSentence() );
Ruby
sentences = 5.times.map do goblin_ipsum_sentence() end
sentences = 5.times.map do goblin_ipsum_sentence() end
Goblin
sentences | collect 5 of goblin_ipsum_sentence()
sentences | collect 5 of goblin_ipsum_sentence()
Goblin names the operation directly. You are collecting results from repeated evaluation.
Why This Exists
Building arrays by repeatedly evaluating something is an extremely common operation. Without collect, every use requires creating an empty array, running a loop, generating a value, appending it, and returning the array.
Collect expresses the intent directly:
Evaluate this N times and give me the results.
The underlying loop still exists, but the programmer no longer has to write it.