Skip to content
Guides— browse docs
On this page

Formulas

Calculated columns in a Table — spreadsheet formulas over your world's data.

A Table column can be a calculation: a formula that reads the other columns in the same row and produces a number, a percentage or a piece of text. It is a spreadsheet formula — the same functions, the same syntax — over your cards.

The one you probably came for

You have Base XP, a Multiplier and a Difficulty, you want them multiplied together and rounded up, and you want to call it Final XP:

=CEILING(@[Base XP] * @[Multiplier] * @[Difficulty], 1)
Base XPMultiplierDifficultyFinal XP
1001.51.2180
2501.10.9248
4021.75140

Set the column's result type to Whole number and you are done. Every card of that type now carries Final XP, and you can read it on the card itself.

Writing one

  1. Open a Table and press + Add Property.
  2. Choose Calculation at the bottom of the list.
  3. Name it, then write the formula in the bar that opens.
  4. Click a column heading while the bar is open to insert that column's token at your cursor — quicker and safer than typing the name.

Formulas start with =. Press Enter to save, Escape to cancel. Cancelling a brand-new calculation removes the column again.

Referring to columns

You writeIt means
@[Price]the Price cell in this row
@[Level Bonus]a column whose name has a space — the brackets are why
@[Price] * 2arithmetic on this row's value

Renaming a column does not break your formulas. References are stored by the column's identity, not its name, so the formula bar simply shows the new name the next time you open it.

What you can use

The full spreadsheet function library. The ones that come up most:

Numbers

=ROUND(@[Price] * 1.08, 2)        rounds to 2 decimal places
=CEILING(@[XP] * 1.5, 1)          always rounds UP to a whole number
=FLOOR(@[XP] * 1.5, 1)            always rounds DOWN
=ABS(@[Delta])                    magnitude, sign discarded
=MIN(@[Cost], 100)                cap a value
=MAX(@[Cost], 0)                  floor a value
=@[Total] / @[Count]              plain arithmetic: + - * / ^

Decisions

=IF(@[HP] <= 0, "Defeated", "Alive")
=IF(@[Level] > 10, @[Base] * 2, @[Base])
=IFS(@[Tier] = 1, "Bronze", @[Tier] = 2, "Silver", TRUE, "Gold")

Text

=CONCATENATE(@[First], " ", @[Last])
=UPPER(@[Code])
=LEN(@[Description])
=TRIM(@[Name])

Across the whole column

A reference without the @ means the entire column, so you can compare a row to its table:

=@[Price] / SUM(Price)            this row's share of the total
=@[Score] - AVERAGE(Score)        distance from the mean
=COUNT(Price)                     how many rows have a price

Result types

Pick the type when you create the column; it decides how the answer is rendered and what an invalid answer looks like.

TypeRenders asUse for
Whole number180counts, XP, levels
Decimal12.45money, weights, rates
Percent16.37%shares of a total
TextDefeatedlabels from IF

If a formula returns something the type cannot hold — text where a number is expected — the cell shows #VALUE! rather than guessing.

When something is wrong

The cell shows the spreadsheet error, not a blank:

ErrorMeans
#VALUE!the answer is the wrong shape for the column's result type
#DIV/0!divided by zero, or by an empty cell
#NAME?a function name that does not exist
#REF!a column the formula referred to has been deleted
#CALC!the engine could not finish — usually a transient load failure

Calculated properties on the card

A calculation does not have to live in a Table at all. Open World info → Types → your type, click a property, and fill in Calculate:

@[Price] * @[Rarity]

That property is now computed for every card of that type — in the card editor, in a Table, in the wiki, on a published site, and for anything reading your world over the API. Nothing has to be open for it to be right.

You write property names; vvd stores the reference by identity. Rename Price to Cost and every formula keeps working, with no card rewritten.

Calculations can use other calculations

A calculated property can read another one:

Subtotal = @[Price] * @[Quantity]
Total    = @[Subtotal] * @[Tax]

vvd works out the order for you. If two properties end up depending on each other, both show #CIRCULAR! and everything else keeps computing — so you can fix it without the tool fighting you halfway through an edit.

From a Table column to a card property

A Table calculation that only reads its own row becomes a property of the card type automatically when you save it — that is what makes it durable.

A calculation that reads a whole column (SUM, AVERAGE, "share of the total") stays in the Table, because it is a question about a set of rows rather than a fact about one card.

Speed

A calculated property is arithmetic over one row, so vvd simply computes it — every render, everywhere. Editing Price updates Total in the same frame, with no network call and no formula engine loaded. 1,000 cards with three calculated properties each project in about 14 ms.

Cross-row Table calculations are different: those results are stored in the Table, so the column paints instantly when you open it and offline, and the engine only runs when the inputs actually change. While a recalculation is in flight the previous answer stays on screen, so you never see a blank where a number used to be.

Limits

  • Formulas read the current row. Reading a value from a different card — or from another Table — is not supported yet.
  • A calculated property cannot be typed into, in the Table or on the card.
  • An input you have not filled in yet leaves the result empty, not 0 — a zero total looks like a real answer.
  • Sorting, filtering and grouping all work on calculated columns, and CSV export includes them.