Creating Comics with Branching Storylines

Comics made with Panels are normally linear stories, where each sequence is presented in order from start to finish. With a few tweaks you can create a nonlinear, choose-your-own-adventure style comic instead.

Table of contents

Comic Creation

Basic setup & comic creation will the be the same as it is for linear comics. You will of course need to keep in mind the nonlinear nature of your story to ensure that all potential story paths are complete and coherent.

Setup

Follow the instructions in the main Get Started section to install and import the Panels library.

Creation

Follow the normal instructions for creating artwork and comic data files.

Define Branching Behavior

Add a decision point to a sequence by listing an advanceControls table with an input control and target sequence number for each option.

These options will be presented to the user on the final panel of the sequence. When the user invokes one of the listed input controls, they will be taken to the corresponding sequence.

Example:

advanceControls = {
    { input = Panels.Input.A, target = 2 }, -- press A to go to sequence 2
    { input = Panels.Input.B, target = 4 }, -- press B to go to sequence 4
},

Display Choices

The way you present branching story points to the user is entirely up to you. The layout of the choice panel will be defined by the last panel in the comic data for your sequence.

You most likely want to explain to the user what each choice does. You can do this by adding text to the panel that describes each choice, or by adding images that graphically illustate the choices.

Position Controls

Panels will display controls for the inputs listed in your advanceControls table. You can position them over your panel by adding x and y properties:

advanceControls = {
    { input = Panels.Input.A, target = 2, x = 180, y = 20},
    { input = Panels.Input.B, target = 4, x = 180, y = 180},
},

Hide Controls

If you prefer to not display the input controls (perhaps they’re already illustrated in your panel graphics), you can hide them by setting the showAdvanceControls property:

showAdvanceControls = false,
advanceControls = {
    { input = Panels.Input.A, target = 1 },
    { input = Panels.Input.B, target = 4 },
},

Custom Functions (Advanced)

If you’re using custom functions for your final panel, you can specify the sequence target by returning it from a targetSequenceFunction.

This method would allow you to have a minigame or other interactive scene embedded in your comic where the outcome of the game determines the story path. Fun!

Chapter Menu

The chapter menu will by default show all chapters with only the previously-visited chapters being selectable. This works well for linear stories, but in a branching comic it may be confusing for users to see the unvisited, locked chapters appearing out of order. The chapter names might also reveal spoilers and hidden endings.

To address this problem you may choose to hide the locked chapter names by adjusting the comic settings:

Panels.Settings.listLockedSequences = false

With this setting turned off, the chapter menu will only show chapters that the user has already visited.

Alternately, you could disable the chapter menu altogether:

Panels.Settings.useChapterMenu = false

Examples

Download the full example project for more details:
Panels Nonlinear Story Example

This project contains multiple sequences with examples for different use cases:

  1. Basic Example
    Add two branching options to the end of the sequence.
  2. Anchored Controls
    By default, a sequence’s advance buttons float above the panels. This example shows how they can be anchored to the scroll position of the last panel.
  3. Hidden Controls
    Hide Panel’s built in button graphics in order to display your own text or graphics for the user.
  4. Directional Controls
    Let the user choose a physical direction to move in.
  5. Custom Functions
    Use a custom render function to draw interactive content (like a mini-game). Use the targetSequenceFunction to define a target sequence based on any custom-defined criteria.