RenPy Main Menu Button to Play Video

Mikethe3DGuy

Member
Game Developer
Mar 14, 2019
232
443
I've added a button ("Teaser Video") to the navigation menu. I'd like it to play a video (fullscreen). It should return to the menu when finished and also allow the user to return any time by clicking the spacebar. Looking for advice on how to code this. I'm pretty new to coding. Looks like button-click functions are actions, but none of the actions look like they are designed to show an image or play a video.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,111
14,798
Looks like button-click functions are actions, but none of the actions look like they are designed to show an image or play a video.
It's not totally true, Play works perfectly fine with movies. But it's not what you need here, for many reasons.

What you need is a screen that will both display the movie and handle the keyboard:
Python:
# The movie
image trailer = Movie( play="movies/trailer.webm" )

screen trailer():

    #  Ensure that the screen do not pass the input.
    modal True

    #  Hide the screen when the player hit "space".
    key "K_SPACE" action Hide()
    #  Better, hide the screen when the player hit one of the usual keys to advance ;
    # therefore, space, return, left click, etc.
    # key config.keymap["dismiss"] action Hide()

    #  Show the movie centered.
    add "trailer" xalign 0.5 yalign 0.5
Then you just need to show the screen from the main menu, textbutton "trailer" action Show( "trailer" ).

Edit: corrected a format error.
 
Last edited:
  • Like
Reactions: Mikethe3DGuy

Mikethe3DGuy

Member
Game Developer
Mar 14, 2019
232
443
Thanks, but when I run it I get, on the first line of code:

File "game/screens.rpy", line 321: expected a keyword argument, colon, or end of line.
image trailer = Movie( play="movies/trailer.webm" )
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,111
14,798
Thanks, but when I run it I get, on the first line of code:

File "game/screens.rpy", line 321: expected a keyword argument, colon, or end of line.
image trailer = Movie( play="movies/trailer.webm" )
Then you have an error somewhere else in your code, prior to this line. Probably a string that you haven't closed.

Or... Wait, line 321, it's in the middle of the "navigation" screen that, no ?
You haven't tried to define the image and the screen inside a screen, right ?
 
  • Like
Reactions: Mikethe3DGuy

Mikethe3DGuy

Member
Game Developer
Mar 14, 2019
232
443
Or... Wait, line 321, it's in the middle of the "navigation" screen that, no ?
You haven't tried to define the image and the screen inside a screen, right ?
Haha, well of course I did. But once I corrected it, I get the following when I click the "Teaser Video" menu button:

I'm sorry, but an uncaught exception occurred.

While running game code:
File "renpy/common/00action_control.rpy", line 131, in __call__
renpy.show_screen(self.screen, *self.args, **self.kwargs)
Exception: Screen Alpha is not known.


-- Full Traceback ------------------------------------------------------------

Full traceback:
File "renpy/common/_layout/screen_main_menu.rpym", line 28, in script
python hide:
File "D:\renpy-8.0.3-sdk\renpy\ast.py", line 1131, in execute
renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
File "D:\renpy-8.0.3-sdk\renpy\python.py", line 1061, in py_exec_bytecode
exec(bytecode, globals, locals)
File "renpy/common/_layout/screen_main_menu.rpym", line 28, in <module>
python hide:
File "renpy/common/_layout/screen_main_menu.rpym", line 35, in _execute_python_hide
ui.interact()
File "D:\renpy-8.0.3-sdk\renpy\ui.py", line 299, in interact
rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
File "D:\renpy-8.0.3-sdk\renpy\display\core.py", line 3377, in interact
repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, pause=pause, pause_start=pause_start, pause_modal=pause_modal, **kwargs) # type: ignore
File "D:\renpy-8.0.3-sdk\renpy\display\core.py", line 4258, in interact_core
rv = root_widget.event(ev, x, y, 0)
File "D:\renpy-8.0.3-sdk\renpy\display\layout.py", line 1175, in event
rv = i.event(ev, x - xo, y - yo, cst)
File "D:\renpy-8.0.3-sdk\renpy\display\layout.py", line 1175, in event
rv = i.event(ev, x - xo, y - yo, cst)
File "D:\renpy-8.0.3-sdk\renpy\display\layout.py", line 1175, in event
rv = i.event(ev, x - xo, y - yo, cst)
File "D:\renpy-8.0.3-sdk\renpy\display\screen.py", line 743, in event
rv = self.child.event(ev, x, y, st)
File "D:\renpy-8.0.3-sdk\renpy\display\layout.py", line 1175, in event
rv = i.event(ev, x - xo, y - yo, cst)
File "D:\renpy-8.0.3-sdk\renpy\display\layout.py", line 1175, in event
rv = i.event(ev, x - xo, y - yo, cst)
File "D:\renpy-8.0.3-sdk\renpy\display\behavior.py", line 1073, in event
return handle_click(self.clicked)
File "D:\renpy-8.0.3-sdk\renpy\display\behavior.py", line 1008, in handle_click
rv = run(action)
File "D:\renpy-8.0.3-sdk\renpy\display\behavior.py", line 329, in run
return action(*args, **kwargs)
File "renpy/common/00action_control.rpy", line 131, in __call__
renpy.show_screen(self.screen, *self.args, **self.kwargs)
File "D:\renpy-8.0.3-sdk\renpy\display\screen.py", line 1185, in show_screen
raise Exception("Screen %s is not known.\n" % (name[0],))
Exception: Screen Alpha is not known.
 

