DEVELOPMENT CORNER
Ren'Py 101: Writing Your Script Part II
by Rio

Here, we'll finish up learning the rest of the things you may want to put in your script and we'll end with preparing for the release of your game by covering how to make a README file. As usual, what I'll be covering:

1. Variables and If-Else Logic

2. MPEG Movies

3. Music and Sound Files

4. Text Styles with Text Tags

5. Restarting the Game

 
1. Variables and If-Else Logic

To make a variable, it follows the same general outline of a python statement which is: $ variable_name = value
The most common variable types you will most likely be using are the True-False variable and the more versatile value-based variable. For example:

$ date_with_minako = False
$ points = 0

It is best to set up the main variables to be used within the game as it starts (i.e. the first label at the start of the story). To change the value of the variable, you have to make the change somewhere in the game. To change the values, just set the variable to True for the True-False type and incrementally increase or set another value to the variables that require numbers.

$ date_with_minako = True <--- change value of True-False variable
$ points += 1 <--- change the value of variable incrementally
$ points = points + 1 <--- another way to change the value incrementally
$ points = 5 <--- directly change the value of the variable

Below, we have a short-handed example of the variables being set at the beginning of a script, how it is changed in the game, and how it will ultimately decide the ending of the story.

label start:

    $ save_name = "Beginning"

    $ date_with_minako = False # for special ending with Minako
    $ points = 0 # for Aiko ending (default endings)

    scene ocean
    m "Hey, Umaru!"

(fast forward script to variable changes)

    menu:

        "Enter competition.":
            "I signed my name on the competitor's list."
            points += 1 # Aiko points increase by 1
            jump enter_competition

        "Don't enter.":
            u "No way! I'd rather watch."
            date_with_minako = True # Get Minako ending
            jump watch_competition

(fast forward script to the end)

    if date_with_minako: # if date_with_minako is True, this will be executed.
                         # If Not True,


        jump minako_ending # Ren'Py will go down to next if statement....

    elif point >= 20: # if points is greater-than-or-equal to 20, game will
                      # proceed to best ending


        jump best_minako_ending # otherwise, Ren'Py will go down to next if                                 # statement...

    elif points <= 9: # if points is less-than-or-equal to 9, worst ending will
                      # be played


        jump worst_minako_ending # if condition is not met...

    else: # Ren'Py will automatically execute the last statement which is always
          # an else statement.


        jump med_minako_ending

The ending makes use of the if-else logic. Basically, when one statement is not met (i.e. True), Ren'Py will keep going down the list until one of the conditions is met or it reaches the last statement (else) and executes it. If one of the condition(s) is met, it will follow the statement after it. Here is the standard format for the if-else logic:

if condition:
python statement

elif condition: # elif is short for else-if
python statement


else:
python statement

Yellow denotes that it is optional. You can have just a simple and direct if-else logic but in most cases, you will need to make use of an if-elif-else logic. You can have as many eif as you want, btw, but just make sure you start with if and you end with an else. Don't forget that the if, eif, and else line ends with a colon!

For more complex conditions and operators* you may use, here are some examples:

if (variable1 == variable2) and (variable2 == variable3) and (variable3 == variable1):

if (variable1 > variable2) and (variable1 > variable3):
# must spell out "and", can also use "&&", but not "AND"

if (variable1 == variable3):
# == means the comparable equal and not placing a value to a variable as with a
# single "="


if (variableA >= 5) or (variableB >= 5):
# can also use double pipe symbol (||) to represent "or"

*Operators are those used in math: =, +, -, <, >, %, *, !, and, or, xor, etc. Much like you have learned in math, operators are executed in a logical order like those in parenthesis are evaluated before other operators.

Back to Dev Corner | Back to Top

2. MPEG Movies

Playing MPEG-movies is a recent feature added into Ren'Py. So far, it has not been used in any released Ren'Py game aside from the demo but I'm sure it will be used soon. Basically, to play a movie in fullscreen mode with Ren'Py, you just have to follow the python statement with yellow being optional:
$ renpy.movie_cutscene('moviename.mpeg', delay, loops=value)

moviename.mpeg - the name of the mpeg file you want to play.

delay - the amount of seconds before ending the cutscenes. Usually the length of the movie. Optional.

loops=value - Number of times the movie will show again. 0 means once (default). -1 will loop movie infinitely. Optional.

$ renpy.movie_cutscene('Eisenhow1952.mpg', 63.0)

