when does Ren’py think I’m in the main menu

n.b. This information is accurate to Ren’Py 7.3.x and should also work for versions 7.0.x, 7.1.x, and 7.2.x. It will most likely not work for versions prior to 7.

Screens are often the biggest programming component to a VN. There’s a ton of ground to cover there, but here’s a gotcha specific to the main menu that I thought I’d highlight first.

how the heck do I know if I’m in the main menu in the GUI?

Ren’Py’s engine always has a ‘store variable’ set for its main menu- that is, it keeps track of whether it’s displaying the main menu or not.

This allows you to display other screens differently if you have the main menu up. All you have to do is check the main_menu variable to see if it’s true or false. It can’t have any other value.

Example code:

        if main_menu:

            textbutton _("Start") action Start()


            textbutton _("History") action ShowMenu("history")

            textbutton _("Save") action ShowMenu("save")

This is code from within the base code’s navigation menu.

If you haven’t started or loaded a game yet, you’ll be in the main menu as the first screen. Ren’Py knows that you can’t look at your conversation history or save your game when no game is loaded yet. So instead it gives you a button to start a game.

So here’s a gotcha when designing a GUI- if you have elements that link back to the main menu, you can run into an error if you call action MainMenu().

Here’s an example:

textbutton _("Main Menu") action MainMenu()

This code is from a Preferences screen somebody coded. When they tried clicking on the text button, sometimes Ren’Py would crash.

The problem occurs when a game hasn’t been started or loaded yet. Ren’Py thinks it’s still in the Main Menu even when you bring up the Preferences screen. So it crashes when it tries to return to the Main Menu, because it thinks you’re already there.

When you’re in the Preferences screen before you’ve started a game, the Return() action will take you back to the Main Menu screen. To make sure the button executes the correct action, you can check the main_menu store variable.

if not main_menu:
     textbutton _("Main Menu") action MainMenu()
     textbutton _("Main Menu") action Return()

tl;dr: Ren’Py considers you to be using the Main Menu screen until you’ve started or loaded a game.

The Main Menu screen has some other unique traits I’m curious to explore. Next up: playing videos in the Main Menu, and how other screens use the Main Menu.

how do I change the opacity of the dialogue box in Ren’Py

This information is valid for Ren’Py 7.3.x. I believe it should work all the way back to Ren’Py 7.x. The names and values I use for the variables do not need to be yours.

This tutorial’s going to reference the last one a bit. We’re going to use the Preferences screen with persistent variables again. Only this time, we’re playing with a slider and transforms. The goal is for the player to adjust how opaque they want the dialogue background (but not the dialogue), because it can increase readability in different circumstances.

Open up your script editor and define the persistent variable, probably in options.rpy or wherever you have other persistent variables stored.

Screencap of code, defined below

Below’s where I put the code, in between the stock gui.about variable and the game’s short name:

define gui.about = _p("""

# additional persistent variables begin here
define persistent.dialogueBoxOpacity = 1.0
# end extra variables

## A short name for the game used for executables and directories in the built
## distribution. This must be ASCII-only, and must not contain spaces, colons,
## or semicolons.

We’ve named the persistent variable dialogueBoxOpacity, but you can name it whatever you want. We set the default value to 1 because that means completely opaque.

Next, we figure out where on the Preferences screen you want to add the slider that will control the opacity. Your Preferences screen is probably defined pretty far down in the screens.rpy file, in the screen preferences() function.

screen shot- code is below

In this case I’ll put it in a new column (vbox). Here’s the code for the menu setting:

label _("Dialogue box opacity")
bar value FieldValue(persistent, "dialogueBoxOpacity", range=1.0, style="slider")

The label value is what you want the user to see headingwise. The bar is a Ren’Py object that is used when you want more fine-grained control of your variables.

In the parentheses, persistent means we’re setting the value of a persistent variable. The next string should be the same as the persistent variable name you used above.

The range=1.0 statement defines the max value of the bar, which is something we can set to correspond to the values we want possible for the opacity setting. All bars have a minimum value of 0.

That wraps up our work in the preferences screen part of the file.

Now, this is a bit more complicated than the style refresh we used to change the background of the dialogue window. Since there isn’t a predefined style for the opacity, I don’t know how to just inject that.

Instead, I put a transform for opacity in the Say screen. Every time this window gets rendered, it will check the opacity of the dialogue box and render that before it renders any text (so the text is always opaque).

The Say screen is traditionally defined about a hundred lines in to the stock screens.rpy file.

Under id “window”, we’ll add the following line:

window background Transform(Frame("gui/textbox.png",xalign=0.5, yalign=1.0), alpha=persistent.dialogueBoxOpacity)

window background Transform, uh transforms the window background. Frame is used to define a window that has a background. We need to specify the background being rendered, which is traditionally saved as textbox.png in the gui folder.

xalign=0.5, yalign=1.0 puts the window at the bottom of the screen, centered. You may have different settings in your custom GUI, in which case you should change these values to whatever you have defined in your style window: block.

alpha=persistent.dialogueBoxOpacity applies an alpha transform to the window. Here, the code consults the persistent variable to determine how opaque your image will be.

You should be good to go. Any questions or things I should clear up?

Further notes

As it is, this code allows you to use only one background. You can have the name of the background be a persistent variable too, but I’m assuming this is not a common use case. If you want to do it, leave a comment.