Function Scripting
This is an advanced reference. Most Loreline stories don't need custom functions at all. The Writer's Guide covers everything you need to write rich interactive fiction. This page is here for when you want to go further with computed values, complex logic, or custom utilities.
This page is a reference for the scripting syntax used inside Loreline functions. If you're new to Loreline, start with the Writer's Guide to learn about beats, choices, and state management first.
Functions in Loreline are defined with the function keyword, followed by a name, parameters in parentheses, and an indented body:
function greet(name, time)
if time < 12
return "Good morning, $name!"
else
return "Good afternoon, $name!"
The body uses a general-purpose scripting syntax covered in detail below.
Values and types
Loreline supports these value types:
// Numbers (integers and decimals)
var count = 42
var price = 3.99
var offset = -5
// Strings (double quotes)
var greeting = "Hello"
var name = "Alice"
// Booleans
var active = true
var hidden = false
// Null (represents "no value")
var result = null
// Arrays (ordered lists)
var items = [1, 2, 3]
var empty = []
// Objects (key-value maps)
var stats = { hp: 100, mp: 50 }
var blank = {}
Type coercion
Values are automatically converted in boolean context:
0,""(empty string),[](empty array),null, andfalseare falsy- Everything else is truthy
When using + with a string, the other value is converted to a string automatically:
var message = "Score: " + 42 // "Score: 42"
Use the built-in conversion functions for explicit conversion:
float(value): convert to a numberstring(value): convert to a stringbool(value): convert to a boolean
Variables
Use var to declare local variables inside a function:
function calculateTotal(price, quantity)
var subtotal = price * quantity
var tax = subtotal * 0.1
return subtotal + tax
Variables declared with var are local to the function. If you omit var, you're reading or writing a state variable instead:
state
score: 0
function addPoints(points)
var bonus = points * 2 // local variable
score += bonus // modifies the state variable
A var with no initial value defaults to null:
var result // result is null
Local variables shadow state variables of the same name:
state
x: 10
function example()
var x = 99 // local x, does not affect state
return x // returns 99
Operators
Arithmetic
var a = 10 + 3 // 13, addition
var b = 10 - 3 // 7, subtraction
var c = 10 * 3 // 30, multiplication
var d = 10 / 3 // 3.333..., division
var e = 10 % 3 // 1, remainder (modulo)
Comparison
x == y // equal
x != y // not equal
x < y // less than
x > y // greater than
x <= y // less than or equal
x >= y // greater than or equal
Logical
a && b // true if both are true
a || b // true if either is true
!a // true if a is false
You can also write and and or instead of && and ||:
if sunny and warm
return "Perfect weather!"
if raining or snowing
return "Stay inside."
Assignment
x = 10 // assign
x += 5 // add and assign (x is now 15)
x -= 3 // subtract and assign
x *= 2 // multiply and assign
x /= 4 // divide and assign
Increment and decrement
x++ // add 1 to x (postfix)
++x // add 1 to x (prefix)
x-- // subtract 1 from x
--x // subtract 1 from x
String concatenation
The + operator joins strings. Non-string values are converted automatically:
var label = "Item #" + 3 // "Item #3"
var info = name + " (" + age + ")"
String interpolation
Inside strings, $ inserts a variable's value and ${} evaluates an expression:
function formatReceipt(item, price, qty)
var total = price * qty
return "$qty x $item = $$${total}"
Field access and function calls work directly after $:
var line = "$player.name has $array_length(inventory) items"
For anything more complex, use ${}:
var summary = "Total: ${price * quantity + tax}"
var note = "Next: ${items[currentIndex + 1]}"
Control flow
if / else
function describe(temperature)
if temperature > 30
return "hot"
else if temperature > 20
return "warm"
else if temperature > 10
return "cool"
else
return "cold"
Parentheses around the condition are optional:
if (x > 0 && y > 0)
// both positive
for loops
Range loops iterate from a start value up to (but not including) an end value:
function sum(n)
var total = 0
for i in 0...n
total += i
return total
0...5 produces the values 0, 1, 2, 3, 4. Variables work too: start...end.
Array loops iterate over each element:
function findItem(inventory, target)
for item in inventory
if item == target
return true
return false
while loops
function countdown(n)
var result = ""
while n > 0
result += "$n... "
n -= 1
return result + "Go!"
do-while loops
The body runs at least once, then repeats while the condition holds:
function rollUntilSix()
var attempts = 0
do
var roll = random(1, 6)
attempts += 1
while roll != 6
return attempts
break and continue
break exits a loop immediately. continue skips to the next iteration:
function firstNegative(numbers)
for n in numbers
if n >= 0
continue
return n
return null
function sumUntilLimit(values, limit)
var total = 0
for v in values
if total + v > limit
break
total += v
return total
return
Exits the function and optionally returns a value. Without an explicit return, the function returns null:
function isEven(n)
return n % 2 == 0
function doSomething()
if !ready
return // returns null, exits early
// ... rest of the function
switch / case
Match a value against multiple cases:
function drinkPrice(drink)
switch drink
case "espresso"
return 3
case "latte"
return 5
case "cappuccino"
return 4
default
return 0
Working with arrays
Creating and accessing
var items = ["sword", "shield", "potion"]
var first = items[0] // "sword"
items[2] = "elixir" // replace "potion" with "elixir"
var count = array_length(items) // 3
Method-style calls
Array functions can be called with dot notation. These are equivalent:
array_add(items, "bow") // function style
items.add("bow") // method style
Common operations:
items.add("arrow") // append to end
items.prepend("helm") // insert at beginning
var last = items.pop() // remove and return last
var first = items.shift() // remove and return first
items.remove("shield") // remove first occurrence
var found = items.has("sword") // true if present
var pos = items.index("sword") // position, or -1
Sorting and joining:
var sorted = [3, 1, 2].sort() // [1, 2, 3]
var text = ["a", "b", "c"].join(", ") // "a, b, c"
items.reverse() // reverse in place
Calls can be chained:
var result = [3, 1, 2].sort().join(", ") // "1, 2, 3"
See the Built-in Functions: Array for the complete list.
Working with objects
Creating and accessing
var player = { name: "Alex", hp: 100, level: 1 }
var name = player.name // dot notation
var hp = player["hp"] // bracket notation
player.level = 2 // modify a property
Bracket notation is useful when the key is dynamic:
var key = "hp"
var value = player[key] // same as player.hp
Method-style calls
var keys = player.keys() // ["name", "hp", "level"]
var exists = player.has("mp") // false
player.set("mp", 50) // add a new key
player.remove("mp") // remove a key
See the Built-in Functions: Map for the complete list.
Putting it together
Here's a complete example that combines multiple features: a function that formats an inventory list with quantities and a total value:
state
inventory: ["sword", "shield", "potion", "potion", "arrow", "arrow", "arrow"]
prices: { sword: 50, shield: 35, potion: 10, arrow: 2 }
function inventorySummary()
// Count occurrences of each item
var counts = {}
for item in inventory
if counts.has(item)
counts.set(item, counts.get(item) + 1)
else
counts.set(item, 1)
// Build the summary
var lines = []
var total = 0
for name in counts.keys()
var qty = counts.get(name)
var value = prices.get(name) * qty
total += value
lines.add("$qty x $name ($$${value})")
return lines.join("\n") + "\nTotal: $$$total"
barista: Want to see what you're carrying?
$inventorySummary()
This produces:
1 x sword ($50)
1 x shield ($35)
2 x potion ($20)
3 x arrow ($6)
Total: $111