How to Use LNVL
===============

This documents explains how to use LNVL: the LÖVE Visual Novel engine.
It is a tutorial and a guide for users wanting to use LNVL to create
their own stories.  This document assumes you can run LNVL and are
comfortable writing scripts with a text editor of your choice, but
makes no other assumptions about your knowledge of scripting or
programming languages.  However, it does assume you are familiar with
[visual novels][nvl] and their related concepts.

The document will sometimes refer to the reader as *the author.*


The Bird’s-Eye View of LNVL
---------------------------

You use LNVL as the author by writing *scripts.*  These are files that
do things like:

1. Describe scenes for action to take place.
2. Create characters to interact with each other.
3. Provide the dialog and narration for your story.
4. Present options to the reader so he can make choices affecting the
story on a scale that you control.

LNVL scripts are plain text files; you can write them with any text
editor.  But the scripts use their own special language.  This
language provides ways for you to do all of the things listed above.
Here is a simple example:

    Lobby = Character {dialogName="Lobby Jones", image="images/Lobby.png"}

    START = Scene {
        Lobby "Hello everyone!",
        Lobby "My name is Lobby Jones.",
        Lobby "And this is my short introduction.",
        Lobby "Now goodbye to you!"
    }

This script creates one character, Lobby Jones, and one scene.  All of
the action in LNVL takes place within scenes, so every script must
define at least one scene.  The action always begins with the `START`
scene, so that is the one you create.  And within that scene you have
our Lobby character speak four lines of dialog.  The user would see
these lines one-by-one and could navigate back and forth between them
at his leisure.

Computer programmers may recognize this language is actually the
[Lua programming language][lua].  That is true.  The special language
LNVL provides is a [domain-specific language][dsl] (DSL) written in
Lua.  This DSL makes it easier to write scripts for LNVL, but it also
means that, if necessary, authors have the full power of the Lua
programming language at their disposal.


Creating Scenes
---------------

A *scene* is the container for everything that happens in LNVL.  All
character dialog, all background images, all transitions, all of these
things take place inside of a scene.  That means you cannot do
anything without first creating a scene.  Here is the most basic
example:

    START = Scene {}

The name for this new scene is `START`, which is a special name.  Any
non-trivial story using LNVL will contain multiple scenes, but there
must always be an initial scene.  `START` is that initial scene, the
one LNVL always expects to exist because that is the first one it
displays.  That means every LNVL story *must* define the `START`
scene.

The example scene is empty though.  You can add narration to the scene
by adding strings.  LNVL will display each string one at a time,
allowing the user to move back and forth through them.  LNVL considers
strings separated with commas as different lines of dialog.  However,
you can concatenate strings too long to fit comfortably on a single
line using the `..` operator.  For example:

    START = Scene {
        "Hello world!",
        "This is our second line of narration.",
        "And this is the third but even though it spans " ..
          "multiple lines it is actually a single string " ..
          "instead of many.",
        "But now this is our last line of dialog."
    }

LNVL will display every string of dialog to the player, even if that
string is empty.  Nothing will appear on screen but the player will
have to press a key to continue.  If you want to use that effect for a
dramatic pause, for example, then your script will be more readable by
using the `Pause` constant.  It is the equivalent of writing `""` in a
scene but it makes the intentional pause explicit.

### Backgrounds ###

By default a scene has a black background with a white background for
the dialog container.  But you can change these.

To change the dialog box color you can to set the `boxBackgroundColor`
property of the scene.  You must assign the property a list of three
or four numbers, representing the red, green, blue, and (optional)
alpha channels, respectively.  But to make this easier LNVL provides a
`Color` module that has pre-defined names for colors.  For example,
after creating a scene and its dialog you can change its background
color like so:

    START = Scene {
        boxBackgroundColor = Color.NavyBlue,
        "Thus begins our tale...",
    }

The file `src/rgb.txt` names every color you can use; although the
`Color` module always uses title-case names, so the file lists
‘gray50’ but in scripts you write `Color.Gray50`.  If you want
transparency you can use `Color.Transparent` for any color.

Instead of names you can use [short-hand hexadecimal notation][color-hex]:

    START = Scene {
        boxBackgroundColor = Color.FromHex("#088008"),
        "...",
    }

