After that introduction to screen language, it’s time to actually create some screens and learn how you can get them to appear to the player in-game.
This tutorial series does not expect any prior knowledge of Ren’Py screen language or coding. I recommend you start with Getting Started with Ren’Py Screen Language if you haven’t yet read it.
Declaring a screen
Very first things first, you need to know how to declare a screen. Screens go at the very leftmost level of indentation, like labels do. They don’t belong inside anything, especially not labels.
Unlike labels, which are executed line-by-line in order to show dialogue and images to the player, you can think of a screen as a description of what a collection of UI elements should look like and do. If you want to see a screen as part of the script, you need to show
or call
them, similar to how you can’t see an image until you’ve shown it in-script with a line like show xia happy
.
The most basic form of a screen declaration looks like so:
screen stats_screen():
pass
screen
indicates that you’re declaring a screen, the way label
indicates you’re declaring a label or image
indicates you’re declaring an image.
stats_screen
is what I’ve named this particular screen. It follows the same rules as variable names – it can’t start with a number, can only have letters, numbers, and underscores (no spaces, dashes, special characters etc), and conventionally it’s named in all lowercase with underscores separating words (aka snake_case).
The parentheses ()
after stats_screen()
indicate that this screen doesn’t take any parameters. We’re not going to worry about what parameters are or how to use them at the moment, but know that adding these helps Ren’Py with prediction so it can run faster and more efficiently. You should always include them.
The :
at the end of the line starts a block – again, much like a label does. Everything beyond this point will be indented at least one level to the right to show it’s part of the screen.
Finally, pass
is just a placeholder for now, since Ren’Py will complain if your screen is entirely empty. It’s just a line that essentially says “do nothing here”. You may have seen this in menus, too, to indicate nothing should happen after a choice e.g.
menu:
"Say nothing.":
pass
"Say hello.":
"You" "Hello!"
"Xia didn't seem to notice your presence."
In the above example, nothing in particular happens if you decide to say nothing, so pass
is used to just move onto the line after the menu.
Call vs Show
There are two ways to display a screen to the player as part of gameplay – call
, and show
. (There are other ways to display screens as well, like by clicking a button on the main menu, but we’ll tackle that once we look at buttons).
show screen
show screen
should be used for screens that don’t require any action from the player. This is good for UI icons, notification popups, stat indicators, UI that tracks the time of day, etc. The player may click on parts of these screens to cause things to happen – for example, you might show a screen with a button the player can click to go to the Save screen. However, the player should still be able to interact with and proceed to play the game normally even though the screen with the button to go to the Save screen has been shown.
To show a screen in this way, simply use show screen the_screen_name()
e.g.
label start():
show screen stats_screen()
"The screen should be showing."
Showing a screen, like showing an image, doesn’t inherently wait for anything to happen. So, if you want to wait for a click after showing the screen, you’ll need to add a pause
after showing the screen. The player can click anywhere to continue with the game, again much like showing an image.
You can hide the screen again with the line hide screen stats_screen
. You shouldn’t use ()
after the name of the screen when hiding it, even if it has parameters. You can think of this as similar to how hiding image tags works – you might’ve written show zoran happy
but you can hide Zoran with hide zoran
– it isn’t necessary to include “happy” to hide the sprite. If you’re hiding a screen, it isn’t necessary to specify any more information about the screen you’re hiding since it’s already showing and now it’s going to be hidden. Ren’Py just needs to know the name of the screen to hide.
So, a simple example of showing a screen, waiting for the player to click, and then proceeding with the game, might look as follows:
label start():
window auto hide # Make sure the dialogue window is hidden
show screen the_game_will_remember_this()
pause
hide screen the_game_will_remember_this
"You've started a new Ren'Py game."
call screen
call screen
should be used for screens that do require some kind of interaction from the player in order to proceed. This is good for things like point-and-click sections, where the player must investigate the correct items to continue, map screens where they have to click a location to proceed, character selection screens where the player must choose a character’s route to play, and most minigames.
Calling a screen will cause the whole game to essentially be put “on hold” until something happens on the screen to return the player to normal gameplay. Ren’Py calls this an “interaction”, so, calling a screen will “wait for an interaction” before proceeding. Typical ways of causing this interaction are by using Return()
to go back to the line after the screen was called, or Jump
or Call
to go to a particular label. These actions will also automatically cause the screen to hide, unlike with show screen
, where you’ll have to manually hide the screen yourself.
Calling a screen in your script looks similar to showing a screen, except the game will not move forward until you’ve returned from that screen or jumped somewhere to continue the script.
label start():
call screen character_creator()
"Welcome to the game!"
In the above example, presumably the character_creator
screen allows the player to select traits about their character before they can begin the game, such as hair colour, skin colour, or body type. The player has to select these things before continuing with the rest of the script, so call screen
is used to ensure they interact with it before returning to the gameplay.
Summary
- You declare a screen at the leftmost level of indentation, outside of any other existing blocks (so, not inside labels,
init
orinit python
blocks, or anything else). - Screens are declared via
screen screen_name():
wherescreen_name
is any name you want to give the screen, so long as it only has letters, numbers, and underscores, and does not begin with a number. - You can display screens to the player in-game by
show screen screen_name()
(which will allow gameplay to continue as normal while the screen is shown) orcall screen screen_name()
(which will require some kind of interaction, usually on the player’s part such as clicking a button, to continue gameplay).
Next Steps
For the next part of this tutorial series, I suggest you set up a basic screen that you can see as soon as you begin the game so you can start testing some code and playing around with it:
screen test_screen():
pass
label start():
"The game starts here."
call screen test_screen()
return
When you hit Start
from the main menu, you will be able to see test_screen
after the first line of dialogue (though the above example just has a blank screen with nothing in it for now).
In the next tutorial we will move on to Ren’Py Screen Language Basics – Images and Text. My biweekly tool is also up now on itch.io!
Be sure to follow me on itch.io to get an email about new tool releases!