Conditional Content

Conditional content

A Conditional content brick (type CONDITIONAL) makes a lesson adapt to the learner. It groups bricks into branches, and each branch has a condition about what the learner did in a simulation of the same content: how many points they scored, which ending they reached, a variable the simulation keeps. The learner sees the bricks of the first branch whose condition is met; if none is, they see the bricks of the final branch, Otherwise.

Typical uses: a reinforcement text only for those who ended badly, a congratulation for those who reached the best ending, a different next step depending on a decision.

What you need first

Conditions read simulations, so the content needs at least one:

  1. An Embed code brick with an uploaded package that sends progress or a result.
  2. A simulation identifier on that brick, unique in the content (lowercase letters, digits and _, starting with a letter, for example sim_u1). The condition refers to the simulation by this identifier.
  3. That simulation must sit outside any branch. A simulation inside a branch cannot be named, and it cannot be marked as Scored either (it would be hidden and never finish).

Building it in the editor

Creating the brick

In the brick insertion sheet, Conditional content is in the Structure family. It starts with one empty condition branch, which does not hold until you write its condition, and the Otherwise branch. It is not offered from the insertion point of a branch (there is only one level), nor in the exam or bank editor.

The frame and its branches

On the canvas, the brick is a frame. At the top it shows the Conditional content tag and, branch by branch, a plain-words summary of the condition ("Branch 1: shown if sim_u1.trust is at least 3"). Below there is one zone per branch: the condition branches in their order and Otherwise last, each with its tag (Branch 1, Branch 2…, Otherwise) and its bricks.

  • Add a branch, at the foot of the frame, adds a condition branch (up to 10).
  • The header of each condition branch has buttons to move it up, move it down and remove it. Reordering changes which branch is checked first; no brick changes branch.
  • Removing an empty branch just removes it. If it has bricks, the editor asks: Remove with its blocks or Keep the blocks, which stay in the lesson right after the conditional content and are always visible (they never move to another branch).
  • An empty branch shows "This branch has no blocks yet" and an Add a block button. Each branch also has its own insertion point.

Putting bricks in and taking them out

  • By dragging: drop a brick on a brick of a branch to put it in its place, or on a branch's zone (empty ones too) to put it at the end. Dragging the frame moves the conditional content with all its branches.
  • Without dragging (with the keyboard or on narrow screens): in the brick's toolbar, Move to… lists every branch of every conditional content in the lesson (numbered when there are several) and, from a branch, Out of the conditional, which leaves the brick right after it. The brick goes in at the end of the branch.
  • Move up and Move down move a brick within its branch. Bricks in a branch are numbered per branch: "Actions for block 2 in branch 1".

Deleting, duplicating and templates

  • Delete the brick on a conditional content with bricks asks: Delete with its blocks or Keep the blocks (they stay in the lesson, in place and always visible). Both can be undone with Undo.
  • Duplicate the brick duplicates the conditional content with all its branches and bricks. A brick duplicated inside a branch stays in that branch.
  • When you choose bricks for a template or for AI, the conditional content brings its bricks along; a brick in a branch cannot be chosen on its own. A template you paste from a branch goes into that branch.

The condition of each branch

Edit the brick opens the conditional content's panel, with one section per condition branch:

  • The Condition of branch N field, where you write the condition (see "Writing a condition" below). If it cannot be understood, the reason and the character where it stopped appear below it, for example "Unexpected “)” at character 12"; if it can, the plain-words summary, the same one as in the frame's header.
  • The warnings for that branch (see "Warnings" below).
  • An assistant that writes it for you. Choose the Simulation (those in this lesson and in the other lessons of the content that are outside every branch), the Variable (the ones its package declares, with their type, and the result ones: grade, score, maxScore, ending and kind), the Comparison and the Value (a checkbox for true or false, a number, a text for ending and a list with good, mixed and bad for kind), then press Add to the condition. If something was already written, first choose whether to join it with and (&&, both must hold) or or (||, one is enough). If the package does not declare its variables, you can type the name yourself, with a warning that it cannot be checked. The assistant writes the comparison where your cursor is in the field (or in place of the text you have selected), leaves the cursor right after it and gives the focus back; if the field has not had the cursor yet, it adds it at the end.

Warnings

Anything that would keep a branch from ever showing, or a simulation from working, appears as a warning in the panel and in Checks, with the Content tag. Warnings never prevent saving, exporting or sharing:

  • no branch has bricks, Otherwise included;
  • a branch has no condition, or one that cannot be understood;
  • a condition reads a simulation that is not in the content (it happens when copying between contents) or a variable its package does not declare;
  • a condition reads variables of a simulation whose package does not send its state (state);
  • a condition uses a variable with a type that does not accept that operation, according to what the package declares (for example, comparing a true/false variable with a number);
  • the simulation comes after the conditional content in reading order: when the learner gets there, they have not played it yet;
  • a Scored simulation is inside a branch, or a simulation in a branch is read by some condition.

An assistant connected through the MCP gets these same warnings in warnings when it creates the brick, changes it or moves bricks.

Writing a condition

A condition is a short expression that is true or false. It reads variables written as simulation.name:

sim_u1.reused
sim_u1.trust >= 3
sim_u1.kind == "good" && sim_u1.grade >= 70
!(sim_u1.reused) || sim_u2.ending == "agreement"

Variables

NameWhat it holdsType
gradeThe grade (0–100) the package reportednumber
scoreThe score the package reportednumber
maxScoreThe maximum scorenumber
endingThe identifier of the ending reachedtext
kindgood, mixed or badtext
any other nameA variable the package keeps in its state (for example trust)number or true/false