As for the black background around the dialog box, LNVL lets you use
images for that part of the scene.  You give a background picture to a
scene with by assigning `background` the name of an image file:

    START = Scene {
        background = "examples/images/Sunny-Hill.jpg",
        "...",
    }

Now LNVL will draw that image throughout the entire scene content.

### Fonts ###

Naturally fonts are important in LNVL because every scene uses one to
render dialog.  Visual novels would be boring if every one used the
same font.  So there are multiple ways you can change the font for
scenes.

The first way is to change the global font.  The file
`src/settings.lua` provides many of the default values for LNVL.
Inside that file is the setting `LNVL.Settings.Scenes.DefaultFont`.
As its verbose name indicates, it represents the default font that
every scene will use.  You can change that default font by giving that
setting the value of [a `Font` object][love-font] using the LÖVE engine
functions; see their documentation for more information.

You may also change the font only for an individual scene without
affecting the rest.  The way you do this is similar to how you change
the background image of a scene.  For example:

    START:setFont("path/to/myFont.ttf", 16)

The first argument is a path to the font file, and the second is the
size of the font in pixels.  So this example code loads a TrueType
font (TTF) and tells the scene to draw the dialog with that font at a
size of sixteen pixels.  This will only affect the `START` scene;
every other scene will continue to use the global default font
discussed above.

LNVL also lets you change the font color for scenes.  Every scene uses
the color from `LNVL.Settings.Scenes.TextColor` by default.  You can
change that value to control the default text color for all scenes.
You can change the color for individual scenes by naming the color
when you create the scene, like so:

    START = Scene {
        textColor = Color.Peach,
        "This narration will be in peach.",
        "It will override the default setting.",
    }

Later on you will see how scenes can have characters who speak dialog.
Those characters can have individual colors for their speech.  Colors
for characters *always* take precedence over colors for scenes.

### Changing Scenes ###

Cramming an entire story into one scene would create a mess.  You
*could* do it, but that doesn’t make it a good idea.  It is easier to
put a story together by breaking it down into scenes just as you would
if you were writing a play.  You can create as many scenes as you want
by assigning them to names of your choice.  For example:

    START = Scene {...}

    MIDDLE = Scene {...}

    END = Scene {...}

This example code creates three scenes.  Remember that every LNVL
script must have the `START` screen.  But the rest of the names are
arbitrary and can be anything you want.  The example scene names are
in all capital letters, but this is not a requirement, only a
suggested convention.

Creating scenes, however, does nothing to connect them to one another.
In the example above LNVL would not know how to progress from `START`
to the `MIDDLE` scene.  You can connect the two using the
`ChangeToScene()` function.  Here is an example:

    START = Scene {
        "And so our story begins...",
        "Except I really have nothing to say as a narrator.",
        "Oh well.  Let's move along!",
        ChangeToScene "MIDDLE",
    }

    MIDDLE = Scene {
        "Now then...",

        -- Just pretend an actual story is here and save me the effort
        -- of writing some dumb garbage, ok?

    }

The important line here is the final part of the `START` scene:
`ChangeToScene "MIDDLE"`.  This tells LNVL to transition to the
`MIDDLE` scene once it reaches the end of `START`.  Notice the name of
the scene is in quotes; this is a requirement.  If you omit the quotes
then LNVL will crash with an error.

You can place additional dialog or anything else after a line using
`ChangeToScene()` but there is no good reason to do so.  LNVL will not
display any dialog or do anything else in a scene once it is told to
switch to another scene.  So that means `ChangeToScene()` is best
placed as the final part of a scene.

#### Scene Preconditions ####

LNVL keeps a record of every scene visited during the course of a
story.  You can use this information to enforce order in the way
scenes appear by listing `preconditions`.  [For example][HarvestMoon]:

    MARRIAGE = Scene {
        preconditions = { "GIVE_GIFT", "BLUE_FEATHER" },
        -- ...
    }

Any attempt to use `ChangeToScene "MARRIAGE"` will only work if the
player has previously visited the scenes `GIVE_GIFT` and
`BLUE_FEATHER`.  The order of the preconditions is not enforced.  In
the example above, the player can visit `GIVE_GIFT` and `BLUE_FEATHER`
in either order to satisfy the preconditions for the `MARRIAGE`
scene.

