Ren'Py [SOLVED] Baffled; help, please! - using input inside a screen, nesting modal True screens that Return(smth)

Me666

Newbie
Mar 14, 2018
96
215
Hello, and thank you for your attention :)

Firstly, I must mention that I've only just discovered that there is proper documentation in the SDK in a docs folder somewhere. I intend to wade through this as soon as I get time... However, I've had reasonable luck flailing about thus far, and am hoping for a kind person to just pop into the thread and point out exactly which things I've gotten wrong.

I'm trying to pop up a modal 'dialog box' from the middle of another modal screen (not the main game), where the user can quickly enter a text string (later on: click a spin dial, and all with limits-checking). The results of this will then get fed into a pre-existing binding (pname).

This is my current code, along with the traceback. Commenting out the two input: and value pname lines makes it all run just fine:
You don't have permission to view the spoiler content. Log in or register now.
You don't have permission to view the spoiler content. Log in or register now.

[Edit] : Clicking on the 'dialog box's "OK" textbutton exits out of the box - and also out of the previous screen, too. Hopefully there is a way around this?

Many thanks!
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,979
16,236
[Note: it's late and only half of my brain is working, but normally I'm right]

Python:
                        action(
                             Show("playerinput", query="Name?", field=pname, styleprefix="hud"),
                             SetVariable("pname", _return))
I keep this as reference.


Python:
            input:
                value field
So, as the traceback say, the error is located on this screen statement. More precisely, it's due to a wrong use of its value property.
You are providing it a string, while it expect an ; in your particular case, the most fitted is probably the .

There's two way to solve this :
Python:
screen laptop():
[...]
                   textbutton "[pname]":
[...]
                        # Note that you pass the name of the variable, not the variable.
                        action Show("playerinput", query="Name?", field="pname", styleprefix="hud")
                        # The SetVariable become obsolete. /pname/ will have its value updated automatically
[...]

screen playerinput(query, field, styleprefix):
[...]
            input:
                value VariableInputValue( field, default=getattr( store, field ) )
[...]
or
Python:
screen laptop():
[...]
                   textbutton "[pname]":
[...]
                        action(
                             Show("playerinput", query="Name?", field=pname, styleprefix="hud"),
                             # This time the variable isn't updated, so it's needed.
                             SetVariable("pname", _return))
[...]

screen playerinput(query, field, styleprefix):
[...]
            input:
                # Provide the default value, and let Ren'py return you the value input.
                default field
[...]

This being said, this :
Code:
# This gets run at init 0, so all our defines, defaults, styles, transforms etc. are in place for when we want them
init:
    define hud_text_size = 25 # Probably best not to exceed 40...

    style hud:
[...]
Is partly wrong.

define and style have their own context and are always proceeded at init level. Therefore they should be at 0 level of indentation.
There's no need to put them on an init bloc.
 
  • Like
Reactions: Me666

Me666

Newbie
Mar 14, 2018
96
215
Thank you, anne O'nymous :)

I appreciate the response, the solutions, and the information about define and style context - cheers!

I did flail about for a further hour trying to come up with a solution on my own, and came up with this after trawling through the information at ( ), which worked as intended but may not be particularly elegant. I'll experiment with what you put, to see if it solves my other problem also, which is that using "Return()" at all in playerinput() takes me out of playerinput() (expected) AND laptop() (not expected, and skipping any further Actions) - straight back to the original "call screen laptop".

Is there a way to avoid this? I realise that a screen is not the same thing as a function, so I shouldn't really expect it to behave like one... I have a workaround in mind, but it will mean doing what it says in the following TODO (which is fine, but I feel like I'm missing the point :p)

You don't have permission to view the spoiler content. Log in or register now.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,979
16,236
[...] to see if it solves my other problem also, which is that using "Return()" at all in playerinput() takes me out of playerinput() (expected) AND laptop() (not expected, and skipping any further Actions) - straight back to the original "call screen laptop".
The Return() screen action is not intended to close a screen (it's just a side effect), but to return to the script. Therefore, whatever how many sub-screens have been opened, and whatever how deep in this chain the Return() will be triggered, all screens will be closed and Ren'py will pass to the next line on the script.

You don't need to use Return() to catch the value of the input statement. As far as I remember right now, the _return special variable is automatically updated each time the player hit a key.
Therefore, replace your Return() by a Hide( "playerinput" ), and it should be good. The input screen will be hidden, and the player will stay on the laptop one.
 
  • Like
Reactions: Me666