Creating a Custom Main Menu in Ren'Py with Screen Language and ATL
Step‑by‑step guide to replace Ren'Py's default main menu with a custom screen that includes a background image and animated buttons using ATL.
05 Oct 2026, 04:40 UTC

Desired outcome
Replace Ren'Py's built‑in main menu with a custom screen that shows a background image, displays three buttons (Start, Preferences, Quit), and provides smooth hover animations using ATL. After following the guide you will be able to launch the project, see the custom menu, interact with the buttons, and revert to the default menu if needed.
Prerequisites
- Ren'Py 8.x SDK installed (tested with 8.2.2).
- A blank or existing Ren'Py project that launches without errors.
- A text editor that shows indentation (e.g., VS Code, Sublime Text).
- Two image files placed in the
game/folder:menu_background.png– the background for the menu.button_idle.png– optional base image for buttons (can be omitted if using text only).
- Basic familiarity with Ren'Py script syntax.
Focused procedure
-
Prepare the assets. Copy
menu_background.pngintogame/. If you want a simple button background, copybutton_idle.pngas well. No additional declaration is required; Ren'Py automatically loads images from thegame/directory. -
Edit or create
screens.rpy. Open the file in your editor and add the following screen definition near the top (after any existing screens).# screens.rpy screen custom_main_menu: # Fixed layout positions elements relative to the window. fixed: # Background image stretched to fill the window. add "menu_background.png" xpos 0 ypos 0 # Start button textbutton "Start" action Start() xpos 0.5 ypos 0.4 xanchor 0.5 yanchor 0.5: atl { idle: alpha 1.0 hover: alpha 0.8 linear 0.2 } # Preferences button textbutton "Preferences" action Preferences() xpos 0.5 ypos 0.5 xanchor 0.5 yanchor 0.5: atl { idle: alpha 1.0 hover: alpha 0.8 linear 0.2 } # Quit button textbutton "Quit" action Quit() xpos 0.5 ypos 0.6 xanchor 0.5 yanchor 0.5: atl { idle: alpha 1.0 hover: alpha 0.8 linear 0.2 }Explanation:
- The
fixedlayout lets us place items with absolute coordinates. adddraws the background image.- Each
textbuttonuses a standard Ren'Py action (Start(),Preferences(),Quit()). - The
atlblock defines two states:idle(normal) andhover(when the mouse cursor is over the button). Thealphaproperty changes opacity, creating a fade effect; you can replace it withzoom,rotate, etc.
- The
-
Replace the default main menu. There are two common ways; choose one.
- Option A – via
label start:: At the very beginning of yourscript.rpy(or any early label), ensure the game calls your screen before any other content:label start: call screen custom_main_menu returnThis overrides the default menu because the
startlabel is the entry point Ren'Py uses when launching. - Option B – via configuration: Add the following line to
options.rpy(create the file if it doesn’t exist):# options.rpy config.main_menu_screen = "custom_main_menu"This tells Ren'Py to use the named screen as the main menu without modifying
script.rpy.
- Option A – via
-
Run the project. Launch the game using the Ren'Py launcher (Shift+Shift) or by executing
renpy.exefrom the command line in the project root:# From the project directory renpy.exe .You should see the background image and three buttons.
-
Expected checks:
- The menu appears without any error messages in the console.
- Hovering over a button triggers the ATL-defined fade (or other transform) smoothly.
- Clicking Start begins the game (or jumps to your first label).
- Clicking Preferences opens the preferences screen.
- Clicking Quit closes the application cleanly.
-
Recovery options (if something goes wrong):
- Open
log.txtin the project directory. Look for lines indicating indentation errors, missing files, or undefined actions. - If the screen fails to show, temporarily comment out the custom menu call or configuration:
# label start: # call screen custom_main_menu # returnor
# config.main_menu_screen = "custom_main_menu" - Restart the game; Ren'Py will fall back to its default main menu, allowing you to fix the issue.
- Open
Limitations and practical verification
This guide assumes you are using Ren'Py 8.x; older versions may lack certain ATL features or have different default menu handling. The ATL example uses only opacity changes; for more complex animations you can add zoom, rotate, or linear timing functions.
To verify that the custom menu is indeed being used, you can add a temporary diagnostic statement:
screen custom_main_menu:
text "Debug: custom menu loaded" xpos 0.0 ypos 0.0 size 20 color "#ff0"
# … rest of the screen as above
If the text appears in the top‑left corner, the screen is active. Remove it once you confirm the menu works.
Summary
By defining a screen in screens.rpy, adding ATL hover transforms, and either calling the screen from label start or setting config.main_menu_screen, you replace Ren'Py's default main menu with a fully customized, animated interface. Verify the result by launching the project, checking hover feedback and button actions, and keep the log.txt handy for quick rollback if needed.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.