MissFortune

I Was Once, Possibly, Maybe, Perhaps… A Harem King
Respected User
Game Developer
Aug 17, 2019
4,521
7,458
Exception: Screen Alpha is not known.
Looks like the screen "Alpha" itself is the issue. I'd assume it either doesn't exist or isn't labeled correctly.

Might have an easier time if you post a screencap or paste the said code.
 
  • Like
Reactions: Mikethe3DGuy

Mikethe3DGuy

Member
Game Developer
Mar 14, 2019
232
443
Looks like the screen "Alpha" itself is the issue. I'd assume it either doesn't exist or isn't labeled correctly.

Might have an easier time if you post a screencap or paste the said code.
Ah! Actually it works, very well in fact. Problem was my video filename had a space. Now just have to kill my main menu music when it plays!
 
  • Like
Reactions: MissFortune

Mikethe3DGuy

Member
Game Developer
Mar 14, 2019
232
443
So I'm actually having difficulty killing the main menu music on that textbutton action. The line is this:
Code:
textbutton _("Teaser Video") action Show("trailer")
and the music is called in options.rpy by this:
Code:
define config.main_menu_music = "audio/Epic_Main.ogg"
Making this change did not work:
Code:
textbutton _("Teaser Video") action Show("trailer"), Stop("audio/Epic_Main.ogg")
My hope is that once I'm able to kill the main menu music during teaser video playback, when the video ends and it returns to the main menu I'll be able to get main menu music back... somehow. Even temporarily muting main menu music volume would work if I can just bring it back to previous volume after the video, but not sure how to alter channel volume as an action.

Any suggestions?
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,111
14,798
Making this change did not work:
Code:
textbutton _("Teaser Video") action Show("trailer"), Stop("audio/Epic_Main.ogg")
screen action expect a channel name, not a file name.
The action should be Stop( "music" ), since it's on this channel that the main menu music is played.

But it's not what you want here, because you would have to restarts the music. It's better to use instead.

The action triggering the trailer would then be PauseAudio( "music", True ), Show( "trailer" ) (more logical in this order.
And the action closing the "trailer" screen become PauseAudio( "music", False ), Hide(), in order to bring back the music.
 

Mikethe3DGuy

Member
Game Developer
Mar 14, 2019
232
443
The action triggering the trailer would then be PauseAudio( "music", True ), Show( "trailer" ) (more logical in this order.
And the action closing the "trailer" screen become PauseAudio( "music", False ), Hide(), in order to bring back the music.
Oh that works beautifully! Thank you!
 

Mikethe3DGuy

Member
Game Developer
Mar 14, 2019
232
443
Any way to get the video to hide and revert to the main menu automatically after the first playthrough? It loops until there's an interrupt.
 

osanaiko

Engaged Member
Modder
Jul 4, 2017
2,099
3,351
There is a loop control parameter on the Movie class constructor: so you can make it play only once and not loop

And then to cause the screen to hide after the movie is done... there's no callback or similar for movie end, so instead I would use a timer to run the hide action after a specified duration. You'll need to set the timer to match the runtime length of the movie clip.

(note this example below is just editing AnneO's code from above, you may have modified it so be careful)

Code:
# The movie (with loop parameter)
image trailer = Movie( play="movies/trailer.webm", loop=false )

screen trailer():

    # Ensure that the screen do not pass the input.
    modal True

    # Hide the screen when the player hit "space" or similar keys
    key config.keymap["dismiss"] action Hide()

    # Show the movie centered.
    add "trailer" xalign 0.5 yalign 0.5

    # auto hide the screen after 7.5 seconds have passed (change the time to the length of the movie clip)
    timer 7.5 action Hide()
 

Mikethe3DGuy

Member
Game Developer
Mar 14, 2019
232
443
There is a loop control parameter on the Movie class constructor: so you can make it play only once and not loop

And then to cause the screen to hide after the movie is done... there's no callback or similar for movie end, so instead I would use a timer to run the hide action after a specified duration. You'll need to set the timer to match the runtime length of the movie clip.

(note this example below is just editing AnneO's code from above, you may have modified it so be careful)

Code:
# The movie (with loop parameter)
image trailer = Movie( play="movies/trailer.webm", loop=False )

screen trailer():

    # Ensure that the screen do not pass the input.
    modal True

    # Hide the screen when the player hit "space" or similar keys
    key config.keymap["dismiss"] action Hide()

    # Show the movie centered.
    add "trailer" xalign 0.5 yalign 0.5

    # auto hide the screen after 7.5 seconds have passed (change the time to the length of the movie clip)
    timer 7.5 action PauseAudio("music", False), Hide()
Beautiful. Thanks for your help! Just needed a couple changes (above) and it's just what I need. Edit: Oh damn, you can't change font color in code blocks. Anyway: [false to False] and [adding PauseAudio("music", False), to timer line.]
 
Last edited:
  • Like
Reactions: osanaiko