Preconditions can also be functions.  They must return a boolean.  If
any function returns `false` then the scene fails the preconditions.
Returning `true` indicates satisfaction of that particular
precondition and LNVL will move on to the next.  Using functions for
preconditions allows use of arbitrary logic to determine whether a
scene has satisfied all of its preconditions.  See the code in
`examples/17-ScenePreconditions` for an example.

### Standard Lua Functions ###

LNVL dialogue scripts allow the use of two functions from Lua’s
standard library:

- [`print()`](http://www.lua.org/manual/5.2/manual.html#pdf-print)
- [`error()`](http://www.lua.org/manual/5.2/manual.html#pdf-error)

They exist to help with debugging scripts during development.

The function `assert()` is also available.  However, unlike the
standard Lua `assert()`, the version in LNVL will send output to
various places based on values in the `src/settings.lua` file.  See
the comments in that file for further details.


Characters
----------

Every good story needs characters.  So LNVL provides a way to create
characters and plug them into your tale.  Here is a simple example of
a character:

    Lobby = Character {dialogName="Lobby", textColor="#363"}

This creates the character `Lobby` and defines his name and color,
i.e. the color of that character’s dialog on screen.

### Character Names ###

The example above defines the `dialogName` property for the character.
However, sometimes you will want characters will full names.  LNVL
supports this by allowing you to define the first and last name of a
character, like so:

    Lobby = Character {firstName="Lobby", lastName="Jones"}

If you do not provide the `dialogName`, as in this example, then LNVL
will default to using the `firstName` when showing the character name.
You can change the name LNVL shows by using `displayName`.  Here is a
list of the arguments it accepts, with example usages:

1. `Lobby:displayName "firstName"`.  Will display `Lobby` in dialog.

2. `Lobby:displayName "lastName"`.  Will display `Jones` in dialog.

3. `Lobby:displayName "fullName"`.  Will display `Lobby Jones`.  This
   option combines the first and last name, in that order.

4. `Lobby:displayName "default"`.  Will display the value of character’s
   `dialogName` property.

You can change the name to display at any point during a scene.

### Speaking With Characters ###

You use characters inside of scenes to specify who says which lines of
dialog.  All you have to do is write strings of dialog in the scene
like in the example above, except you provide the character name
before the string.  That tells LNVL which character is speaking that
line.  For example, here is a short scene of two characters speaking:

    Lobby = Character {dialogName="Lobby", textColor="#363"}
    Eric = Character {dialogName="Eric", textColor="#66a"}

    START = Scene {
        Eric "Hello Lobby!",
        Lobby "Eh?  What?  What time is this?",
        Eric "Are you alright Lobby?",
        Lobby "I'm going back to bed, forget this..."
    }

To make a character speak all you have to do is type the dialog after
the character’s name.  This helps your scripts read naturally.  But
what if you have one character speak numerous lines in a row?  You
could copy the character name each time, but LNVL provides a way for
you to avoid that repetition: by writing a *monologue.*  Here is an
example:

    START = Scene {
        Eric {
            "Look Lobby, we need to talk.",
            "You have a problem.",
            "And it worries me.  It worries all your friends.",
            "You don't work.  You steal money from me constantly. " ..
                "You're intoxicated every day...",
            "We just want to help you Lobby."
        },
        Lobby "Eh, what?  Sorry.  I wasn't listening."
    }

By using `Eric { … }` you can write multiple lines of dialog
for that character without having to prefix every line with the
character’s name.  But be careful to add the comma after the closing
curly-brace in a monologue.  That is a common syntax error that will
cause LNVL to reject your script.

### Character Images ###

Often you will want to show a character on screen, as is common in
visual novels, role-playing games, and all manner of genres.  LNVL
allows you to assign multiple images to a character and change between
them throughout a scene.  This can help convey your story by showing
changes in a character’s emotion through art, for example.

To use images with a character you must first provide a default image,
like so:

    Lobby = Character {
        dialogName = "Lobby Jones",
        textColor = "#363",
        image = "images/Lobby-Default.png",
    }

Notice the new property: `image`.  This has a path to an image file
which LNVL will use as the default picture for that character.  Now
LNVL will show that image whenever the character speaks.

But it would be dull if you could only use one image.  So LNVL lets
you change character images during scenes by making a character
‘become’ something else.  Think of it as the character becoming
surprised, excited, saddened—like that.  That is why you use the
`becomes` function of characters in scripts to change their images.
Here is an example:

    START = Scene {
        Lobby "So I thought about what you said and...",
        Lobby:becomes("images/Lobby-crying.png"),
        Lobby "...I realize I need help.",
        Lobby "I'm sorry for everything.  Please forgive me!",
        Lobby:becomesNormal(),
        Lobby "Heh, nah, I'm just kidding.  Dummy.",
        Lobby:becomes("images/Lobby-laughing.png"),
    }

The lines like `Lobby:becomes("images/Lobby-crying.png")` tell LNVL to
change the character image of screen.  As you can see, it accepts the
path to an image file as its argument.  The path must obey
[the restrictions LÖVE has on files][love-files].

The initial image you give when creating the character is the ‘normal’
image.  That means `Lobby:becomesNormal()` reverts the character back
to his original image.  You could use `becomes()` and provide the path
to the original image, but LNVL lets you use `becomesNormal()` as a
short-cut.

### Image Positions ###

You will not want every character portrait to appear at the same place
on screen.  If you did then they would overlap and block each other
out!  So LNVL allows you specify where each character image should
appear.

Character images appear on the left side on the screen by default.
The first way you can change this is to specify the position when you
create a character, like so:

    Lobby = Character {
        dialogName = "Lobby Jones",
        textColor = "#363",
        image = "images/Lobby-Default.png",
        position = "Right",
    }

This is the same as the character definition from earlier but with one
addition: the new `position` property.  The string `"Right"` tells
LNVL that it should draw Lobby’s image on the right side of the screen
instead of the usual left.  These are the acceptable values for
`position`:

1. `"Left"`
2. `"Center"`
3. `"Right"`
4. `"TopLeft"`
5. `"TopCenter"`
6. `"TopRight"`
7. `"BottomLeft"`
8. `"BottomCenter"`
9. `"BottomRight"`

They do not provide pixel-perfect control over the position.  Instead
LNVL decides what is best for ‘Right’, for example, based on settings
such as the screen size and the width of other elements on screen.
This helps prevent you from accidentally covering up other things with
character images.

The second way to change a character position is by using the `isAt`
function.  It requires one of the three strings above as its
argument.  But unlike the `position` property, `isAt` allows you to
change the position of a character dynamically in the middle of the
scene.  For example:

    START = Scene {
        Lobby "Want to see how fast I can run?",
        Lobby:isAt "Center",
        Lobby "Ok---hold on, I'm getting there.",
        Lobby:isAt "Right",
        Lobby:becomes "images/Lobby-exhausted.png",
        Lobby "I need to stop smoking...",
    }

Each use of `isAt` makes LNVL draw the character image at the new
position.  This is useful to move a character to a new position when
you introduce another in a scene to avoid any overlap.  You can also
use it for dramatic effects; if you have characters in an argument,
for example, you could group characters on each side based on their
conflicting points-of-view, maybe with a mediator in the center trying
to calm everyone down.  Look at popular visual novels for ideas about
how you can convey feelings in a story through the use of character
portrait positioning.

### Removing Characters ###

Imagine a scene where two characters are talking but in the middle of
the conversation one character leaves.  LNVL will draw the characters
on screen if it thinks they are actively participating in the scene.
That means to make LNVL stop drawing a character you must tell it when
that character leaves the scene.  This is exactly what
`leavesTheScene()` does.  For example:

    START = Scene {
        Lobby "Capital day to you good sir!",
        Eric "Oh, hello Lobby.",
        Lobby "'Lobby'?  That is Mr. Jones to you.  Mr. Jones!",
        Eric "Wow, you need to calm down.",
        Eric "Actually, forget this.  I'm leaving.",
        Eric:leavesTheScene(),

        -- Now 'Eric' no longer appears on screen.

        Lobby "Wait.  I said wait you scallywag!  Halt!",
        Lobby "The nerve...",
    }

A character who leaves a scene will return and begin to appear on
screen again if you make that character speak, or change the
character’s image via `becomes` or position via `isAt`.  And remember,
`leavesTheScene()` must have the pair of parentheses after it.  If you
forget the parentheses then LNVL will not recognize the command.

### Character Fonts ###

Individual characters can use different fonts in the same way you can
assign a different font for an individual scene.  To make a character
use a specific font you define the `font` property of that character,
like so:

    Lobby = Character {
        dialogName = "Lobby Jones",
        font = "path/to/font-for-lobby.ttf",
    }

This will cause the character to use that specific font.  By default
the font size will be twelve pixels.  But you can also change that:

    Lobby = Character {
        dialogName = "Lobby Jones",
        font = {"path/to/font-for-lobby.ttf", 16},
    }

Now LNVL will render the font at a size of sixteen pixels.  Note how
`{}` braces surround the name and size.  LNVL will stop with an error
if you omit those braces.  Furthermore, if you define a character to
use a specific font that will *always* take precedence over the fonts
for any scene.  If LNVL has to choose between the font of a character
and the font of a scene, it will choose the character every time.

### Temporary Characters ###

If you want a character to be temporary, i.e. then assign that
character the value `nil` at the end of the script.  For example:

    Lobby = Character { firstName="Lobby", textColor = "#a33" }
    
    START = Scene {
        Lobby {
            "I have lots of important things to say.",
            "You can never silence or delete me!",
            "I'll exist in your story forever!"
        }
    }
    
    -- Oh really?
    Lobby = nil

Because of the final line, `Lobby` will not be a valid character in
any other dialogue script.


Complex Scene Content
---------------------

LNVL also accepts functions for scene content.  For example:

    Lobby = Character { dialogName="Lobby", textColor="#a66" }
    Lobby.lazy = true
    
    START = Scene {
        "What to do today...",
        function ()
            if Lobby.lazy == true then
                return Lobby:says("Eh, nothing.  Too lazy!")
            else
                return Lobby:says("Maybe some actual work?")
            end
        end,
        function () return "And thus the lobster made his decision." end
    }

The second piece of content is a function which has the character
Lobby say something different depending on the value of the
`Lobby.lazy` property.  Note the use of the `says()` method on the
character to achieve this.  The final piece of content is an anonymous
function which does nothing but return a string.  This is entirely
equivalent to using a plain string in the first place, but with a
function one could potentially return different strings based on
property values, similar to the example using `Lobby.lazy` above.

**Note for Programmers:** LNVL executes such functions in the context
  of the ‘script environment’, i.e. the `LNVL.ScriptEnvironment`
  table.


Settings
--------

### Ways to Change Them ###

Previous examples change settings in a variety of ways.  You can
change global settings by editing the values in the `src/settings.lua`
file.  Or you can change settings for individual scenes or characters
by providing those values when you create them, for example:

    Lobby = Character {
        dialogName = "Lobby Jones",
        textColor = Color.Blue,
    }

This overrides the default text color for characters, giving this
specific characer his own unique color for all of his dialog.

There is another way to change global settings: in dialog scripts
themselves.  Since each dialog script is actually Lua code you can
change the values for global settings inside of those scripts.  For
example:

    -- This example script demonstrates how we can change some global
    -- settings in the script itself, without modifying the
    -- 'src/settings.lua' file.

    -- Explicitly disable debugging mode.
    LNVL.Settings.DebugModeEnabled = false

    -- Change global settings for all scenes.
    LNVL.Settings.Scenes.TextColor = Color.Blue
    LNVL.Settings.Scenes.BorderSize = 0

    -- Use two scenes to make sure the changes above affect all scenes.

    START = Scene {
        "This text should appear in blue.",
        ChangeToScene "END",
    }

    END = Scene {
        "With no border around the dialog box.",
    }

This example changes three global settings by modifying values that
the `src/settings.lua` file defines.  The changes have the intended
effect because LNVL does not use settings like `Scenes.TextColor`
until you create a scene.  That means there is a window of time in
dialog scripts where you are free to modify global settings relating
to scenes, characters, and other story objects before you create any
of those objects.

One benefit to this approach is that it allows you to change global
settings only for one script.  Imagine that you are using LNVL to
present multiple stories.  You may want different global settings for
those stories (i.e. scripts).  Changing the values in
`src/settings.lua` would affect every story.  You could change the
appropriate settings for each individual scene, character, etc., but
that becomes tedious and repetitive.  A convenient middle-ground is to
change the global settings as needed in each script.  This way you can
modify the colors for every scene in a single story without causing
changes for any other independent stories using the same installation
of LNVL.


Menus
-----

**Note:** This section of the document assumes the reader is
  comfortable with [Lua][] programming.

**Note:** This part of the engine is currently under heavy development
  and the system described below may change suddenly.

Centuries of literature demonstrate that you can have an engrossing
story that is entirely linear in its progression.  However, this is
not common in [visual novels][nvl].  The genre often presents stories
with branches, places where the player can select from a set of
choices with results that affect the development of the story moving
forward.  A common method to present these choices is through the use
of *menus.*

LNVL provides support for menus.  Script authors can use menus to
allow their story to branch into different scenes based on the
player’s choice.  Or authors can execute [Lua][] code based on what
menu choice a player selects, providing a way to implement more
complexity in stories (e.g. keeping track of variables based on a
series of choices).

### Adding Menus to Scenes ###

We begin with an example:

    START = Scene {
        Judge "I have reviewed the evidence.  How do you plead?",
        Menu {
            {"Not Guilty", "NOT_GUILTY"},
            {"Obviously Guilty", "THE_TRUTH"}
        },
    }
    
    NOT_GUILTY = Scene {
        -- ...
    }
    
    THE_TRUTH = Scene {
        -- ...
    }

You create menus using the syntax `Menu { … }`, which is intentionally
similar to how you create scenes and characters.  Within those braces
is a list of choices, each wrapped in their own set of braces.  Each
choice has two parts:

1. A label, which is a string that the player will see for that
   choice.  For example, in the script above the player would see the
   text ‘Not Guilty’ and ‘Obviously Guilty’ for the two choices.

2. An action to perform if the user selects that choice.  If an action
   is a string then LNVL assumes it is the name of a scene; if the
   user selects that menu choice then LNVL will transition to that
   scene (e.g. in the script above).  An action can also be an
   anonymous function of Lua code.  **Note:** Support for this is
   currently under so much change that we intentionally omit
   documentation because anything we write now could become invalid.

### Displaying Menus ###

LNVL does not assume how it should render menus.  Each game will want
to draw menus and handle player input in their own way, based on their
design, aesthetics, and so forth.  So LNVL provides a hook for games
to control how to handle menus by using Lua [coroutines][].  LNVL
calls these *handlers,* functions and coroutines meant to handle
LNVL-related logic outside of the scope of LNVL itself.

The settings file contains all of the handlers.  For example, it has
this for menus:

    -- When the player reaches a menu within a scene, LNVL will invoke
    -- this coroutine with one argument: the LNVL.Menu object representing
    -- that menu.  See the documentation for that module about the
    -- properties and methods available from that class.  LNVL expects the
    -- coroutine to return the player's choice from the menu, i.e. a
    -- string.  For example, developers can use this handler to control
    -- the user interface for how menus appear and interact in their game.
    --
    -- The dummy handler below automatically returns the first choice from
    -- the menu without ever asking the player for input.
    Settings.Handlers.Menu = coroutine.create(
        function (menu)
            return next(menu)
        end
    )

The documentation for the handler explains its purpose and what it
does, which is effectively a no-op.  LNVL expects games to redefine
this function with something more appropriate for their game.  The
file `src/menu.lua` contains all of the code and commentary for the
`LNVL.Menu` class the function mentions, i.e. the individual menus in
scenes.



[lua]: http://www.lua.org/
[dsl]: http://en.wikipedia.org/wiki/Domain_specific_language
[color-hex]: http://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form
[love-font]: https://love2d.org/wiki/Font
[love-files]: https://love2d.org/wiki/love.filesystem
[nvl]: http://en.wikipedia.org/wiki/Visual_novel
[coroutines]: http://www.lua.org/manual/5.1/manual.html#2.11
[HarvestMoon]: http://en.m.wikipedia.org/wiki/Harvest_Moon_(series)#Getting_married