Skip to content


For more information about the basics of Ren'Py animation and transitions we will kindly refer you to a youtube tutorial of your choice or the Ren'Py documentation. This will help to make your scene and character changes look less like an adventure into the deep-end of high-ping gaming and provide more smoothness to their movement. A good starting point are the sections on transitions and the more sophisticated animation language called ATL. However there are a few things in this game that the regular Ren'Py engine does not have and we'll use this section to talk about those items in particular.


A morph is executed like in the example below and will transition one character into another using in-game and programming magic.

morph begin magic john leona casual a_6
"Some narration."
morph do john
"Some more narration."
morph end john

It consists of three parts: morph begin needs five pieces of information to work:

  1. Style of the morph (magic or alien)
  2. The person you want to morph (a character name from the sprite viewer)
  3. The person to morph into (another character name)
  4. The outfit for the morphed body
  5. The expression for the morphed body

All of this besides the first item can be looked up in the sprite viewer included in the game. In the example above, this would start an animation to morph john into leona in her casual outfit, wearing the expressiona_6.

morph do <character> is used in the middle of the morph. It will switch up the animation and prepare the character to appear as the morphed character.

morph end <character> finishes the morphing process, at the end of which the character will appear as the one you morphed them into.

Both of the above commands require you to append the name of the character whose animation you want to control. This allows you to have multiple morphs going at the same time, while retaining control over each of them individually.


For reasons of backwards compatibility, the morph command still supports omitting the character name after the do and end commands, but we would recommend always sticking to this new notation to prevent display glitches and to be able to use multiple morphs at the same time.


A swap requires two characters to be present on the screen and subsequently exchanges their bodies. It is executed like this:

swap <None|pulse|zap> john a_4 : b_3, connie b_3 : a_4

It needs three blocks of information: The first argument is optional, and can thus be either empty (referred to as None in the above example) or one of pulse or zap. This changes the animation that is used for the swap, which resolves to this:

  • None: Ghosts are expelled from the bodies and trade places.
  • pulse: The same as None, but after trading places, a pulse effect highlights the swapped characters with their repective ghosts.
  • zap: The ghosts "teleport" into the respective other body using an animation similar to an old TV turning off.

The next two blocks determine the characters involved in the swap. john a_4 : b_3 is the first character in the swap and the expressions separated by : denote the expression john has while swapping (a_4) and the expression in the swapped-to body when the swap has finished (b_3). The next block works the same, except that it controls the expressions of the other character.


Take notice of the fact that swapping characters will also necessitate you to use the expression banks of the character you swapped to. This applies not only to subsequent usage of the swapped characters but also to the second expression argument for both characters in this very swap command.


Possession is a two-step process. First off, you'll have to turn the character doing the possessing into a ghost:

exspirit john a_4

This will replace john with a ghost character of himself with the a_4 expression. You can control the ghost of any character by adding Ghost to their name, so john becomes johnGhost. To possess another character, you can now do this:

possess john mina b_6

This will manifest the ghost of john with the body of mina wearing the expression b_6. The character to be possessed (mina) will have to be present on the screen for this to work, as they do in most ghost stories because apparently, long-range possession teleportation is not a thing.

Casting Spells#

If you are more inclined to magic, we got you covered as well. If you want to cast a spell, you can show a pulsating pentagram on the screen for added effect and to add a sense of increased mysticality to an otherwise embarassingly LARP-y recitation of weird-sounding words you don't actually understand. This is a two-step process and might look like this:

show pentagram at center behind john as pentagram
"The magic began rushing through my body."
hide pentagram

show pentagram at center will do just that. But if a character, john in this case, is already on the screen, the pentagram will be overlaid on top of him. To remedy that we tell it to show the pentagram behind john as pentagram, which will put it behind the character. The as statement is a helper for us so that we can refer to it later on. Think of it as a kind of variable. This is necessary since we want to hide the effect at some point. One can imagine it being quite unnerving having to spend the rest of their life walking around with a giant glowing pentagram above their head. After a sufficient amount of spell-casting, we can then hide the effect with a simple hide pentagram statement, dissipating the animation and the last bits of doubt about magic not being a real thing.