Above is the actual script used from the Ren'Py demo. Notice that "delay" is used but "loops" is not.



Eileen: "It's like I'm some sort of newscaster or something."
Video clip from Ranma 1/2.

Ranma 1/2 © Rumiko Takahashi, Shogakukan Inc, and Viz Comm.
Eileen © PyTom. All rights reserved.

Playing a movie fullscreen is not the only way you can display an mpeg movie. You can also have a displayable which shows the movie along with the rest of your game, complete with overlays and underlays as shown to the right. Like Eileen says in the demo, "Ren'Py can even overlay rendered images on top of a movie,
although that's more taxing for your CPU."

The actual structure of the displayable python statement is as follows:
$ renpy.movie_start_displayable('filename', (size_width, size_height), loops=value)

filename - name of the mpeg file

size_width/height - the width and height of how you would like to display the video. For example, (320, 240).

loops=value - much like previously stated, this is the number of times the movie will show. 0 means once (default value). -1 for a continuos loop. This is optional to put in, btw.

To put it in a displayable like in the Ren'Py demo, you have to declare a value for movie first in an init label like this:

init:
    image movie = Movie()

Then you can set the layers, including the movie, the displayable command, and proceed with the script from there. Here is an excerpt directly from the Ren'Py demo:

init:
    image movie = Movie()

    (fast forward script a bit)

label movie:

    hide eileen
    show movie at Position(xpos=420, ypos=25, xanchor='left', yanchor='top')
    # Sets movie layer including location, made possible with the Position()
    # function.
    # Otherwise, if you'd like to just show mpeg in middle of screen, just type
    # "show movie"

    # You can also opt to show mpeg as a background by using "scene movie"
    # instead.

    show eileen happy

    $ renpy.movie_start_displayable('Eisenhow1952.mpg', (352, 240))
    # plays the mpeg and sets size

    e "Ren'Py can even overlay rendered images on top of a movie,
       although that's more taxing for your CPU."

    e "It's like I'm some sort of newscaster or something."

    $ renpy.movie_stop()
    hide movie

To stop the movie, you have to put in the $ renpy.movie_stop() python statement. Also note the use of "hide movie" which hides that movie layer much like it would for a character layer. There is no set order to do these two - you can have hide movie first if you want - but just make sure you have these two declared in the end.

