Use the spreadsheet for calculations

The OctoMY spreadsheet lets you keep a grid of values and formulas that update automatically when their inputs change. It's useful for quick computation, sanity-checking numbers, exploring trade-offs in a sketch before committing them to code, and recording reference tables.

Pro Tip

Spreadsheet formulas use the full OctoMY expression language — the same GLSL-subset syntax that drives FACS rigs and Construct varset entries. If you can write it in one place, you can write it in the others. See the expression language reference for the complete syntax.


Opening the spreadsheet

The spreadsheet activity lives under the Hub's Development menu (look for the spreadsheet icon, or search for "Spreadsheet" in the activity launcher).

Entering values

Click a cell and type:

You type Cell behaviour
42 Stores the number 42
3.14 Stores 3.14 as a decimal
(empty) Cell value is 0
= followed by an expression The cell is a formula and evaluates that expression

The = prefix is what makes a cell a formula. Without it, the cell holds a literal value or text.

Referencing other cells

Cells are named using the standard spreadsheet convention: a column letter (A, B, …, Z, AA, AB, …) followed by a row number (1, 2, 3, …). Top-left is A1. B5 is row 5, column 2.

A1 = 5
B1 = =A1 * 3      → 15
C1 = =B1 + 1      → 16

When you change A1, both B1 and C1 update automatically — the engine tracks the dependency graph and re-evaluates only what's affected.

Examples

Simple arithmetic

A1 = 10
A2 = 20
A3 = =A1 + A2     → 30

Using built-in math

A1 = -7
B1 = =abs(A1)              → 7
C1 = =clamp(A1, 0.0, 5.0)  → 0
D1 = =sqrt(16.0)           → 4

Vector calculations

You can store and operate on vectors, and a vector cell shows every component:

A1 = =length(vec3(3.0, 4.0, 0.0))   → 5
B1 = =vec3(1.0, 2.0, 3.0)           → (1, 2, 3)
C1 = =vec3(1.0, 2.0, 3.0) * 2.0     → (2, 4, 6)

Cell types

Every cell is a float unless its formula says otherwise. You never declare a type: =vec3(0.0, A6, 0.0) makes the cell a vec3 because the formula does.

Sometimes you want the type before anything writes the formula — an input cell a slider will drive, say. Right-click the cell and pick from Cell type:

Choice Effect
Infer The default. The cell's type comes from its formula.
Float, Int, Bool Force a scalar type.
Double Force double precision — see the note below.
Vec2, Vec3, Vec4 Force a vector.

The override wraps your formula in that type's constructor, so a cell holding =A1 under a Vec3 override computes vec3(A1) — GLSL splats a single value across all three components, and the cell reads (2, 2, 2) when A1 is 2.

Select several cells first and the choice applies to all of them at once. When the selected cells disagree about their type, no entry is ticked.

Pick Infer to go back.

Note — Double is the one choice that changes the answer

Every other entry here restates a shape your formula already had. Double changes how the cell calculates.

A cell holding =0.1 + 0.2 computes in single precision and reads back 0.30000001192092896. The same cell set to Double reads 0.30000000000000004 — the answer double arithmetic gives. Neither is a rounding display: they are different numbers, and a long chain of arithmetic compounds the difference.

You can also ask for double precision inside a single formula with the lf suffix, as in =0.1lf + 0.2lf, without setting the cell's type at all. Use the cell type when the whole cell should be double; use the suffix when one constant should be.

The grid still displays a handful of digits either way. The precision is in the value, not in what you can see — which is why this is worth reaching for when a displayed result looks right and a later calculation built on it does not.

Values from the previous frame

prev(A1) reads what A1 held on the previous frame rather than this one, which is what lets a sheet accumulate or oscillate without the engine calling it a circular reference:

A1 = 1
B1 = =prev(B1) + A1     → 1, then 2, then 3, … one per frame

A frame advances when the sheet is told to advance, not on every keystroke — otherwise =prev(B1)+1 would count your edits, which is a different feature and a surprising one.

Conditional logic

The ternary operator is the most compact way to express a conditional:

A1 = 25
B1 = =A1 > 18 ? 1.0 : 0.0     → 1

For longer logic, you can also define helper functions inline:

A1 = 5
B1 = =float maxClamp(float x) { return clamp(x, 0.0, 4.0); } maxClamp(A1)   → 4

What if I make a mistake?

A cell that will not compile reads #ERROR! instead of a value. Hover it and the tooltip says why, naming that cell rather than the sheet:

You typed What went wrong
=A1 + Missing right-hand side of the + operator
=undefinedThing + 1 Cell or function name not found

Fix the formula and the dependent cells re-evaluate immediately.

Results that are not numbers

Arithmetic that compiles can still produce a value with no meaning, and those read as errors in the cell rather than as digits:

Cell shows What happened
#DIV/0! The result is infinite — most often a division by zero
#NUM! The result is "not a number", such as 0.0 / 0.0 or inf - inf

Division by zero follows the IEEE rule the graphics hardware uses, so =1.0/0.0 is infinity and displays as #DIV/0!. It is the same answer on every path your sheet can be evaluated on, which is what makes it safe to build on: a formula that reads #DIV/0! in the grid does not quietly become a zero somewhere else.

Note

These are read from the value, not carried from the cause. 1e38 * 1e38 also overflows to infinity without any division in it, so #DIV/0! is the best available reading of an infinite result rather than a statement about how it got there.

Circular dependencies

If A1 = =B1 and B1 = =A1, the engine detects the cycle at compile time and surfaces an error naming the full path (A1 → B1 → A1). Every cell on the loop is marked, because a circular reference is a property of the set rather than of any one of them. Nothing evaluates until you break the cycle by changing one of the cells.

If what you wanted was a cell that reads its own last value — a counter, a running total, a smoothed signal — that is not a cycle and has its own spelling: see previous-frame values.

Known limitations

  • The grid is sized at activity startup. A sheet of a few hundred formulas recompiles faster than you can type the next character; several thousand starts to be noticeable. See fast formulas for what the recompile actually costs and why reopening an unchanged sheet is much quicker than the first compile.
  • Matrix-valued cells (mat3, mat4) compute but have no display form yet, so prefer vectors for anything you want to read in the grid.

See also