visual novel guide

Upload: nazleen-diana

Post on 14-Apr-2018

228 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/29/2019 Visual Novel guide

    1/30

    Before You Begin

    There are only two requirements to get started with this tutorial:

    Download Ren'Py

    1. You have to download Ren'Py from theOfficial Download Pageand install it.Think about the story

    2. You have to have some idea what the story that you want to tell is. You don't need to have acomplete outline, or know all of the characters, though that might be a good idea as a storytelling practice (many, though not all, people believe that you should know your entire story atleast at a high level before you start to write any of it down). But at a minimum you just need tohave a basic idea of at least two characters, a setting, and some idea of where your plot isstarting.

    Planning

    You can, of course, jump straight into a mega project, but experience shows that one of the

    main reasons for projects not being completed is that it was just too huge and ambitious.

    It's a good idea to consciously aim to keep your first project small and simple.

    As a guide, 5000 words of story-text is usually about 15 minutes of playing time. 30-45 minutesof playing time is a realistic target.

    Producing art takes a lot of time. While you don't want to let it dictate the story, it's sensible tolimit the number of locations (and therefore backgrounds) where you can. Likewise having alarge cast will increase the artist's workload dramatically - unless you're happy for thecharacters to have only one pose and one expression.

    Just to give you an idea, below are the "profiles" of some completedfirst-time projects:

    Project 1

    Creative team: 2 (1 writer, 1 artist)

    Development time: 1 month (NaNoReNo)

    playing time: 30-45 minutes

    Story length: 17466 words

    Cast: 3 characters, 38 sprite images

    Story world: 15 backgrounds (filtered photos)

    Music: none.

    Project 2

    Creative team: 1 person

    Development time:Playing time: 30 minutes (but had shoot-em-up elements)

    Story length: 8000 words

    Cast: 3 characters, 45 sprite images + 3 minor characters

    Story world: 12 backgrounds, plus rendered spaceships

    Music: from the web.

    Project 3

    http://www.renpy.org/wiki/renpy/Download_Ren%27Pyhttp://www.renpy.org/wiki/renpy/Download_Ren%27Pyhttp://www.renpy.org/wiki/renpy/Download_Ren%27Pyhttp://www.renpy.org/wiki/renpy/Download_Ren%27Py
  • 7/29/2019 Visual Novel guide

    2/30

    Creative team: 1 person

    Development time: 2 months

    Story length: 1507 words,

    Only one ending (kinetic).

    Cast: 3 characters. Everyone has only one pose.

    Main character has 7 expressions, while the others have 4 and 1.

    Story world: CG and 4 painted backgrounds

    Music: 3 tracks from the web.

    And a major project just for comparison:

    Project 4

    Creative team: 2 people (artist/writer, musician)

    Development time: 2 YEARSStory length: 51756 words,

    6 main endings plus a couple of "you die" dead ends.

    Cast: 9 characters, 65 sprite images

    Story world: 86 backgrounds (50% filtered photos)

    Music: 8 tracks, composed for this work

    So you see, projects can be as big or as small as you like.

    Start making your game

    That's it. You're now ready to get started.

    Getting StartedOnce you've installed the latest version of Ren'Py, run the Ren'Py launcher. On Windows, this isrenpy.exe. On linux, you run the script renpy.sh in the installed renpy directory.

    Click on the "New Project" button. Click on the "template" button. The launcher will prompt youfor a name. Enter a simple, preferably one-word name for your project. If you can't think ofanything, "renai1" will work. Then hit enter.

    This should bring you back to the main launcher page, except now it will say the name of yourproject in the upper left-hand corner. Click on the "Edit Script" button. This will launch the jEdittext editor with your new Ren'Py script (which is currently the same as the Ren'Py templatescript). If you're not on the "script.rpy" tab, please pay no attention to the current tab and switchto that one.

    You're now ready to go.

    Thinking in Ren'Py

  • 7/29/2019 Visual Novel guide

    3/30

    Ren'Py Is Easy

    Ren'Py is probably the easiest way to write visual novels that exists. Yet many people who seea Ren'Py script for the first time are scared. How can this be?

    The answer is simple: Ren'Py is designed to make writing complete visual novels as easy aspossible. It's not designed to make startingvisual novels as easy as possible. What's thedifference? A visual novel is a long and fairly complex story. An easy tool for small projectsoften gets in your way on large projects. Consider a hand trowel and a shovel: if you want toplant a petunia in a window box, the short handle and small spade of a trowel make it easy tohandle. But if you want to dig a hole in your back yard to plant a tree, the long handle and bigspade of the shovel will let you finish in 1/10th the time and effort. It's not that either one iseasier than the other: they're each easier for the problem they're meant to solve.

    And let's not kid ourselves: writing a visual novel is much more like planting a tree. A visualnovel which takes only half an hour to play might easily have 10,000 words and severalbranches in it. Writing 10,000 words of a story which branches and recombines is real work.Some of the games made with Ren'Py have 30,000 words. Professional visual novels have100,000+ words. That's a lot of work.

    The goal of Ren'Py is to require as little extra work as possible. That's why Ren'Py might seema little scary at first. The features of Ren'Py which make it as easy as possible to deal with a50,000 word visual novel may seem unnecessary when you've only written 50 words. If youkeep writing, it will seem necessary soon enough.

    So, even if Ren'Py might look a little scary right now, please trust us that Ren'Py is the easiestway to write a visual novel. Because if you start, pretty soon you're going to be wrestling withyour plot and characters and the choices and the branches, and the Ren'Py script will be sonatural when dealing with them that you'll barely notice it.

    (originally written by Chris Lansdown)

    Programming

    You don't need to know any programming, or be able to program, to use Ren'Py. It is, however,true that even a basic Ren'Py visual novel requires a few programming statements in python.Don't worry about this. In this tutorial we'll show you all of the python statements that you'll needto use, and you'll be able either to copy them directly or copy them and modify the names orfilenames, and where that's relevant, we'll explain how to do it.

    You won't need to understand python code at all to write a visual novel; you'll only need to beable to copy and paste it.

    If you are a programmer, or have a programmer on your team, you can go to the trouble ofunderstanding the python that you'll need, but it probably won't win you much. On the otherhand, if you want to use the python to do something unique and cool, we will provide links intothe reference manual so you can do this if you want.

    Indentation

    The biggest problem with computers, and consequently with Ren'Py, is that they're notintelligent. Computers can't understand human communication, so we have to do all of the workto make the computer understand us. It's not fair, but in any relationship the one with less tolose always wins. Since the computer is an inanimate object, it has nothing to lose at all.

  • 7/29/2019 Visual Novel guide

    4/30

    So we need to figure out ways to communicate with the computer that the computerunderstands. Most of the time this isn't too bad. For example, we use variables to hold values.We're used to giving things names, so this doesn't strain us very much. Writing something like:

    $ gift = "swimsuit"

    might be unusual, but it's just a formalized way of doing what we're used to doing. In this case,it's the same thing as saying, "I'm buying the swimsuit for my girlfriend", except in computerishrather than in English.

    So far, so good. The big problem with communicating with computers is context. We're so usedto dealing with this that for most people it's unconscious. When you say "I tipped the waiter" and"I tipped the cow", you know that in the first one "tipped" means that you gave the waiter moneyand in the second one it means that you pushed the cow. You know this because ofcontext:you normally give waiters money, but rarely push them over, whereas cows have no use formoney. Computers have no concept of context, so we have to come up with some way to fakeit.

    Ren'Py uses is indentation as its solution to this problem. Indentation is the amount of "whitespace" (spaces) before the words on a line. For example:

    "This line isn't indented."

    "This line is indented 4 spaces."

    "This line is indented 8 spaces."

    "This line is also indented 4 spaces."

    "And this line is indented 12 spaces."

    "Whereas this line isn't indented at all."

    In Ren'Py, we use this to give the Ren'Py engine context, so it can figure out what we mean. All

    of the statements next to each other with the same (or greater) indentation are in the samecontext. We call all of these statements a "block". For example, in a bit we'll talk about "initblocks". This just means all of the lines which are indented after an init statement:

    init:

    # This is in the init block

    # this line is also in the init block

    # this line is NOT in the init block

    It's also possible for blocks to be nested in each other like those russian dolls that open toreveal a smaller doll:

  • 7/29/2019 Visual Novel guide

    5/30

    init:

    # This is in the init block

    # this line is also in the init block

    python:

    # this line is both in the python block and the init block

    # as it's written here, it's not possible to be in the python block

    # but not the init block.

    # this line is still in the init block, but not the python block, so

    # we say that the python block is "closed", since no more statements

    # can go in it. But we can still put statements in the init block.

    # this line is NOT in the init block

    Don't worry about getting the hang of indentation and blocks now, it will make a lot more senseas you continue reading the tutorial and see real examples. Conveniently, you don't need tounderstand it before then, either. :)

  • 7/29/2019 Visual Novel guide

    6/30

    Ren'Py Script Structure

    Init Blocks

    Every Ren'Py script has information, such as characters, images, and music which you need todeclare outside of the story. This is done with init blocks. An init block looks like this:

    init:$ john = Character("John Smith")$ percy = Character("Sir Percival Blakely")

    image black = "#000000"

    Later sections will explain what goes in the init block, for the moment we're just pointing outwhat they look like. They can come anywhere in a file, but it's generally best to put them at thetop. Init blocks are not indented, and the statements following an init block which are indentedare in that init block. Once you type a statement (usually a label) which is not indented, the init

    block is finished. You can have any number of statements in an init block.

    And that's all you need to know about them for now.

    Labels

    Labels allow you to give names to points in your story. Using them to change the flow of yourstory is discussed inBranching & Recombining the Story. Right now, the important thing to knowis that every Ren'Py script has to have one label in it, called "start". That's where Ren'Py startsexecuting your story. It looks like this:

    label start:

    So, generally, the beginning of a simple Ren'Py script would look like:

    init:

    $ j = Character("John")

    label start:

    j "Hello, World!"

    Comments

    You will occasionally see comments in a Ren'Py script explaining what a line in the script is for.Comments look like this:

    # lines that start with an octothorpe (a.k.a. a number sign,

    # hash, or sharp) are comments. If you want to have comments

    http://www.renpy.org/wiki/renpy/doc/tutorials/Branching_%26_Recombining_the_Storyhttp://www.renpy.org/wiki/renpy/doc/tutorials/Branching_%26_Recombining_the_Storyhttp://www.renpy.org/wiki/renpy/doc/tutorials/Branching_%26_Recombining_the_Story
  • 7/29/2019 Visual Novel guide

    7/30

    # continue over several lines, you have to put the hash mark

    # at the start of each line.

    People playing Ren'Py games never see comments, they're only for you and anyone

    collaborating with you on a Ren'Py game. Ren'Py ignores comments, so you can put anythingthat you like in them. They're also useful for removing lines from the story which you're notready to lose forever:

    # j "Nice shoes, Jen."

    Multiple files

    As your game gets bigger, you might decide to split the game file up, to make it easier to findthings without all that scrolling. You can call the files whatever makes sense to you, but theymust be in the "game" folder for that project, and must end with the extension ".rpy"

  • 7/29/2019 Visual Novel guide

    8/30

    Defining Characters

    Characters in Ren'Py are very powerful objects, but in common practice they're very easy. (Ifyou want to get into the really powerful stuff, check out theDefining Characterschapter of thereference manual.) (Please note through all of these examples that characters mustbe defined

    inside of an init block.)The simplest way to define a character is:

    init:

    $ jane = Character("Jane")

    In practice, this is a little too simple. You should choose a color for the character's name. Youdo this by a standard red-green-blue hex triplet: #rrggbb. To make Jane's name appear inmedium green:

    init:

    $ jane = Character("Jane", color="#009900")

    A useful color chart may be foundhere.

    Still common, but less so, is to use an image in place of the name. To do this, instead of givingjane a name, you give the filename of an image (placed in the game directory of our Ren'Pyproject), and tell Ren'Py that the name is really an image:

    init:

    $ jane = Character("jane_label.png", image=True)

    The other common thing that you might want to do with characters is to make the text that theysay appear in a different color. This makes both the label and the text for whatever Jane saysappear in medium green:

    init:

    $ jane = Character("Jane", color="#009900", what_color="#009900")

    When defining characters with more than a few lines, it's a good idea to make the Ren'Py nameof the character as short as possible. So rather than:

    init:

    $ jane = Character("Jane")

    it's better to write:

    http://www.renpy.org/wiki/renpy/doc/reference/Defining_Charactershttp://www.renpy.org/wiki/renpy/doc/reference/Defining_Charactershttp://www.renpy.org/wiki/renpy/doc/reference/Defining_Charactershttp://www.immigration-usa.com/html_colors.htmlhttp://www.immigration-usa.com/html_colors.htmlhttp://www.immigration-usa.com/html_colors.htmlhttp://www.immigration-usa.com/html_colors.htmlhttp://www.renpy.org/wiki/renpy/doc/reference/Defining_Characters
  • 7/29/2019 Visual Novel guide

    9/30

    init:

    $ j = Character("Jane")

    It will save you a lot of typing in the long run, and is usually just as readable when you're editing

    your story.When definining more than one character, don't forget that they only have to be in aninit block,you don't need an init block for each one:

    init:

    $ j = Character("Jane")

    $ a = Character("Adam")

    $ s = Character("Sara")

    http://www.renpy.org/wiki/renpy/doc/tutorials/Ren%27Py_Script_Structure#inithttp://www.renpy.org/wiki/renpy/doc/tutorials/Ren%27Py_Script_Structure#inithttp://www.renpy.org/wiki/renpy/doc/tutorials/Ren%27Py_Script_Structure#inithttp://www.renpy.org/wiki/renpy/doc/tutorials/Ren%27Py_Script_Structure#init
  • 7/29/2019 Visual Novel guide

    10/30

    Your First Dialogue

    Basic Dialogue

    Dialogue in Ren'Py is extremely easy. Once you've defined a character, you simply prefix theirdialog, in quotes, with their name:

    bob "Hi Alice!"

    alice "Hi Bob!"

    For characters who have very little screen time, you don't need to create a character for them ifyou don't mind their dialogue appearing in the default style:

    bob "I wonder who this man approaching us is."

    alice "I don't know, but he looks tough."

    "Tough Guy""Yo. Whaddup?"

    bob "Hello."

    "Tough Guy""I'm oudda here."

    bob "That was strange."

    Narration

    Narration is simply dialog without anyone saying it:

    "The brief appearance of that tough guy left me feeling uneasy.

    Was it one of the rival noodle companies trying to intimidate me?"

    Spicing Up Your Text

    You can spice up your text using text tags:

    "Text tags let you render parts of a dialogue or narration

    in {i}italics{/i} or {b}bold{/b}."

    Text tags can do a lot of other things as well, check out the reference manual page onTextTagsfor more information.

    A word to the wise: text tags can be effective if used sparingly, but if used often they can maketext painful to read.

    http://www.renpy.org/wiki/renpy/doc/reference/Text#tagshttp://www.renpy.org/wiki/renpy/doc/reference/Text#tagshttp://www.renpy.org/wiki/renpy/doc/reference/Text#tagshttp://www.renpy.org/wiki/renpy/doc/reference/Text#tagshttp://www.renpy.org/wiki/renpy/doc/reference/Text#tagshttp://www.renpy.org/wiki/renpy/doc/reference/Text#tags
  • 7/29/2019 Visual Novel guide

    11/30

    Adding Graphics to Your Story

    Initializing the Graphics

    The first step in using a graphic image is to tell Ren'Py about it in an init block with animagestatement. You create a Ren'Py image from either solid colors or files (really, anyDisplayable):

    init:

    image black = "#000000"

    image bg park = "park.jpg"

    image eileen happy = "eileen1.png"

    image eileen sad = "eileen2.png"

    image eileen surprised = "eileen3.png"

    As you see, image names can be more than one word. We'll talk about why this is useful in thesection on hiding images. Image names and character objects don't have anything to do witheach other, so you can re-use character names as image names.

    Showing graphics before the game begins

    If you want to show a picture before the player gets to the main screen, then use the label"splashscreen" like so:

    label splashscreen:

    show opening picture name

    $ renpy.pause(2.0)

    return

    The line "$ renpy.pause(2.0)" will show the picture for two seconds. Change the number if youwant to show it for a different time. If you leave the brackets empty, so:

    label splashscreen:

    show opening picture name

    $ renpy.pause()

    return

    Then Ren'Py will show the picture until the player clicks the mouse or presses "Return".

    Scene Backgrounds

    Thescene statementclears the display of what's on it and optionally places a new backgroundon the display:

    scene bg park

    (Please recall that "bg park" is the name of the image; bg is not a keyword.)

    http://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#imagehttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#imagehttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#imagehttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#imagehttp://www.renpy.org/wiki/renpy/doc/reference/Displayableshttp://www.renpy.org/wiki/renpy/doc/reference/Displayableshttp://www.renpy.org/wiki/renpy/doc/reference/Displayableshttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#scenehttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#scenehttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#scenehttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#scenehttp://www.renpy.org/wiki/renpy/doc/reference/Displayableshttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#imagehttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#image
  • 7/29/2019 Visual Novel guide

    12/30

    Character Graphics

    Character graphics and other objects which are drawn in the foreground are displayed with

    theshow statement:

    show eileen happy

    A show statement without any modifiers shows the image centered in the screen. You can alsodisplay images on the sides:

    show eileen happy at right

    show eileen happy at left

    Custom positions

    Ren'Py already has some standard positions defined, but inevitably there will come a time whenyou want to position an image in a specific place.

    You do that by using Position:

    show eileen happy at Position(xpos = 0.5, xanchor=0.5, ypos=0.5,

    yanchor=0.5)

    xpos describes a point on the background to Ren'Py in terms of how far it is from the left-handedge. If you use a whole number (e.g. 129) Ren'Py will assume you mean pixels. If, as above,you use a decimal number between 0 and 1, Ren'Py will calculate it as a proportion of the width.So 0.25 would be interpreted as "a quarter of the way across the background from the left."

    xanchordescribes a point on the image you want to position, again in terms of how far it is from

    the left hand side. Just as in xpos above, use a whole number to count pixels, or a decimalbetween 0 and 1 if you want to describe it as a proportion of the width.

    Ren'Py now will show the image so that the xpos and xanchor points are in the same place.

    Reduce the xpos value to move it left, increase the xpos value to move it right.

    ypos and yanchorfollow exactly the same rules, describing to Ren'Py how far the point is fromthe top of the image. (So to move an image down, you need to increase the ypos value.)

    If you're going to use a custom Position more than once, then you can give it a name, like so:

    init:

    $ gardenpath = Position(xpos=0.5, xanchor=0.5, ypos=0.5, yanchor=0.5)

    Then you can use it just like any pre-defined Position:

    show eileen happy at gardenpath

    http://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#showhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#showhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#showhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#show
  • 7/29/2019 Visual Novel guide

    13/30

    Overlapping images

    When an image is added to a scene, Ren'Py adds it on its own, separate layer. By default eachnew layer is added on top of the ones which already exist.

    Most of the time images added to a scene do not overlap, so it doesn't matter which layers theyare on. However if you want to add the appearance of depth to a scene, then an easy way to dothis is to partly overlap the images. The player will interpret a larger image on the topmost layeras closest to their viewpoint, and a smaller image drawn partly behind it as further back into thescene.

    Imagine for a moment that we've made a background picture of a house with a garden, and wewant to show two characters: one in the foreground and one a little way behind that, who willappear to be halfway up the garden.

    In a real game you'd probably want to make custom positions for these images, but forsimplicity, imagine that they're drawn so that they'll be correctly positioned when they'redisplayed in the default position.

    Having the characters overlap correctly is no problem when beginning a new scene:

    scene bg houseGarden

    show distantChar

    show foregroundChar

    with dissolve

    However if the scene is already showing, and we want distantChar to appear (perhaps havingjust come out of the house), then:

    *** Wrong! ***

    scene bg houseGarden

    show foregroundChar

    with dissolve

    "The sounds of argument in the house cease and distantChar

    comes running out into the garden."

    show distantChar with dissolve

    *** Wrong! ***

    The code above will notgive the effect we want: distatChar will be added to a layer aboveforegroundChar, and so the overlapping will be the wrong way round.

    The way to get the effect we want is to use the behind keyword like this:

    ...

    "The sounds of argument in the house cease and distantChar

  • 7/29/2019 Visual Novel guide

    14/30

    comes running out into the garden."

    show distantChar behind foregroundChar with dissolve

    Now the images are correctly overlapped.You don't have to worry when you're using "show" to replace one image of a character withanother. Ren'Py will automatically place the new image on the same layer where the old onewas.

    Hiding Graphics

    Hiding graphics which were displayed with the show statement can be accomplished in threeways:

    Explicity

    First, you can explicitly hide a graphic which was shown using thehide statement:

    hide eileen

    If an image consists of more than one word, you only need to tell the hide statement about thefirst word (the "image tag"). This means that you don't have to keep track of the version of thecharacter graphic that you've shown most recently.

    Implicitly with show

    The show statement will automatically replace the image with the same image tag which uscurrently being shown (though not quite in the same way as a hide statement). For example:

    show eileen happye "I'm happy."

    show eileen sad

    e "Now I'm sad."

    does the right thing you don't get two copies of eileen on top of each other.

    Implicitly with scene

    The scene statement clears all images off of the screen, so if you're changing scenes you don'tneed to hide anything first.

    Special Effects

    All of the statements which show and hide images can be modified by adding a withclause (see:with statement):

    http://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#hidehttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#hidehttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#hidehttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#withhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#withhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#withhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#withhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#hide
  • 7/29/2019 Visual Novel guide

    15/30

    scene bg park with fade

    show eileen happy with dissolve

    There are many special effects available, but those are the two most commonly used. (It seems

    like only George Lucas can get away with stuff like side wipes, but if you want to try, you cancheck out the full list ofPre-Defined Transitions.)

    Getting What You Want to Happen, to Happen

    Neither the scene statement nor the show statement, on their own, immediately display to thescreen. Rather they queue images up, so if you combined them:

    scene bg park

    show eileen happy

    show ted happy at left

    it will display all at once. The with statement and clause both change this. So if you wrote this:

    scene bg park with fade

    show eileen happy with dissolve

    show ted happy at left with dissolve

    Ren'Py will first fade the background in, then dissolve eileen onto the screen, then dissolve tedonto the screen. To get a single fade into the new background with eileen and ted on it, use thestatement form of "with" after you've told Ren'Py what you want on the screen:

    show bg park

    show eileen happy

    show ted happy

    with dissolve

    (Please note: for historical reasons, this is not the same as:

    show bg park

    show eileen happy

    show ted happy with dissolve

    Which will cause the background and eileen to display without a transition and then show tedwith a dissolve transition. In general, if you're using more than one statement, only usethe with statement on its own line.)

    As a result of the show statement's queueing behavior, this won't work:

    show eileen happy

    show eileen sad

    show eileen morose

    http://www.renpy.org/wiki/renpy/doc/reference/Transitions#predefinedhttp://www.renpy.org/wiki/renpy/doc/reference/Transitions#predefinedhttp://www.renpy.org/wiki/renpy/doc/reference/Transitions#predefinedhttp://www.renpy.org/wiki/renpy/doc/reference/Transitions#predefined
  • 7/29/2019 Visual Novel guide

    16/30

    show eileen elated

    the reader will only see the last one. If you want to show several versions of a character withoutinteracting with the reader, you need to use the with clause to get them displayed:

    show eileen happy with dissolve

    show eileen sad with dissolve

    show eileen morose with dissolve

    show eileen elated with dissolve

  • 7/29/2019 Visual Novel guide

    17/30

    Giving the User a Choice with Menus

    Menus are implemented themenu statement, which is probably best explained by an example:

    menu:

    "Choice 1":"This is the result of the user choosing choice 1"

    bob "Hi Sarah."

    sarah "Hi Bob."

    "Second Choice":

    "This is the result of the user choosing the second choice."

    "The third menu option":

    "This is the result of the third menu option"

    bob "What up, Sarah?"

    sarah "Yo yo yo."

    "The fourth option doesn't do anything if you pick it":

    pass"The fifth option is a little different":

    bob "Hi Sarah. Hey, could you give me your sister's phone number?"

    sarah "Um, she doesn't have a telephone."

    Menu choices can be as long as you like, and you can have as many of them as you like,provided that they can all fit on the screen. The results of menu choices can also be as long asyou like, without restriction. Every line that's the result of a menu choice must be indentedbeyond the menu choice.

    Please note that every menu option must have at least one statement, so if you want the menuoption to do nothing, use thepass statement.

    http://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#menuhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#menuhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#menuhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#passhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#passhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#passhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#passhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#menu
  • 7/29/2019 Visual Novel guide

    18/30

    Remembering User Choices

    Changing Game Flow Based on Earlier Choices

    You can remember user choices by assigning to variables. For example:

    menu:

    "Buy her an Iguana":

    $ gift = "iguana"

    b "I'll take an iguana, my good man!"

    "Buy her a Corn Snake":

    $ gift = "corn snake"

    b "I'll take a Corn Snake, my good man!"

    "Buy her a tortoise":

    $ gift = "tortoise"

    b "Give me your slowest tortoise, please!"

    Please note that a single "=" is used to assign a variable.

    Later in the game, you can then use theif statementto change the script based on the previouschoice:

    b "Open it, Mary."

    if gift == "iguana":

    m "Oh Bob, I've always wanted an iguana!"

    if gift == "corn snake":

    m "Oh Bob, I needed a corn snake that matches my red dress! Thank you so

    much!"if gift == "tortoise"

    m "Bob! It's so slow! I love you!"

    Please note that the double "==" is used to test for equality.

    You can call your variables anything that you like, as long as it doesn't conflict with keywords orcharacter objects. The only rule with variables is that you have to assign to a variable beforeyou can use it in a conditional.

    Showing or hiding menu options

    Often, when you get to a particular point in a game, you'll want to tailor the options offered to the

    player depending on what they've chosen to do earlier in the game. Let's imagine that Bob andMary are going out on their second date, and the player gets to choose between the Park andthe Cafe - unless Bob gave Mary the tortoise as a gift, in which case they can go to the TortoiseLand Speed Trials!

    Here's how:

    http://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#ifhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#ifhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#ifhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#if
  • 7/29/2019 Visual Novel guide

    19/30

    b "So, where would you like to go, Mary?"

    menu:

    "I'd like to go to the park!":

    jump park_date

    "I'd like to go to the cafe!":

    jump cafe_date

    "Can we go tortoise racing?"if gift == "tortoise":

    jump tortoise_racing

    (Notice the two equals signs "==" between gift and tortoise.)

    The menu choice for tortoise racing will only appear when the result of the "if" test is true. IfMary was given a snake or an iguana, then the player will only be able to choose the park orcafe dates.

    This system can be easily adapted if you want to have the player returned to a menu, but tohide the options(s) which have already been chosen.

    First create the variables which the game will use.

    $ park_date_done = False

    $ cafe_date_done = False

    $ tortoise_date_done = False

    Notice that we use a single equals sign "=" because we're settinga value. Two equals signs"==" are fortestinga value.

    The names of variables can be any length you like, but can't contain spaces. The longer aname, the more descriptive it is, and so the easier it is to tell what it's for when you look back atyour script in a few weeks, months or year's time. Of course it's also more typing, so it's worthchoosing short names for variables that you'll use a lot.

    ...

    label date_choice:

    b "So, where would you like to go, Mary?"

    menu:

    "I'd like to go to the park!"if park_date_done == False:

    $ park_date_done = True

    jump park_date

    "I'd like to go to the cafe!"if cafe_date_done == False:

    $ cafe_date_done = True

  • 7/29/2019 Visual Novel guide

    20/30

    jump cafe_date

    "Can we go tortoise racing?"if gift == "tortoise":

    jump tortoise_racing

    "Let's just go home"if park_date_done ==True:

    jump date_over

    label park_date:

    b "Well, here we are, at the park!"

    m "Yes, it's very interesting. Can we do something else now?"

    jump date_choice

    label cafe_date:

    m "Gee, what an exciting cafe!"

    jump date choice # WRONG! should be date_choice

    label tortoise_date: # WRONG! Ren'Py will complain about this until you

    # correct it to "tortoise_racing"

    m "Well! A whole lot of tortoise-related fun!"

    b "Yeah, great."

    jump date_choice

    label date_over:

    "... and the game goes on from here."

    etc.

    The park and cafe dates can only be chosen once, because Ren'Py changes the value of thevariable concerned after the player chooses that option. At the end of that date, the "jump"instruction takes the player back to the date-choosing menu.

    However, the lucky couple can go tortoise racing as often as they want, because Ren'Py isn'ttold to change the value of "tortoise_date_done." (That variable is just wasted, although Ren'Pywon't complain.)

    Notice that you have to have at least one "Exit" option that doesn't loop back to the menu,

    otherwise the player will get stuck. The "Just go home" option will appear after they've been tothe park, because choosing the park option changes the variable the "Just go home" optiontests.

    Be careful not to make the "Exit" option the tortoise choice - otherwise players who gaveiguanas or snakes will likewise be stuck, since that option won't show up for them.

    Implementing a Point-Based Game

  • 7/29/2019 Visual Novel guide

    21/30

    A point-based game is one in which the choices that a user makes at menus cumulativelychange the story after many of them have been made.

    First, you'll need to decide what you want to be able to gain points for. For example, you mightwant the user to be able to win points by (1) building big muscles (strength) (2) learning to

    juggle large numbers of objects (dexterity) and (3) performing chemical experiments and

    creating increasingly advanced forms of life (mad science).Next, you'll need to initialize the variables that you're going to use to keep track of these points.You do this immediately after the start label:

    label start:

    $ strength_points = 0

    $ dexterity_points = 0

    $ mad_science_points = 0

    During the game, you'll present the user with choices that affect these points, and then modifythe variables based on the choices. To increase the points, use:

    $ variable += 1

    (That's plus followed by equals.) You can use any number, it doesn't have to be 1. To decreasethe points:

    $ variable -= 1

    (That's minus followed by equals.) You can again use any number, not just 1.

    For example:

    menu:

    "Go to the gym":

    $ strength_points += 1

    "The gym was hot and sweaty."

    "I picked up heavy things, then put them down again."

    "I always wonder why I bother, since I could achieve

    the same thing by not picking them up in the first place."

    "Practice juggling balls":

    $ dexterity_points += 1

    "I practiced juggling seven balls."

    "It was hard, but I finally managed to get it at least once.""Practice juggling angry porcupines":

    $ dexterity_points += 3

    $ strength_points -= 1

    "Practicing with angry porcupines really sharpened my reflexes.

    Unfortunately, I'm feeling weak from blood loss."

    "Invent a happy porcupine":

    $ mad_science_points += 1

  • 7/29/2019 Visual Novel guide

    22/30

    "Unfortunately I was only able to create a melancholy echidna,

    but I learned a lot and I was sure that next time would be better."

    (You can of course customize the responses based on the current points, using the techniques

    outlined in the earlier section on variables.)Finally, customize your ending using the variables:

    if strength_points > max(dexterity_points, mad_science_points):

    "You pick up a cow and jump over the moon."

    elif dexterity_points > max(strength_points, mad_science_points):

    "You juggle 215 balls and set the world record."

    else:

    "You create the perfect companion and retire with it to the castle

    built by the army of servile eight-armed giant gorilla-men

    you created earlier in the day."

    return

    The above code decides ties in favor of the last option (mad science). If you would like to beexplicit about how to handle ties, it's more complicated, as there are seven possible conditions,but still quite doable. It looks like this:

    if strength_points > max(dexterity_points, mad_science_points):

    "You pick up a cow and jump over the moon."

    elif dexterity_points > max(strength_points, mad_science_points):

    "You juggle 215 balls and set the world record."

    elif mad_science_points > max(strength_points, dexterity_points):

    "You create the perfect companion and retire with it to the castle

    built by the army of servile eight-armed giant gorilla-men

    you created earlier in the day."

    elif strength_points == dexterity_points == mad_science_points:

    "Your band of servile sixteen-armed giant gorilla-men built you

    three castles, which you juggle to impress the perfect companion

    you created earlier in the day."

  • 7/29/2019 Visual Novel guide

    23/30

    elif strength_points == dexterity_points:

    "You juggle three large boulders and many attractive people of

    the opposite sex swoon."

    elif dexterity_points == mad_science_points:

    "You invent a species of round humming bird, and juggle 5,000

    of them at once."

    elif strength_points == mad_science_points:

    "You invent a 30 ton 24-armed gorilla man, and then pick him up

    so that he can paint the top part of the house he's building

    for you."

    return

    The ordering of the conditions above is important, because later alternatives assume thatprevious ones have been false. In general, you want to first test if any single variable wins, thentest if they're all the same, then test to see which ones tied. This strategy avoids severalpossible pitfalls in the game logic.

  • 7/29/2019 Visual Novel guide

    24/30

    Branching & Recombining the Story

    Short branches can be accomplished entirely with the menu statement by including the entirebranch indented after the menu option. For longer branches, however, this will get cumbersome.The solution is to use labels and thejump statementor thecall statement.

    The first thing that you'll have to decide is whether you're going to use call or jump. Jump simplychanges where in the script Ren'Py is executing, and that's it. The new place of execution in thescript can only move forward; there's no such thing as returning from a jump, though you couldalways jump to a label after the original jump. Thus you can't easily re-use jump-branches frommultiple places in your script. For a visual novel, jump will probably be sufficient.

    Call, by contrast, saves information about where you were, so that the branch being called canautomatically return to the right place. With call, you can easily re-use branches. Dating simswill probably want to use call.

    You can, of course, use both types of branching in the same visual novel (or dating sim). Mixingand matching is fine, so long as any single branch is only either a call-branch or a jump-branch..

    Branching with JumpThe first step of branches using jump is to mark places in your script using thelabel statement:

    label jewelry_store:

    b "Let's go to the jewelry store. I'd like to buy you something."

    s "You're so sweet!"

    Next, you add the jump to the branch:

    s "What do you want to do?"

    menu:

    "Let's go to the jewelry store":

    jump jewelry_store

    #we'll never go past the jump statement, since it doesn't return

    "Let's do nothing":

    s "This is boring."

    http://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#jumphttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#jumphttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#jumphttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#callhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#callhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#callhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#labelhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#labelhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#labelhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#labelhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#callhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#jump
  • 7/29/2019 Visual Novel guide

    25/30

    Congratulations, you've branched with jump!

    Unless this branch runs to the end of the game, you will probably want your branch to jump to otherplaces in the script. This is done in the same way; branches are not special and you can jump toanywhere you want even though you're in a branch. For example, suppose that in the above example youwant to go back to after the menu from the branch. First, you add a label after the menu so that you havesomewhere to jump to:

    s "What do you want to do?"

    menu:

    "Let's go to the jewelry store":

    jump jewelry_store

    #we'll never go past the jump statement, since it doesn't return

    "Let's do nothing":

    s "This is boring."

    label what_to_do:

    b "Well, now what?"

    Then you add a jump to the end of the branch:

    label jewelry_store:

    b "Let's go to the jewelry store. I'd like to buy you something."

    s "You're so sweet!"

    b "I am."

    s "Well, that's enough. Let's go back."

    jump what_to_do

    Please note that labels have to be unique within a Ren'Py script.

    Branching with Call

    The first step of branches using call is to mark a branch in your script using thelabel

    statementand thereturn statement:

    label jewelry_store:

    b "Let's go to the jewelry store. I'd like to buy you something."

    s "You're so sweet!"

    etc.

    return

    http://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#labelhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#labelhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#labelhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#labelhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#returnhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#returnhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#returnhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#returnhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#labelhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#label
  • 7/29/2019 Visual Novel guide

    26/30

    (NOTE: it's very important that a call-branch should never be entered either with a jump or bynormal script flow. If it is, the return statement at the end of the branch will cause the game toimmediately end. A return statement outside of a call is actually the correct way to end thegame: the metaphore is that since the game came from the starting menu, a return statement inthe main story would go back to the starting menu.)

    Next, you add the jump to the branch:

    s "What do you want to do?"

    menu:

    "Let's go to the jewelry store":

    call jewelry_store

    s "That was fun"

    "Let's do nothing":

    pass

    Congratulations, you've branched with call! Unfortunately, you're not done.You don't need to do anything while you're still writing your game, but when you're ready torelease your game, you'll need to run the "Add From to Calls" tool in the Ren'Py launcher to addlabels below your call statement and from clauses to all of your call statements.

    Reaching the End

    Your story may have more than one ending, or just a single ending. Games with just a singleending and no choices are often called Kinetic Novels rather than Visual Novels, just for clarity.

    Regardless, when the player gets to the end, you'll probably want to make it a bit of a specialevent. Perhaps with a specially drawn picture or an animation, but at least a screen saying "THEEND".

    If your game has more than one ending, it's worth considering giving each ending a name, or atleast numbering the endings. This helps when people are discussing your game, since they canbe sure that they're talking about the same ending without having to actually describe it (and sorisk giving out spoilers.)

    Imagine your story is about characters getting together and planning a party. You've a lovelyfinishing image of all your characters whooping it up, which you declared in the usual way:

    init:

    image party ending = "party.jpg"

    If your ending has a line of text being shown, the ending scene is really easy to write:

    "Chris smiled."

  • 7/29/2019 Visual Novel guide

    27/30

    c "Well, that seems to be that!"

    scene party ending

    "And everyone partied happily. \n\nEnding 3 - Neighbourhood Party"

    return

    The "return" tells Ren'Py to go back to what it was doing before the player started playing -which was showing the main screen.

    Ren'Py always waits for a response from the player when it shows text, so this works fine.

    However, if you want to show an image without having part of the screen taken up with thedialogue box, then there is a problem.

    If you write:

    "Chris smiled."

    c "Well, that seems to be that!"

    scene party ending

    return

    Then you will find that the party image will be shown only briefly before the game returns to themain screen. We need to tell Ren'Py to pause so that the player can enjoy the art.

    Happily that's easily done: the instruction is $ renpy.pause().

    Like so:

    "Chris smiled."

    c "Well, that seems to be that!"

    scene party ending

    $ renpy.pause()

    return

    Now the picture will be shown until the player clicks the mouse.

    A Note on Organization

    There is no consensus on the best way to organize branches. It is, however, recommended thatyou come up with some way to organize your branches and stick to it.

  • 7/29/2019 Visual Novel guide

    28/30

    If you use multiple files to organize your script, please bear in mind that labels are visible fromany file, so jumping to a label in a different file is exactly the same as jumping to a label in thesame file. Since labels have to be unique in a Ren'Py script, this means that you can't re-uselabels in different files of the same Ren'Py game.

  • 7/29/2019 Visual Novel guide

    29/30

    Chapters

    Just like a traditional story, you might want to divide your Visual Novel up into chapters (or Acts,or any other story-telling chunk which makes sense in the context of your work.) Here's how.

    scene black with dissolve

    show text"Chapter 1\nA Frightening Sight"with Pause(1.5)

    scene black with dissolve

    scene your_scene_title

    e "And now the story really begins."

    The code above will cause Ren'Py to fade to a black screen, showing "Chapter 1" centered onthe screen, and below it on the next line "A Frightening Sight", also centered. (The "\n" means"new line".) After a pause of 1.5 seconds, the text will fade out again.

    If you just say:

    show text"Chapter 1/A Frightening Sight"with Pause

    then "Chapter 1" etc. will stay on the screen until the player clicks or hits Return.

    "black" (note the lower case "b") is the only color which Ren'Py knows about by default. If youwant to use a different color as the background for your chapter titles, then you'll have to set

    that up before you can use it, in an init block, like so:

    init:

    image black = Solid((0, 0, 0, 255))

    image white = Solid((255, 255, 255, 255))

    image grey = Solid((128, 128, 128, 255))

    Just google for "web colors" if you don't know what the values in brackets should be for the coloryou want.

    Note that there's nothing special about this "Chapter scene" - you don't have to use a Solid color

    if you don't want to. A custom scene-title .jpg would work just as well.

  • 7/29/2019 Visual Novel guide

    30/30

    Adding Music & Sound Effects

    Music

    To play background music (which loops until you stop it), you use theplay statement:

    play music "ominous.ogg"

    To use fade-in or fade-out (in seconds):

    play music "ominous.ogg" fadein 2 fadeout 2

    To stop the background music, you usestop statement:

    stop music

    Sound Effects

    To play a sound effect, use theplay statement:

    playsound"bang.ogg"

    There's a Ren'Py function to stop sound, but there's usually no reason to use it.

    Voices (Voice Acting)

    If you want to add voice acting to your visual novel, you'll need to put each screen of dialog intoa separate file, and name them in a way that you can figure out which line of dialog they go with.

    Then, before each line of dialog, put avoice statement:

    voice "bob203.ogg"

    bob "I love ice cream."

    voice "nancy218.ogg"

    nancy "I love ice cream too."

    voice "bob204.ogg"

    bob "I also like cookies."

    http://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#playhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#playhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#playhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#stophttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#stophttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#stophttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#playhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#playhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#playhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#voicehttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#voicehttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#voicehttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#playhttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#stophttp://www.renpy.org/wiki/renpy/doc/reference/The_Ren%27Py_Language#play