DEVELOPMENT CORNER
Ren'Py 101: Starting Out Part II
by Rio

Welcome to the second part of a six-part series of tutorials on Ren'Py. If you haven't read through it already, I suggest you read over Part I. There are pertinent information on avoiding errors in there. Anyways, here is an overview of the topics I will covering in this tutorial:

1. Backgrounds & Transitions

2. Character Images

3. Character Objects

4. Character Animation Images

 
1. Backgrounds & Transitions

image renaigames = Image("renaigames.jpg")
image title = Image("title.png")
image bedroom1 = Image("bg_bedroom1.gif")
image bedroom2 = Image("bg_bedroom2.gif")
image sky = Image("bg_sky.gif")

Background declaration lines are composed of the following from left to right:

image - a default word that tells Ren'Py that it is dealing with and will display a picture on the screen

name - a name unique to this particular image. When calling this background in your script, you type this name. (ex/ "scene sky" will call forth the image file "bg_sky.gif") The name may be comprised of numbers and letters or alphanumeric as it is called technically and underscores may be used (i.e. "_"). Make sure you start the name with a letter and not a numbe or underscore.

This is case-sensitive, so I suggest you keep everything in lowercase letters to make things easier. I also recommend you make the name of the file something that relates to the background image you will use. If you look in the examples above, the file name and the name as it will be called in the script are basically the same.

=
- basically tells Ren'Py to take the file name declared on the right and make it the value of "name".

Image("imagename.*")
- the default method of declaring an image file. The only thing you have to worry about is changing the imagename.* portion of the script. Imagename refers to the filename of your graphic while the wildcard (*) refers to the file type (i.e. jpg, gif, png).

Now that you've learned how to set backgrounds, all you have to do to actually have them show up in your game is to use the "scene" command. For example,

scene bedroom1 with fade
"I cracked my eyes open to see where I was going "
"and to prevent myself from knocking something over -"
"TA-THUD"
"Ooops - too late."

Let's take a closer look at the above sample. "scene" tells Ren'Py to take the called image and place it at the lowest layer, automatically placing it as the background image. "bedroom1" is the called image that Ren'Py will take and display. As declared in the backgrounds section, "bedroom1" is the file "bg_bedroom1.gif". These two are the only commands you need to type when displaying backgrounds.

"with fade", on the other hand, is an extra feature in Ren'Py allowing for better presentation. This is one of the many transitions available. Other transitions include:

fade
dissolve

wiperight
wipeleft
wipeup
wipedown

slideright
slideleft
slideup
slidedown

slideawayright
slideawayleft
slideawayup
slideawaydown

irisout
irisin

All you have to do to use these transitions is type "with" and the transition type. For example, "scene bedroom1 with irisout". Transitions are nice effects but much like your PowerPoint presentations, it is best to stick to one or two transition types - preferably in the same grouping such as fade and dissolve or irisin and irisout.

On a side note, you may notice that the image types for backgrounds varied from png, gif, and jpg. Work with what's best for the game - try to balance between getting the lowest file size and keeping the quality of your image intact.

Back to Dev Corner | Back to Top

2. Character Images

image rover = Image("Rover.png")
image slurp = Image("Slurp.png")
image corus normal = Image("corusN.png")
image corus happy = Image("corusH.png")
image corus vhappy = Image("corusVH.png")

Declaring character images are much like declaring backgrounds except for an extra option of adding in an emotion type such as normal, happy, sad, etc after the "name" of your image. If you have a character that only appears once, you may opt not to declare the emotion type as in the first two lines of the above example.

But usually, the case for characters is that you have to declare an emotion type or else face making a staid unresponsive character. Corus, from Garden Society: Kykuit, for example has normal, happy, and vhappy (short for very happy) as some of his emotions. If you look at their respective filenames, you see the names "corusN.png", "corusH.png", and "corusVH.png". The capitalized letters after his name tells me the mood of the character. N is short for "normal", H is short for "happy", and so forth. This brings me to an important note...

When naming your character images, particularly those games with multiple characters, make sure you name the character as well as the state of his or her mood. You can adopt my method or you can make your own. Just don't make them completely random like the example below:

# I don't recommend you declare images like this!
image corus nA = Image("corusn0.png")
image corus nB = Image("corusn1a.png")
image corus h = Image("corus.png")
image corus s = Image("sad.png")