Note: A player can click to interrupt the cutscene and continue the story. They can also rollback and re-play the cutscene if they want. While the movie is playing, overlays and underlays are disabled (i.e. background scenes, dialogue boxes, etc) unless it's in the displayable mode. If you're playing the movie in windowed mode and you minimize the screen, the movie will still remain where it is and quite viewable (this applies for Windows, not sure if applicalbe to other OS's).

Back to Dev Corner | Back to Top

3. Music and Sound Files

Music and sound files are that extra feature that gives your ren'ai game that extra punch when released. There is a big difference between the two though they may sound the same at first glance. Sound files takes care of short files such as those for the interface (button click sound, error sound, etc) whereas music files takes care of the longer, more in-depth files (i.e. background music).

There are two ways sound files may be set into the game. The first kind is for the interface, to which Ren'Py already comes packaged with. The sounds and the actual setting of them are already in the script file, right under the mainmenu and frame lines under the init label.

# Interface sounds, just for the heck of it.
$ style.button.activate_sound = 'click.wav'
$ style.imagemap.activate_sound = 'click.wav'
$ library.enter_sound = 'click.wav'
$ library.exit_sound = 'click.wav'

The second way to set a sound file is inside the script itself. This could be a short sound effect like clashing of swords, punching, running, and the like. This is the basic python structure of a sound file in-game:
$ renpy.play("filename", loops=value)

There are some important notes regarding sound files. They include:

1. The file must be a wav file and must be at a sample rate of 44100hz*, 16 bit, stereo. You can have a wav file without these settings but it will take awhile for Ren'Py to convert it.
* can be changed with config.sound_sample_rate

2. Once it is played, there is no way to stop the sound file.

scene racetrack
$ renpy.play("audio/race_cars_passing_by.wav", loops=-1)
show announcer happy

Now let's get to the more useful part, playing music! As stated in the Reference Manual, Ren'Py can technically support playing "any format SDL_mixer supports (mp3, ogg, midi, mod, and more)", but mp3, ogg, and midi support are the only ones used so far. No worries, they are what you will most likely be using anyways.

There are some things to note about music files as well, namely:

1. Music files cannot be archived. They will not work properly, otherwise.

2. Music files must be placed within the game directory. They may be put in their own folders but it must be under the game directory, though.

3. If the filename is renamed or mistyped within the game, Ren'Py will not play the music file. The game will proceed without any traceback or notices unlike for missing image or scene files so be noteful of this and be careful (i.e. test like crazy before releasing)

Now that you've got those down, here is the two most important python statements regarding music files:

$ renpy.music_start('filename', loops=value, fadeout=0.0)
$ renpy.music_stop(fadeout=0.0)

Music_start() will play your music file automatically once Ren'Py reaches this line. If another music file is already playing, the new music_start() will stop the older music and play the new called music file. Version 4.8 of Ren'Py introduces a new parameter "fadeout=0.0" to both music_start() and music_stop(). Basically, this is the number of seconds the music will take to fade out or fade in the currently playing music. If set to "None", music will stop and start abruptly.
On another note, 4.8 no longer supports the parameter: "startpos=0.0".

If you would prefer not having your music stop abruptly in between changes of music, you can use the python statement:
"$ config.fade_music = 0.0" with the value afterwards being the amount of time in seconds to fade the old track before starting the new track. To use this, though, you have to have the renpy.music_start() begin in the next line, like this:

$ config.fade_music = 5.0
$ renpy.music_start('music/fear.mid', loops=-1)

Back to Dev Corner | Back to Top

4. Text Styles with Text Tags

Text styles offer the control needed to emphasize words and expressions in dialogue. With it, you can punctuate instances by bolding, underlining, or italicizing them. You can also manipulate the size of the text from small to large and change it's color if you like. If you're familiar with HTML, it's much the same format but it uses {} instead of <>. If not, all you have to remember when using text tags is to start it with {command} and end it with {/command} which tells Ren'Py to stop applying the style to the text.

List of Text Tags.

(Name of ability - opening tag and then closing tag - notes)
Bold - {b} {/b}
Italic - {i} {/i}
Underline - {u} {/u}

Size - {size=value} {/size} - value may be positive or negative in number and adds/substracts from the default font size which is a 22 on Vera.ttf. If subtracting {size=-2}, for example, then the font size will decrease to 20.

Color - {color=#rgb} {/color} - RGB is the value you must declare to change the color. There is no fourth number/letter to worry about which is for opacity. For this, you have to declare the hexadecimal value which is comprised of letters (A to F) and numbers (0 to 9). Web safe colors usually have the numbers 0, 3, 6, and 9 with letters C, and F within it.
For a list of colors in hexadecimal and numeral format, check out the Hue Color Chart which is also found in the Development Corner page.

Note: If, for some reason, you want to use a left brace in your script, just double it into so {{, and a single left brace will show up.

rio "Hey, there!"
rio "I'm going to {i}demonstrate{/i} the {b}awesome{/b} power of {u}Text Tags{/u}!"
rio "{size=+6}I can shout!{/size}"
rio "{size=-4}Or I can whisper...{/size}"
rio "Just by changing the font size."
rio "I can also play around with the color, check it:"
rio "{color=#f00}Red{/color}, {color=#0f0}Green{/color}, and {color=#00f}Blue{/color}."
rio "Neat, huh?"
rio "I can also mix up all the text tags {b}for more {i}versatility{/i}{/b}."
rio "But don't get too {size=+4}{color=#000}crazy{/color}{/size} with text tags..."
rio "or else readability and overall enjoyment of your game will suffer!"

Should you decide to mix the text tags, make sure you start and end them in order. For example, if you open with a color tag and then follow it with a bold tag, then you should close it with the bold tag first and follow it up with the color tag like so: {color=#fff}{b}Correct way to open and close text tags{/b}{/color}.

Back to Dev Corner | Back to To

5. Restarting the Game

There is only one way to restart the game. Just type out the words as shown in the example below and it'll automatically do it's function.

# Starts game from main menu
$ renpy.full_restart()

I use this when ending the game after the credits but if you'd rather just quit the game entirely, that is possible as well using the "return" command like so:

show text "The End!"
$ renpy.pause(3.5)
hide text with fade
scene black
$ renpy.pause(5.5)

return # Quits the game entirely

<<Writing Your Script Part I | Back to Dev Corner | Releasing Your Game Part I>>

 


Content© 2005 www.RenaiGames.net & RenaiGames.com, unless otherwise specified. All rights reserved.