Advanced Arcweave branches
Use "if" conditionals, to direct your story flow with precision.
Branches are Arcweave items that allow you to direct the story flow according to conditions being true or false. They consist of arcscript expressions in the form of if, elseif, and else and each expression leads to an output connection (in green, in the image below). At the same time, you can give a branch as many incoming connections as you want (in blue).
The current post demonstrates the basics of branches, as well as more advanced uses.
First, let's go through the elementary. To create a branch, you can:
- right-click on an empty area of your board.
- choose "Create Branch."
or, from the items menu, at the bottom of the screen:
- drag the Branch icon and drop it anywhere on your board.
This newborn branch only has an if clause, which is the minimum requirement. Moreover, it says "Enter condition here..." expecting us to fill in the gap with a condition, in the form of an arcscript expression.
The branch will evaluate this condition as true or false. For example, the following condition always evaluates as true:
- if 4 < 5
Obviously, conditions and branches have meaning if their outcomes vary, that is if their expressions include variables—like the first example, with the score, further up.
Moreover, to see the effect of a branch, we need to connect it to something. For instance, we can place the branch between two elements: the first element introduces a locked door, then the branch checks whether we are carrying a key, and the last element tells us we've unlocked the door with the key.
In Play Mode, if we are indeed carrying the key (thus if
true), we get the option to unlock the door:
Otherwise, there is no such option:
Note: to open the Debugger sidebar, click on the orange bug icon, at the top right.
Adding an else condition
In the above example, if we don't have the key, the flow stops at the branch. In case we always want to have an outcome, we need to add an else condition. To do so:
- right-click the branch.
- choose Add else.
has_key is false, the branch's outcome is a third element called Torment and Despair, with the option to Assume a fetal position and cry.
On Play Mode, if we have the key, we get exactly the same result as before. However, if we don't, we get the option to Assume a fetal position.
In either case, the flow continues.
Adding an elseif condition
In some cases, we need to evaluate more than one expression. For example, in our case, having the key is one option, but we don't have it, an alternative can drinking a potion of strength and bashing the door in.
To express this with our branch, we need to add an elseif condition. To do so:
- right-click on the branch.
- choose Add elseif.
- fill in the elseif condition:
Of course, you need to have already created the
has_potion_strength variable, to use it in your arcscript code. Then, your branch will look like this:
Quiz: how many option buttons will the above branch produce?
The answer is one. And here is the logic:
- if we have the key, we follow the first output, producing the Unlock it! option button.
- if we don't have the key, but we have the potion, we follow the second output, the elseif one, which produces the Drink the potion of strength option.
- else, that is if we have neither, we can only Assume a fetal position.
Remember: a branch always creates one outcome—or none. A branch that includes an else condition, always produces an outcome.
Why connect an element to multiple branches?
Note that, with the above branch, as long as we have the key, our option will be to unlock the door, even if we also have the potion:
Therefore, if we want to produce both key and potion options, we should use a second branch:
- if has_key -> Unlock the door!
- if has_potion_strength -> Drink the potion of strength.
But what happens with... crying in fetal position? We can make this option appear, too, with a third branch that evaluates as
true if neither the key nor the potion is present:
- if not has_key and not has_potion_strength -> Assume a fetal position.
The two items produce their options independently from each other. It is the third option that depends on lacking both items.
Combining branches with elements' dynamic text
1st Law of Interactive Fiction: you can't GET LAMP if lamp ain't there.
2nd Law of Interactive Fiction: lamp can't be there if you've took it.
OK, yes, I just made that up. But it's an obvious truth: action description and player options must agree.
To stick with the lamp example: let's say the current element produces a room description that includes a portable lamp. We need the option for the player to take it, if they so wish. Once they have taken it, though, that option must disappear—as well as the lamp from the room description.
This translates into a combined use of element arcscript and branch. Here's a looping mini game that demonstrates this. It uses a boolean
Sometimes, it’s simpler to use a couple of branches in a row than trying to catch all cases in one mega-branch.
In my demo game Regrets, the dialogue with the NPC Andreas starts like this: (1) a couple of "hello" elements, (2) a branch checking whether you carry the final item (Andreas provides this near the end of his dialogue), (3A) if you have it, you get diverted to a couple of elements where Andreas urges you to go and finish the game, (3B) if you don't have it, you continue to the main dialogue branch. This sends you back to the point where you abandoned the dialogue last time, so you don't have to go through the same topics.
Notice how clearer it is to use 2 branches in a row, instead of trying to merge them into one. In a sense, you can even perceive each branch as a question: (a) "do you have the key?" and then (b) "Where were we?" Clarity is your friend.
Catching logic errors
Instead of using “else” as the last logical outcome, reserve it for the illogical one.
Example, in the same demo game mentioned previously, the dialogue with the NPC Andreas has 4 check points—or bottlenecks. These serve a couple of functions, one of which is providing dialogue points of no return: once you have pass e.g. Bottleneck 3 (i.e. once the bottleneck variable reaches the value 3), the next time you talk to Andreas you will restart the dialogue from Bottleneck 3.
At the beginning of the dialogue, a branch checks which is the last "activated" bottleneck (i.e. the value of the bottleneck variable). Notice how, instead of reserving the "else" part for the last bottleneck, I have strictly used the "if / elseif" parts for all the available cases. As a consequence, if the "else" ever fires, it will be an error. Somewhere in the story, the bottleneck variable must have taken a non-acceptable value.
Wherever you can, it is a good idea to set yourself up for catching errors and "else" is a good helper in this sense.
(To be absolutely safe, I should have shielded myself against the case where the bottleneck variable becomes 0 or less. Oh, well.)
Sometimes, expressing logic with the right conditions can be confusing.
Take a step back from your newborn branch and ask yourself: what do I want to convey? It always helps to speak the logic aloud to yourself: "if this is true, then the first thing happens. Else, if the other is true, then the second thing happens..."
Keep in mind, sometimes it is easier to ask if something is not true: "if the player isn't carrying the sword..."
Also, be aware of the order of your conditions.
Reminder: a branch directs the flow to the first satisfied condition.
Therefore, the next branch will ignore everything after the first condition (which is always satisfied), even what follows is true:
- if 4 > 3 ...
- elseif 4 > 2 ...
In a similar manner, it is impossible to access the second condition of this branch, since we force the more general case to fire first:
- if health < 10 ...
- elseif health < 5 ...
If we want to properly distinguish those cases, we need to flip the conditions:
- if health < 5 ...
- elseif health < 10 ...
Little things like this can break the game logic and keep you bug-hunting for hours. But, hey! Bug-hunting is part of the game, right? The sooner you embrace this truth, the merrier you'll be.
Branches are a friendly, visual way to implement logic in your story. Experiment with them; be daring and have fun!
And if things seem... illogical, don't hesitate to ask for help from our community!