How can I make a screen modal on the fly?

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
Thailandian
Regular
Posts: 30
Joined: Tue Jun 01, 2021 6:24 am
Contact:

How can I make a screen modal on the fly?

#1 Post by Thailandian »

I have a screen that I'm using for both a task completion check and Q&A during a free roam.

Most of the time, I want the screen to be amodal so that players can check their progress without interrupting play. However, during the Q&A parts, the screen should be modal so that interactions with the screen don't accidentally impact the general game-play.

I've been able to change other aspects of the screen using kwargs - e.g.

Code: Select all

screen g01_tasks (tasks_size=g01_tasks_small, tasks_vis=True):
    zorder 5

    if tasks_vis:
        imagemap:
            at tasks_size
However, if I try to do the same with the modal property, e.g.

Code: Select all

screen g01_tasks (m=False, tasks_size=g01_tasks_small, tasks_vis=True):
    zorder 5
    modal m
I get the following traceback:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/game_ch01.rpy", line 300, in script
    call screen game_ch01_entry with Dissolve (3.0)
  File "renpy/common/000statements.rpy", line 560, in execute_call_screen
    store._return = renpy.call_screen(name, *args, **kwargs)
  File "game/inits.rpy", line 129, in openG01Tasks
    renpy.show_screen("g01_tasks", m=False, tasks_vis=True)
  File "game/screens.rpy", line 133, in <module>
    modal m
NameError: name 'm' is not defined
So, I tried using an if/else statement to change the modality:

Code: Select all

screen g01_tasks (m=True, tasks_size=g01_tasks_small, tasks_vis=True):
    zorder 5
    if m==True:
        modal True
    else:
        modal False
That let the code run, but the modality is not affected by changing "m".

If necessary, I could make 2 identical screens and swap them out, but I'm hoping for a more efficient solution.

As always, any suggestions would be most appreciated.

rayminator
Miko-Class Veteran
Posts: 793
Joined: Fri Feb 09, 2018 12:05 am
Location: Canada
Contact:

Re: How can I make a screen modal on the fly?

#2 Post by rayminator »

it's telling you that 'm' is not defined

you have to define it like this

Code: Select all

default m = False

Thailandian
Regular
Posts: 30
Joined: Tue Jun 01, 2021 6:24 am
Contact:

Re: How can I make a screen modal on the fly?

#3 Post by Thailandian »

Thanks for the response Rayminator.
Now, I get the traceback

Code: Select all

File "game/screens.rpy", line 134: a non-constant keyword argument like 'modal m' is not allowed after a python block.
    modal m
That makes no sense to me because there is no Python that I can see between the beginning of the screen block and "modal m"!
I also get the same traceback whether or not "m" is defined in the screen arguments.

What am I missing?

User avatar
Imperf3kt
Lemma-Class Veteran
Posts: 3794
Joined: Mon Dec 14, 2015 5:05 am
itch: Imperf3kt
Location: Your monitor
Contact:

Re: How can I make a screen modal on the fly?

#4 Post by Imperf3kt »

Try using a keyword argument.
screen myscreen(m)
modal(m)

Set m to True or false somewhere.



But the better option is to simply call the screen when you want it modal, and show the screen when you want it amodal since a called screen is modal until an action is triggered.
Warning: May contain trace amounts of gratuitous plot.
pro·gram·mer (noun) An organism capable of converting caffeine into code.

Current project: GGD Mentor

Twitter

Thailandian
Regular
Posts: 30
Joined: Tue Jun 01, 2021 6:24 am
Contact:

Re: How can I make a screen modal on the fly?

#5 Post by Thailandian »

Thanks for the suggestions Imperf3kt.

When I try using a keyword argument, I get the "NameError: name 'm' is not defined" traceback.

I hadn't thought of using call, and it seems promising. However, when I tried:

Code: Select all

renpy.call_screen("g01_tasks", tasks_size=g01_tasks_zoom, tasks_vis=True)
renpy.restart_interaction()
I get the traceback:

Code: Select all

While running game code:
  File "game/game_ch01.rpy", line 263, in script
    tr proud "Here's your mission Mr Phelps. Help me complete this \'To Do\' list."
  File "game/inits.rpy", line 147, in openG01Qs
    renpy.call_screen("g01_tasks", tasks_size=g01_tasks_zoom, tasks_vis=True)
Exception: Cannot start an interaction in the middle of an interaction, without creating a new context.
From the traceback, I guess part of the problem is that I tried to call the screen during a dialogue. But I want the player to be able to open and close the screen at any time.

I looked up "new context" in the Renpy documentation and found "renpy.call_in_new_context" but nothing like "renpy.call_screen_in_new_context". At this stage, although it's inefficient and inelegant, the only option I can see is to use two identical screens and swap them.

User avatar
Imperf3kt
Lemma-Class Veteran
Posts: 3794
Joined: Mon Dec 14, 2015 5:05 am
itch: Imperf3kt
Location: Your monitor
Contact:

Re: How can I make a screen modal on the fly?

#6 Post by Imperf3kt »

I haven't used kwargs in a while, I may have given an improper example.
Sorry, I don't have time to go over it at the moment.

You can allow a player to open and close the screen at will by making a button or binding a key to a Call (capital C) action for the screen, place that button in a screen, and then showing it.
To get rid of the called screen, a button needs to perform a Return() action, if you put a variable inside that Return(), it will be saved to the variable _return until it is overwritten by something else.

I wish I could give examples, but I'm not currently able to from a mobile device.
Warning: May contain trace amounts of gratuitous plot.
pro·gram·mer (noun) An organism capable of converting caffeine into code.

Current project: GGD Mentor

Twitter

Thailandian
Regular
Posts: 30
Joined: Tue Jun 01, 2021 6:24 am
Contact:

Re: How can I make a screen modal on the fly?

#7 Post by Thailandian »

Thanks Imperf3kt - Yes, I suspect that part of my problem is that I'm doing almost everything from Python rather than Renpy. I notice, for example, that the traceback I get when trying to use a kwarg includes:

Code: Select all

File "game/screens.rpy", line 134: a non-constant keyword argument like 'modal m' is not allowed after a python block.
My button action is:

Code: Select all

def openG01Tasks():
        renpy.hide_screen("g01_task_button")
        renpy.show_screen("g01_tasks", tasks_vis=True)
        renpy.transition(dissolve)
        renpy.restart_interaction()
Perhaps the kwarg solution would work if the button action used Renpy rather than Python, so I looked for a Renpy Call screen action, but could only find either the "call screen" statement or "renpy.call_screen". I tried just using "Call" but that didn't work either - in the documentation, it specifies a label.

Anyway, for the moment, I've moved on to other problems and will use two screens if a solution doesn't appear within the next few days.

Thanks again for your help.

Post Reply

Who is online

Users browsing this forum: No registered users