To call character images in your script, you have to use the "show" command. "Show" specifically tells Ren'Py that it's dealing with a character image and that it must be placed in the middle set of layers (i.e. on top of backgrounds but below the dialogue box). To use "show" properly, you have to remember to also state the emotion of the character unless there is no emotion stated as in the case of Rover in the first example box. If you forget to state the emotion, Ren'Py will throw you an error message.

show vivian normal
"the bearer of the voice, came into view -"
show vivian happy
"Female" "\"Thank you.\""
hide vivian
show groupie normal
show vivian happy
"she said with a smile and a nod, before moving on."
hide vivian
"I found myself staring after her in stunned silence..."

The above sample of coding from Garden Society plays with the layering aspects of Ren'Py. It calls for one character to show onscreen. After a bit, the character "Vivian" is flanked by her "Groupie" behind her. To do this correctly, one has to call Vivian first but when the groupie comes in, you have to reset the layers. To reset it, you hide Vivian, call the Groupie image, and then recall the Vivian image on top of that. If you don't reset the character images, you will have them in the incorrect layer order... and let's just say it's a mess. Visually, here's what happens if done correctly:

Vivian by herself Vivian and her groupie Groupie by themselves
Vivian by herself ---> Images are reset and reshown in correct layer order ---> Vivian goes offscreen leaving Groupie

show vivian normal at left
show corus blush at right
c "\"Oh!\""
c "\"...H-Hi, Vivian!\""

2 characters onscreen 3 characters onscreen

Another extra feature of the "show" command is playing with alignment. When no alignment is specified, the character image is automatically shown at the center of the screen. Your other alignment options are adding "at left" or "at right" to your show line. You can simultaneously show one character at the left and the other on the right as shown above. You can also show three characters at the same time like this:

show randel worried at left
show nadine normal
show corus tiredA at right

Note: If you try to show both characters on the same side, the most recent character with the "show" command will replace the previous character and you will end up with just one character onscreen.

As with backgrounds, you can also add transitions to your characters when they show up onscreen.

show randel worried at left with dissolve
show nadine normal with fade
show corus tiredA at right with dissolve

Another interesting feature of Ren'Py is layering multiple images together just by adding an objectname (example: beret) after the emotion and adding the second image after the first layer (example:"beret.png") as highlighted in yellow. This feature was actually made to use a paperdoll-like method which ultimately helps keep image sizes small.

image eileen happy beret = Image(("9a_happy.png", "beret.png"))

When using this feature, you have to make sure you align the second image ("beret.png") at the correct position which in on top of eileen's head for the beret. For more ideas regarding the above feature, check out the Layering Images thread at the Lemma Soft forum.

Last but not least, the best image file type to use is PNG which supports transparent backgrounds and can work with both black and white as well as colored images. PNG files also support more colors than gif files and can have blurred edges without the edges of the character getting a white halo effect. BUT, gif files tend to take up less space than png files. In the end, experiment, and work with what's best for you.

Back to Dev Corner | Back to Top

3. Character Objects

Character objects are there to make life easier for you (okay, they don't technically but they make coding easier so isn't it the same? ^_^). Basically, it saves you time by not having to repeatedly type out a characters name. The only one's you should make a character object are those who will talk in the game a lot. It's kind of pointless if you make a character object for say, "Stranger", or someone with only one speaking line. Anyways, below are the character objects in the game Amgine Park.

$ b = Character('Brent', color=(000, 153, 255, 255)) # periwinkle
$ e = Character('Era', color=(204, 255, 204, 255)) # light green
$ g = Character('Gen', color=(255, 153, 153, 255)) # carnation
$ r = Character('Rover', color=(255, 153, 102, 255)) # orange or brown

From left to right, here is what everything means:

$ - This tells Ren'Py that the line is a python statement. Basically, all you need to know is that if the statement has an equal sign anywhere in the line, whatever is after the dollar sign is a variable that will be saved and become a persistent data throughout the whole game. If it doesn't have an equal sign after the dollar sign, usually, it just calls an already declared python control such as starting music ("$ renpy.musis_start('dream.mid')" ), or restarting the game ("$ renpy.full_restart()"). For a complete list of these controls, check out the Ren'Py Reference Manual.

characterobjectname - This is the shorthand for the character's name (example, b for "Brent"). If no character has the same name, I suggest you stick to the first letter of their name. Otherwise, you can use some kind of shorthand like using the character's initials.