grade, score, maxScore, ending and kind are reserved: they always read the package's last reported result. The other names are the variables the package declares in its slxd-embed.json; ask whoever built the package which ones it offers.

Operators

WhatHowExample
Compare numbers< <= > >=sim_u1.trust >= 3
Equal / different== !=sim_u1.kind != "bad"
And&&sim_u1.trust >= 3 && sim_u1.reused
Or||sim_u1.kind == "good" || sim_u1.grade > 80
Not!!sim_u1.reused
Add / subtract+ -sim_u1.score + sim_u2.score >= 10
Group( )(a.x || b.y) && c.z
  • Numbers are written with an optional decimal point (3, 2.5), no exponent. Negative numbers use -.
  • Text goes between double quotes: "good". Inside, only \" and \\ are special, and there are no line breaks.
  • true and false are available as values.
  • There are no conversions: you cannot compare a number with text, and a text can only be compared with another text, using == or !=. sim_u1.trust == "3" is an error.
  • Comparisons do not chain: 1 < sim_u1.trust < 3 is an error; write sim_u1.trust > 1 && sim_u1.trust < 3.
  • && and || stop as soon as the answer is known, like in JavaScript.
  • The whole expression must be true or false.

Limits

A condition is at most 500 characters. If you write something that cannot be understood, the editor tells you the character where it stopped.

Several branches and "Otherwise"

A Conditional content brick can have up to 10 branches with a condition, plus the Otherwise branch, which always exists and has no condition. Branches are checked in order and the first whose condition is met wins, so put the most specific first:

  1. sim_u1.kind == "good" && sim_u1.trust >= 3 → congratulation
  2. sim_u1.kind == "good" → short positive feedback
  3. Otherwise → reinforcement

Bricks inside a branch are ordinary bricks: they can be any type, in any number. The rules to keep in mind:

  • One level only: a Conditional content brick cannot be inside another one's branch.
  • A condition can name up to 8 different simulations.
  • A branch can be empty.

Never in exams or question banks. Conditional content is only available in regular lessons. The editor does not offer it in exams or banks, a lesson that contains one cannot be converted into an exam or moved to a bank, and the same is true through the MCP.

What the learner sees

The learner only sees the bricks of the branch that applies, in place, as if the Conditional content brick were not there. The other branches do not exist for them: they do not count for progress, do not hold them back and send no xAPI.

A few details:

  • A branch can only be met once the simulations it reads are finished. A simulation is finished when its package says it is done (complete, or a final state). Until then those conditions are false, and the learner sees the next branch or Otherwise. If a variable is not there yet, or has the wrong type, that condition is false too.
  • It is re-evaluated live. If the learner replays a simulation and the answer changes, the lesson updates. Screen readers get a polite announcement that the content changed; focus does not move.
  • What was already done is kept. If the visible branch changes above where the learner already is, a pending blocker inside the new branch still has to be completed, and what they had completed stays completed.
  • Coming back (SCORM): if the learner left inside a branch that no longer applies, they resume at the start of the branch that does, or at the next brick if it is empty.
  • The package's variables are saved with the learner's progress. If the progress does not fit the LMS's room, Creator protects the variables that conditions read.

Previewing

Authors need to see every branch, not only the one that applies to the test run.

  • In the preview, in a version (snapshot) and in review, the bar has a Show all branches switch. When it is on, the player shows every branch one after another, in reading order: the Conditional brick's branches in order, then Otherwise, and no announcement. In review, opening a comment on a lesson that has conditional content switches it on.
  • Only in this view, each branch is preceded by a label with the plain-words summary of its condition ("Branch 1: shown if sim_u1.trust is at least 3"), or Otherwise, and the branch the learner would see right now carries one more line saying so. The learner never sees these labels.
  • Share links do not have the switch: they show what the learner sees.

PDF

The PDF is reference material without a learner, so it prints all the branches, in reading order. Before the first brick of each branch it prints the label "Shown if: …" with the condition written out in words, in the course language (for example, sim.trust is at least 3 and sim.reused is true; if it cannot be read, exactly as you wrote it), and "Shown if none of the above is met" before Otherwise. Empty branches are not labeled.

Reading condition errors

The panel flags a condition that cannot be understood with the reason and the character where it stopped, and warns about a simulation that does not exist in the content. When an assistant writes the brick through the MCP, the whole condition is also checked against the rules above before anything is saved. Typical errors: When an assistant writes the brick through the MCP, the whole condition is also checked against the rules above before anything is saved. Typical errors:

ProblemExampleFix
Text compared with a numbersim_u1.ending == 3sim_u1.ending == "agreement"
Number compared with textsim_u1.trust == "3"sim_u1.trust == 3
True/false variable compared with a numbersim_u1.reused == 3sim_u1.reused
!, && or || on a number, or ordering true and false!sim_u1.trustsim_u1.trust == 0
! on text!sim_u1.kindsim_u1.kind != "bad"
Chained comparison1 < sim_u1.trust < 3sim_u1.trust > 1 && sim_u1.trust < 3
Not true or falsesim_u1.trust + 1sim_u1.trust + 1 > 3
Simulation that does not exist, or inside a branchsim_x.trustuse the identifier of a simulation outside every branch

If the package declares the type of its variables (number or true/false), the panel and the MCP also check that you use them with that type: sim_u1.reused == 3 is an error when reused is true/false. A variable the package does not declare cannot be checked.

Next steps

Conditional Content