Bind card designs to game data
A binding replaces a fixed layer value with game data. This is how one design becomes a full deck: the layout stays the same while the current dataset row supplies the title, artwork, numbers, colours, and other values.
Assign a dataset
- Select a layer and expand Data Bindings in the inspector.
- Use Assigned dataset to choose the dataset that describes these pieces.
- Use Preview row to choose a row to show on the canvas.
- Find the field you want to drive from data.
- Choose the database button beside that field, then select a compatible column or variable.
The picker only offers compatible types. For example, a number can drive position, size, rotation, opacity, corner radius, font size, line height, padding, and stroke width. Text or colour values can drive paint fields, including effect colours and the side's background, and image or text values can drive an image source.
Text content and an image's main source also support bindings. Choose Remove binding in the picker to return the field to its fixed value.
The same panel shows the preview row's Row values, so you can correct a cell without leaving the Designer. It also has Add column, Variables, and Add variable for quick additions to the dataset and game.
Use the binding picker
The database button beside a property opens the binding picker for that property. Choose a dataset column for a value that changes by row, or a game variable for a shared value. Incompatible choices are hidden, which helps prevent a colour being assigned to a numeric field or ordinary text being used as an image by mistake.
For a calculated value, type an expression inside {{ }} directly in the field. Autocomplete appears while the cursor is inside the expression. It suggests available row and var keys, operators, and examples that fit the property. Use the arrow keys to choose a suggestion and press Enter or Tab to accept it, or click it.
Studio checks the expression while you type. Read the message below the field when a reference is missing, a function receives the wrong kind of value, or the result does not match the property. Hover a completed token to see its current value for the preview row. A valid expression can still produce an empty value for a different row, so test the difficult rows as well.
Direct bindings
Use a direct binding when the value can appear unchanged:
{{ row.title }}
{{ row.cost }}
{{ row.frame_color }}
{{ imageUrl(row.artwork) }}
row means the currently previewed dataset row. Column names are normalised into stable keys, visible in Datasets → Bindings. For example, a column named Frame Colour may be referenced as row.frame_colour.
Use var for a game variable:
{{ var.game_title }}
{{ var.brand_color }}
Variables are best for values shared across designs; row bindings are best for values that change from piece to piece.
Which names are available?
In ordinary Designer bindings, use:
row.keyfor a column in the currently previewed dataset row.var.keyfor a game variable.
The expression catalogue also describes specialised contexts such as generated tables and calculated cells. Those names only work where Studio provides that context; seeing a helper in the catalogue does not make cell, layer, or another specialist scope available in every layer property.
Expression templates
Wrap an expression in {{ and }}. Plain text can sit around expressions, so a text layer may contain:
Cost: {{ row.cost }}
Expressions can return text, numbers, booleans, colours, or image values. Use them in any compatible bound field, not only text content.
Conditions and comparisons
Use if(condition, trueValue, falseValue) to choose a result:
{{ if(row.legendary, "Legendary", "Standard") }}
{{ if(row.power >= 7, "Strong", "Starter") }}
{{ if(row.rarity == "rare", var.rare_color, row.frame_color) }}
Supported comparisons include ==, !=, >, >=, <, and <=. Combine checks with && for “and” or || for “or”:
{{ if(row.power > 4 && row.foil, "Elite foil", "Normal") }}
Quote literal text with straight quotation marks. Boolean columns can be tested directly, as in row.foil.
Fallbacks and text formatting
Use default when a cell may be empty:
{{ default(row.subtitle, "No subtitle") }}
Useful formatting helpers include:
{{ upper(row.rarity) }}
{{ title(row.faction) }}
{{ trim(row.title) }}
{{ concat(row.title, " - ", var.game_short_name) }}
{{ replace(row.title, "Dragon", "Drake") }}
For a case-insensitive text condition, normalise the value first:
{{ if(contains(lower(row.tags), "fire"), "Fire", "Other") }}
Numbers
Expressions support arithmetic and number helpers. A numeric field falls back to its fixed value if the result cannot be read as a finite number.
{{ row.base_cost + 2 }}
{{ round(row.power / 2, 1) }}
Images and colours
Use imageUrl for an image binding and imageName when text should show the image's file name:
{{ imageUrl(row.artwork) }}
{{ imageName(row.artwork) }}
{{ if(row.foil, var.foil_color, row.frame_color) }}
Build and test an expression
- Start with one working reference, such as
{{ row.title }}. - Add one helper or condition.
- Preview a row for each possible branch.
- Test empty, zero, false, and unusually long values.
- Open Expression examples in the Designer header (under More options on a phone) for the full searchable helper list.
- Check Export QA for unresolved references.
Functions such as renderVersion and random-value helpers are useful for proofs, but they can deliberately change between renders. Do not use them for a value that must stay identical across a print run or a hosted rebuild.
Renaming a column keeps its key in normal edits, but replacing a dataset creates new columns and may break existing references. Recheck every assigned design after an import or other structural replacement.
Enum values and generated variants
An Enum column can hold several selected values in one row. Each value becomes a generated variant of that row. Preview every variant: the active value can affect expressions, artwork, colour, and other bound properties.