Expressions

console expressions tui

Expressions

There are two expression evaluators in play when you debug a table, and it saves confusion to keep them apart:

Where it runsWhat it does
Console evaluatorThe eval command and watched expressionsA compact calculator over the variables in your debug session
Scoring evaluatorExpression fields in your .cade filesThe full language your table actually scores with

The first half of this page covers what you can type at the prompt. The second half is the complete function reference for scoring expressions.

Part 1 — The eval Command

Variable References

Reference a variable by the name you gave it, written bare — no ${...} wrapper:

cade:debug> set var.score 1000
Set var.score = 1000 for player 1

cade:debug> eval var.score * 2
Expression: "var.score * 2"
Variables:
  var.score = 1000
  (use var.<name> to reference variables in expressions)
Result: 2000

The name in eval must match the name you used in set. Dotted names work as expected:

cade:debug> set var.bonus.multiplier 3
cade:debug> eval var.bonus.multiplier * 500
Result: 1500

Prefer the var. prefix. It is what the console itself suggests, and it matches how variables are written in .cade files, so you keep one habit.

Migrating from ${...}: older debug scripts wrapped references as ${var.score}. The console still accepts that form, but bare is canonical — and in .cade files ${...} is a hard parse error.

Variables resolve against the current debug session. Use player to switch player context before evaluating.

Values

KindExamples
Numbers100, -5, 2.5
Booleanstrue, false
Strings"multiball" (double quotes required)

Operators

Arithmetic+, -, *, /, %. Unary + and - are supported.

Comparison==, !=, <, <=, >, >=.

Logical&&, ||, !.

Parentheses group subexpressions: eval (var.base + var.bonus) * var.multiplier.

Functions

The console evaluator provides three numeric functions:

FunctionDescriptionExample
min(a, b, ...)Smallest of two or more valuesmin(var.score, 10000)
max(a, b, ...)Largest of two or more valuesmax(var.bonus, 0)
abs(x)Absolute valueabs(var.delta)

min and max take two or more arguments; abs takes exactly one. All require numeric arguments.

Not Available at the Prompt

These are valid in .cade scoring expressions but not in eval:

  • Ternary (cond ? a : b)
  • Exponentiation — use pow in scoring expressions
  • The math functions beyond min/max/absround, floor, ceil, clamp, sqrt, pow
  • String and list functions (string.to_upper, list.length, …)
  • Module state (module.<name>.active)

To exercise those, put them in a .cade scoring expression and trigger the event that runs it, then read the computed value off the cascade viewer.

Examples

cade:debug> eval 100 + 50
Result: 150

cade:debug> eval (var.base_score + var.bonus) * var.multiplier
Result: 7500

cade:debug> eval var.score > 1000 && var.multiball.active
Result: false

cade:debug> eval max(var.score, var.high_score)
Result: 15000

Watched Expressions

watch accepts an expression, not just a plain variable name, and re-evaluates it as game state changes:

cade:debug> watch var.score
Now watching variable: var.score

cade:debug> watch var.score > 1000
Now watching expression: var.score > 1000

cade:debug> unwatch var.score
Stopped watching variable: var.score

The operator and function rules above apply. An expression that cannot be evaluated — usually because a variable is not set yet — reports its error instead of a value, and starts working as soon as the variable exists.

Watched variables and expressions survive a config hot reload. See Configuration.

Part 2 — Scoring Expression Functions

These functions are available in expression fields in your .cade files, evaluated by the scoring engine. For syntax, quoting rules, and worked examples, see Writing Expressions.

Math

FunctionDescription
min(a, b)Smaller of two values
max(a, b)Larger of two values
abs(x)Absolute value
round(x)Round to the nearest integer
floor(x)Round down
ceil(x)Round up
clamp(x, lo, hi)Constrain x to the range lohi
sqrt(x)Square root
pow(x, y)x raised to the power y

For deterministic randomness — noise, random_range, weighted_choice and friends — see the Noise Generator.

String

FunctionDescription
string.length(s)Number of characters
string.concat(s1, s2, ...)Concatenate two or more strings
string.contains(s, sub)true if s contains sub
string.substring(s, start, len)len characters starting at start (0-based)
string.to_upper(s)Convert to uppercase
string.to_lower(s)Convert to lowercase
string.trim(s)Remove leading and trailing whitespace
string.replace(s, old, new)Replace all occurrences of old with new
string.matches(s, pattern)true if s matches the regular expression pattern
string.split(s, delim)Split s on delim, returning a list
string.join(list, delim)Join a list of strings with delim
string.to_int(s)Parse s as an integer
string.to_bool(s)Parse s as a boolean
string.from_int(i)Convert an integer to a string
string.from_bool(b)Convert a boolean to "true" or "false"

List

Lists are ordered and zero-indexed. Functions that return a modified list always return a new one — existing lists are never mutated.

Inspection

FunctionDescription
list.length(list)Number of elements
list.empty(list)true if the list has no elements
list.contains(list, elem)true if elem is present
list.index_of(list, elem)Index of the first occurrence, or -1

Access

FunctionDescription
list.first(list)First element
list.last(list)Last element
list.get(list, index)Element at index
list.slice(list, start, end)Sublist from start to end (exclusive)
list.random(list)A random element

Modification

FunctionDescription
list.append(list, elem)New list with elem added at the end
list.prepend(list, elem)New list with elem added at the beginning
list.insert(list, index, elem)New list with elem inserted at index
list.remove(list, elem)New list with the first occurrence of elem removed
list.remove_at(list, index)New list with the element at index removed
list.reverse(list)New list in reverse order
list.sort(list)New list in ascending order
list.shuffle(list)New list in random order
list.unique(list)New list with duplicates removed (first occurrence kept)

Construction and Set Operations

FunctionDescription
list.from_element(elem)Single-element list
list.concat(list1, list2)New list combining both
list.join(list, delim)Join a list of strings with delim
list.difference(list1, list2)Elements in list1 not present in list2
list.intersection(list1, list2)Elements present in both lists

Module Namespace

Scoring expressions can query module state through the module namespace:

ExpressionReturnsDescription
module.<name>.activeBooleanWhether the module’s mode is currently active
module.<name>.instance_countIntegerNumber of active instances (for stackable modules)
module.<name>.<variable>ValueA module-scoped variable

Module variables are registered under both their qualified name (module.<moduleName>.<varName>) and a short name (<varName>). If two modules define the same short name, a collision warning is logged and only the qualified name resolves.