There is a special transition that is used to convey the act of scrying on someone else. It consists of a rapid zoom into a character's eyes, a fade to black and a subsequent reversal of this animation by zooming out of another character's eyes into another scene. There are two parts to this command: scry into <character> and scry outof <character>. The former handles the zooming-in and fade-to-black, while the latter handles the zooming-out part into the new scene. This structure has been adopted so that in between these commands one can have a section in complete darkness, e.g. to insert monologue while being bodyless before appearing in the scried-on persons' body. A full-fledged example might look like this:

scry into john

"Some narration"

scene bg house_davis kitchen night
show abby a_0 at right
show katrina a_0 at center
scry outof abby

This will zoom into john's eyes and fade to black, after which Some narration will appear. After the dialogue, we will zoom out of abby's eyes into a scene that contains abby and katrina and is set in the kitchen at night. You can use scry into anywhere, as long as the character to be scried into is on the screen. After this command you can have as much dialogue as you want before calling scry outof. The latter command is a bit trickier as it requires a scene-definition above it, as shown in the example. This way you can set up the new scene you want to end up in before anything is acutally shown. Just make sure that the character you want to scry outof is somewhere on the screen before calling the command. Be aware that this is more of an advanced transition than it is a function. It does not actually swap bodies or transform anything, like some of the others. Instead it merely provides a convenient way to have a cool animation for all things scrying and slightly nauseating.

Phone Conversations#

The NVL mode that was previously used to imitate phone conversations has been spiced up quite a bit and replaced with an actual messaging-system lookalike. This means that showing phone conversations is now achieved using two custom commands and a bit of magic instead of the regular way of invoking NVL windows. We'll start with a full example and dissect the individual parts afterwards.

text start john
text title "Friends"

msg john "hey, what up, peeps?"

msg katrina "john, where are u? dnd has already started!"

    "What should I do?"

    "Go to DnD":
        msg john "shit, i'm omw"

        msg katrina "better hurry up then"

    "Skip it":
        msg john "sry, can't right now"

        msg katrina "aww, too bad"

msg yui "Why was I invited to this group?"

text end

To begin a new phone conversation you will need to start with two commands:

text start <character> shows an image of a phone with a new conversation on-screen. The character name determines the owner of the phone, and thus whose texts will show up as the owner's (on the right side of the screen). In this case it would be john so all messages john sends would appear on the right side, with a slightly red background color.

text title <chat title> then sets the title of that conversation, meaning the bar above the chat window, which can contain anything you want but is generally reserved for either contact or group-names, similar to apps like WhatsApp. Here, the bar would say Friends. Note that you can use this at any point in a phone conversation to "change the chatroom", so-to-speak, as it will remove all previously sent messages and set the new title text in one fell swoop.

Once the conversation has been set up with the above commands, you can start sending messages via msg <character> <message>. The first message in the example would be sent by john, and would result in a message-bubble popping up on-screen saying hey, what up, peeps?. The message statement behaves like a normal say statement, so after a click from the user the next message-bubble would pop up, this time (as katrina is not the owner of this phone/conversation) showing up on the left side of the screen and with a slightly green background color.

Note that it is also possible to send images as messages simply by specifying the image you want to send instead of text:

msg sandra image sandra a_0
This would send Sandra's sprite with the a_0 expression as an image message. This works for all images. If it can be shown in the script, it can be sent via a message, too.

For times where you want to pre-fill the conversation without having the user click through the messages, you can append the keyword instant to the msg command, such that it looks like this: msg <character> <message> instant. This will omit the requirement for the user to click to continue the conversation and instantly move to the next line.

The really nice thing about this feature is that it also works with regular Ren'Py menu statements, meaning that you can write script like normal, with branching, during a text conversation. The choice dialog will adapt to this and will show up as a smaller list of choices next to the phone instead of obstructing the screen as it normally does. In the above example, you could, for example, modify variables or nest choices as much as you'd like. In this case we just alter the flow of the conversation a bit but the general rules and abilities of the menu statement apply here just as they do for regular Ren'Py script.

Once you're done with a conversation, you can dismiss the phone via text end which will simply hide the screen again. Note that conversations will be cleared upon hiding the phone and will thus not show up when you call it up again.

Please be aware that this system is not a fully-functional messaging-system and thus is severely limited in functionality. It is only intended to more closely emulate the look-and-feel of standard-fare phone conversations, not emulate WhatsApp in its entirety. Nevertheless, you can still look fancy while doing so.

Last update: July 16, 2021