Getting Started

This page makes the same small game three ways. Pick the one that suits you; the game, and everything you learn about the script language, carries over to the others. Installation says where each tool comes from.

You do not need any art to start. An image the story names but cannot find is drawn as a placeholder (a silhouette for a character, a gradient for a background), and the engine draws its own dialogue window and menus in the theme's colours, so a story is playable from its first line.

The story

Every version below plays this script. Save it as game.novella (UTF-8):

define config.title = "The Garden"

character q "Qinglan" color "#c0392b" image qinglan
default met_before = false

label start:
    scene bg garden with fade
    "Plum blossom, and nobody in the garden but one girl with a guqin."
    show qinglan smile at right with dissolve
    q "You came."
    menu:
        "I did.":
            q "Then sit with me a while."
        "I was passing.":
            $ met_before = true
            q annoyed "Of course you were."
    q "Listen, then."
    return

Reading it from the top: define config.title names the game; character declares a speaker whose name shows in red and whose image tag is qinglan; default gives a variable its starting value. The game starts at label start. scene clears the stage and shows the background bg garden; a line in quotes alone is narration; show puts Qinglan on the right; q "..." is her speaking; menu offers two choices; q annoyed "..." changes her expression to qinglan annoyed as she speaks, and it stays changed; return with nowhere to return to ends the game and goes back to the main menu.

Way 1: a folder of scripts

  1. Make a folder named The Garden and put game.novella in it.

  2. Add art if you have it. Images are named from their paths, so these files are exactly the images the script asks for:

    The Garden/
      game.novella
      bg/garden.jpg                    -> bg garden
      sprites/qinglan/smile.png        -> qinglan smile
      sprites/qinglan/annoyed.png      -> qinglan annoyed
    

    A top folder called images, sprites or characters is dropped from the name, the rest of the path becomes words, and names are lower case.

  3. Run it:

    NovellaPlayer run "The Garden"
    

    The main menu opens. Click Start.

  4. Check it: NovellaPlayer lint "The Garden" lists anything the story refers to that does not exist, such as an image name with no file behind it.

While you write, NovellaPlayer run "The Garden" --developer turns on the developer tools: Shift+R reloads the scripts and restarts the label you are in, and Shift+O opens a console where jump label_name warps to a label.

Way 2: C#

Create a .NET 10 console program that references the Novella project (see Installation), put the folder from Way 1 beside it as Assets, and write:

using Novella;

NovellaGame game = new("The Garden", 1920, 1080);
game.AddAssetFolder("Assets");
game.LoadScriptsFromAssets();
game.Run();

AddAssetFolder tells the game where its files are, LoadScriptsFromAssets loads every .novella file among them in path order, and Run opens the window and returns when the player quits. A script's define config.width and define config.height would override the resolution given here.

Code can do what a script cannot. Here the story asks the program for something with run:

    $ answer = "moon"
    run riddle answer
    if _return:
        q "Correct."
using Novella.Values;

game.RegisterCommand("riddle", arguments => Value.FromBoolean(arguments[0].AsText() == "moon"));

The command's result is put in _return. Development covers the C# API properly, including writing the game as a class.

Without a script

The story can be C# too. The story builder writes the same labels the script above does, so the game saves, loads and rolls back exactly as the scripted one; the Assets folder then needs only the art:

using Novella;
using Novella.Building;

NovellaGame game = new("The Garden", 1920, 1080);
game.AddAssetFolder("Assets");
game.WriteStory(story =>
{
    story.Character("q", "Qinglan", color: "#c0392b", image: "qinglan")
        .Default("met_before", false);
    story.Label("start", s => s
        .Scene("bg garden", with: "fade")
        .Narrate("Plum blossom, and nobody in the garden but one girl with a guqin.")
        .Show("qinglan smile", at: "right", with: "dissolve")
        .Say("q", "You came.")
        .Menu(m => m
            .Choice("I did.", c => c.Say("q", "Then sit with me a while."))
            .Choice("I was passing.", c => c.Set("met_before", true).Say("q", "Of course you were.", "annoyed")))
        .Say("q", "Listen, then.")
        .Return());
});
game.Run();

Conditions can be C# lambdas, such as .If(v => v.Flag("met_before"), ...), or built values that read back as script. Development has the whole builder.

Way 3: Divooka

As a procedure (Routine graph)

  1. Create a document with a Routine graph.
  2. Open the document's asset library (in Divooka Compute, the Asset library tool or Ctrl+Shift+A) and use Import files… to bring in game.novella and any art, keeping the folder names the script relies on.
  3. From the Novella toolbox, chain these nodes on the execution path:
    1. Make Novella Game, with the title The Garden, width 1920 and height 1080.
    2. Add Library Assets, with the game wired in. Its library input is supplied by the document, so it needs no wire.
    3. Load Scripts From Assets, with the folder left empty to load every script in the library.
    4. Run.
  4. Run the graph. The game opens in its own window.

Hello Novella running, before it has any art

Instead of importing a script file, you can type the script into a Load Script node, or skip scripts and define things with nodes such as Define Character and Set Config.

As data (Function graph)

The story can also be written as nodes, with no script at all:

  1. Create a Function graph.
  2. Chain Start Sequence → Scene (bg garden, with fade) → Show (qinglan smile, at right, with dissolve) → Say (character q, text You came.).
  3. Make Label with the name start and the sequence.
  4. Start Story → Add Label (the label) → Add Character, fed by Make Character (q, Qinglan, #c0392b, image qinglan).
  5. Make Game Definition with the title and the story.
  6. Select the Make Game Definition node and open its Custom Preview in the Properties panel. The game plays in a window, with saves kept in memory and the developer console on.

Any node along the chain previews: a sequence plays as a one-label story, and a story with no start label starts at its first label. Conditions and changes to variables are nodes too (If with Variable At Least, Apply Effect with Add To Variable), and a game can be written as scenes with Make Scene, each a background, music, lines and where the story goes next. Without the custom preview, the same values preview as the script they amount to, so you can read what a chain of nodes has written.

Novella in Divooka explains every node, the Events graph way of writing a game, and how a Function graph that describes a game is called from a Flows graph.

Next

  • Concepts: what a story, the stage and a checkpoint are.
  • Script Language: everything a script can say.
  • Theming: fonts, colours and a dialogue window with your own art.