Character('charactername', color=(x, x, x, 255)) - This is the basic formula of setting a character object. The things that you can change are the characters name in the single quote and the RGB numbers. The character name within the single quote is what will appear in the dialogue box. If you mess up and put something like 'brent' instead of 'Brent', the name with the lowercase will be the one that shows up in the game. So make sure you double check this if the name appears wrong.

When using the character object in-game, all you have to do is type the characterobjectname and then follow it with the dialogue in quotes. For characters that do not have a character object declared, all you have to do is put the characters name in quotes, enter a space, and then follow it with his/her sentence. If you do not enter a character object or a manually entered character name, the dialoque will appear in game as a thought or a narrative.

"Distant Sound" "Woof! Woof!" <--- Manually entered character
g "Huh?" <--- Character object in use
"Gen looked around for the source of the sound," <--- Thought or narrative
"when she caught sight of something heading her way."
g "Oh, Rover! How's it going, boy?"
r "Woof!"

For GSK, I did something slightly different with the spoken dialogue. They will be surrounded by quotes when they appear in the dialogue box like so:

Corus
"Not that I have a good memory in the first place!"

The trick to doing something like this is to character escape the extra quote's around the sentence:

c "\"Not that I have a good memory in the first place!\""

In a discussion at the Lemmasoft forum, PyTom mentioned a faster way of doing this rather than manually coding all the character escape quotes which makes for one heck of a debugging session if you're careless. This is basically how he explains it:

"When you declare a character, you can define the what_prefix and what_suffix, which give text that is prepended and appended to the line of dialogue that is being said (respectively). So you can write:

init:
$ cima = Character("Cima", what_prefix="\"", what_suffix="\"")

cima "You'll probably find it out, eventually."

And that line of dialogue will show up in quotes when it is run.

Back to Dev Corner | Back to Top

4. Character Animation Images

Getting to animate your character is a wonderful experience to have. Even if it is a simple animation as making your character blink, it comes that much closer to having your character become alive. Not to mention it's just darn cool. Thankfully, animating your characters in Ren'Py has been greatly simplified for the Average Joe. It follows the basic set up of character images with some slight additions, namely, the time delays (i.e. the numerals after the image filename).

image brent happy = Animation("Brenthappy1.png", 4.00, <--- Initial image and
                                                         time delay

                                "Brenthappy2.png", 0.25,
                                "Brenthappy3.png", 0.25,
                                "Brenthappy2.png", 0.25) <--- Starts from
                                                        beginning when this ends

The first three words are much like naming a character image: image, followed by the charactername, then the emotion, and an equal sign. After that Image("filename") is replaced with Animation("filename", timedelay, "filename", timedelay, etc).

What Ren'Py basically does is call the first image - in the case of the example, Brenthappy1.png - and holds that image for X amount of seconds, and in our case, 4 seconds. After the initial time delay is up, it goes down the list and shows the next image and holds it for the specified time. It continues down the list until it reaches the end and goes back to the beginning.


In our example, Brenthappy1.png is shown and held for 4 seconds and then Ren'Py shows Brenthappy2.png, holds it for 1/4 of a second, goes to Brenhappy3.png, holds it for another 1/4 of a second, and ends with Brenthappy2.png and holds for a quarter of a second. When it completely goes through the list, it jumps back to the beginning and holds Brenthappy1.png for another 4 seconds before cycling through the whole process again. When showing, Brent is shown as having his eyes open and then quickly closing and opening his eyes again as shown above.

The animated version will be something like the image on the right albiet, in the actual animation, Brent holds his open eyes much longer. If you do not have a flash-player, here's the animated gif version which completely looks ugly because his face got messed up during conversion to gif. Now he looks like he has chicken pox. T_T

Anyways, when calling your animated image in your script, it's exactly like calling a regular character image: "show brent happy". For animations, you can use gif or png files but again, I recommend you use png files just because you have a lot more colors to work with and you don't have to worry about white pixels showing up around your character.

Note: When playing the game and reading through the dialogue boxes, I've noticed the animation completely stopping at times before restarting when a new show command is run. A slight imperfection but animation in Ren'Py is non-the-less well executed. Also, for some reason, you can't use animated gif files in Ren'Py. If you don't believe me - try it out yourself.

Hey, you can stop looking at Brent blink now! :D

<<Back to Starting Out Part I | Back to Dev Corner | Writing Your Script Part I >>

 


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