Text Input: problem with 'with_none' and 'changed' keywords

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
duck-and-wolf
Regular
Posts: 47
Joined: Thu Aug 29, 2019 6:20 pm
Completed: Head of the Class
Organization: Duck & Wolf
Contact:

Text Input: problem with 'with_none' and 'changed' keywords

#1 Post by duck-and-wolf »

I have two questions about the text input function:

The first one is, in the example renpy.input function in the Text Input doc (https://www.renpy.org/doc/html/input.html), an argument 'with_none' is shown, but nowhere on that page does it describe what it is or does. Does anyone know?

Secondly, my main question is this, I was trying to have a typewriter sound effect play each time the player strikes a key to enter their name, and I was following this forum post: viewtopic.php?t=40217

I wrote this code:

Code: Select all

init python:

    def typewriter():
        renpy.music.play("sounds/typewriter.ogg", channel="audio")

...

    python:

        nameHero = renpy.input(_("What {i}is{/i} your name?"), length = 24, changed = typewriter)
But when I run the game and it gets to the input prompt, I get this exception:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script_1_name.rpy", line 173, in script
    python:
  File "game/script_1_name.rpy", line 175, in <module>
    nameHero = renpy.input(_("What {i}is{/i} your name?"), length = 24, changed = typewriter)
TypeError: input() got an unexpected keyword argument 'changed'

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

Full traceback:
  File "game/script_1_name.rpy", line 173, in script
    python:
  File "C:\Users\Derp\Desktop\renpy-7.3.2-sdk\renpy\ast.py", line 912, in execute
    renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
  File "C:\Users\Derp\Desktop\renpy-7.3.2-sdk\renpy\python.py", line 2004, in py_exec_bytecode
    exec bytecode in globals, locals
  File "game/script_1_name.rpy", line 175, in <module>
    nameHero = renpy.input(_("What {i}is{/i} your name?"), length = 24, changed = typewriter)
TypeError: input() got an unexpected keyword argument 'changed'

Windows-8-6.2.9200
Ren'Py 7.3.2.320
Derp 1.0
Wed Sep 25 11:59:37 2019
Does the 'changed' argument no longer exist in Ren'Py?

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#2 Post by hell_oh_world »

duck-and-wolf wrote: Wed Sep 25, 2019 1:05 pm Does the 'changed' argument no longer exist in Ren'Py?
It doesn't, I guess. But in screen language, the input statement has a property "changed". You can use ui functions instead to achieve this maybe?

Code: Select all

ui.input(changed=functionName)
https://www.renpy.org/doc/html/screen_p ... -functions

duck-and-wolf
Regular
Posts: 47
Joined: Thu Aug 29, 2019 6:20 pm
Completed: Head of the Class
Organization: Duck & Wolf
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#3 Post by duck-and-wolf »

Man, as always I really appreciate your help! I swear I try to search the docs for this stuff but I can never find these pages y'all link to.

So, let's give it a shot. Your link only shows the changed argument as a property of ui.adjustment, but I decided to just try it and see what happens. I modified my input screen code to this:

Code: Select all

screen input(prompt):
    style_prefix "input"

    window:

        vbox:
            xalign gui.dialogue_text_xalign
            xpos gui.dialogue_xpos
            xsize gui.dialogue_width
            ypos gui.dialogue_ypos

            text prompt style "input_prompt"
            $ ui.input(changed = typewriter)
#            input id "input"
And I got this exception:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script_1_name.rpy", line 183, in script
    python:
  File "game/script_1_name.rpy", line 185, in <module>
    nameHero = renpy.input(_("What {i}is{/i} your name?"), length = 24) #, changed = typewriter()
TypeError: typewriter() takes no arguments (1 given)
Ok, so, apparently my function is now being sent an argument. I'm assuming a string variable with the changed letter in it? Not sure, but it's encouraging that the 'changed' keyword seems to work! So I changed my typewriter function to this:

Code: Select all

init python:

    def typewriter(butt):
        renpy.music.play("sounds/typewriter.ogg", channel="audio")
I figure the function can accept whatever the argument is and just ignore it.

So I ran the game, aaaannnndddd.... lo and behold, it worked! There was a typewriter noise to every new letter. This is great, I thought. It kind of sucks to use a deprecated UI function, but I'll take it.

So I type in a name, hit the Enter key, and... nothing. Now the Enter key won't accept the input after you've typed in a name, it just does literally nothing. You can backspace, and move the cursor left and right with the arrow keys, and type whatever you want, but nothing happens when you hit Enter.

So then I thought, well, it's a long shot but what if......

Code: Select all

screen input(prompt):
    style_prefix "input"

    window:

        vbox:
            xalign gui.dialogue_text_xalign
            xpos gui.dialogue_xpos
            xsize gui.dialogue_width
            ypos gui.dialogue_ypos

            text prompt style "input_prompt"
            input id "input" changed typewriter
I used the changed keyword on the standard input function, ran the game and... the sound effect worked! Again, the sound effect plays when you type in new letters. What a genius I am, I thought. So I hit Enter, and... same as before, the Enter key now does nothing.

So it seems like, when you add the changed keyword to a function, it supercedes the default Enter key behaviour in some way.

Any thoughts?

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#4 Post by hell_oh_world »

duck-and-wolf wrote: Thu Sep 26, 2019 11:53 am So it seems like, when you add the changed keyword to a function, it supercedes the default Enter key behaviour in some way.

Any thoughts?
If you're trying to name a character, I bet you have a default variable name for that, include that name variable inside the function.

Code: Select all

default nameHero = ""
init python:

    def typewriter(butt):
        renpy.music.play("sounds/typewriter.ogg", channel="audio")
        store.nameHero = butt
Anyways, I'm not sure about what you mean by this...
So I type in a name, hit the Enter key, and... nothing. Now the Enter key won't accept the input after you've typed in a name, it just does literally nothing. You can backspace, and move the cursor left and right with the arrow keys, and type whatever you want, but nothing happens when you hit Enter.
Do you mean that nothing even procedes after you hit enter? That you got stuck for better in the input phase of the game? Do you mean it like that?

duck-and-wolf
Regular
Posts: 47
Joined: Thu Aug 29, 2019 6:20 pm
Completed: Head of the Class
Organization: Duck & Wolf
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#5 Post by duck-and-wolf »

hell_oh_world wrote: Thu Sep 26, 2019 1:12 pm If you're trying to name a character, I bet you have a default variable name for that, include that name variable inside the function.
Isn't that getting taken care of when I call the renpy.input function in my main game script? Like so:

Code: Select all

label name_loop:

    python:
        nameHero = renpy.input(_("What {i}is{/i} your name?"), length = 24)
        nameHero = nameHero.strip()

    if nameHero == "":
        jump name_loop

    else:
        jump name_valid
The above code was working perfectly until I tried to add this sound effect to the game.
hell_oh_world wrote: Thu Sep 26, 2019 1:12 pm Do you mean that nothing even procedes after you hit enter? That you got stuck for better in the input phase of the game? Do you mean it like that?
That is exactly right. The input prompt comes up, and you can type in, say, "Steve", and every time you press a key, "s", "t", "e" etc., you hear the sound.

But then when you hit the Enter key, literally nothing at all happens. The game just stays at the Input prompt, as if you had not pressed Enter at all. You can not get it to continue, the Enter key no longer has any effect whatsoever.

If I go back and comment out the "changed typewriter" keyword from the input line in the input screen in my screens.rpy, like so:

Code: Select all

screen input(prompt):
    style_prefix "input"

    window:

        vbox:
            xalign gui.dialogue_text_xalign
            xpos gui.dialogue_xpos
            xsize gui.dialogue_width
            ypos gui.dialogue_ypos

            text prompt style "input_prompt"
            input id "input" #####changed typewriter
...then the Enter key works as normal again. So it's definitely something about adding that 'changed' keyword to the input function that is removing the Enter key's default behaviour.

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#6 Post by hell_oh_world »

duck-and-wolf wrote: Thu Sep 26, 2019 2:07 pm Isn't that getting taken care of when I call the renpy.input function in my main game script? Like so:
Yup, but you're using a screen now for input and not the renpy.input() function directly. So getting the value and storing it into the nameHero variable is not like what you seem to be doing with the renpy.input function. You could either use _return variable or do what I just did to get the entered value.
duck-and-wolf wrote: Thu Sep 26, 2019 2:07 pmThat is exactly right. The input prompt comes up, and you can type in, say, "Steve", and every time you press a key, "s", "t", "e" etc., you hear the sound.

But then when you hit the Enter key, literally nothing at all happens. The game just stays at the Input prompt, as if you had not pressed Enter at all. You can not get it to continue, the Enter key no longer has any effect whatsoever.
This sounds weird. Maybe it's because of the music playing whenever you type. This sounds irrelevant but just try to comment out the renpy.music.play from the function and see if the enter works. Also, its like your trying to play a sound rather than a piece of music in the audio channel maybe you could use renpy.play instead?

duck-and-wolf
Regular
Posts: 47
Joined: Thu Aug 29, 2019 6:20 pm
Completed: Head of the Class
Organization: Duck & Wolf
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#7 Post by duck-and-wolf »

hell_oh_world wrote: Thu Sep 26, 2019 2:22 pm Yup, but you're using a screen now for input and not the renpy.input() function directly.
But I am using the renpy.input() function directly, right? I haven't taken that line out of my main game script, this is the line that calls up the input prompt:

Code: Select all

python:
        nameHero = renpy.input(_("What {i}is{/i} your name?"), length = 24)
hell_oh_world wrote: Thu Sep 26, 2019 2:22 pm Also, its like your trying to play a sound rather than a piece of music in the audio channel maybe you could use renpy.play instead?
I actually was not aware of the difference :P I did make that change, like so:

Code: Select all

init python:

    def typewriter(butt):
        store.nameHero = butt
        renpy.play("sounds/typewriter.ogg", channel="audio")
Nothing really changed, I still hear the sound effect for every letter. But if that's a better way of playing a sound effect of course I'd rather use it.
hell_oh_world wrote: Thu Sep 26, 2019 2:22 pm This sounds weird. Maybe it's because of the music playing whenever you type. This sounds irrelevant but just try to comment out the renpy.music.play from the function and see if the enter works.
I went ahead and commented that line out, and now of course I don't hear anything, AND the Enter key still does nothing.

It really seems like using this 'changed' keyword is somehow overriding the default Input behaviour. Is it possible that the Ren'Py source code itself relies on a default 'changed' keyword for the Input that I have now hijacked by injecting in my own custom function for that keyword?

duck-and-wolf
Regular
Posts: 47
Joined: Thu Aug 29, 2019 6:20 pm
Completed: Head of the Class
Organization: Duck & Wolf
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#8 Post by duck-and-wolf »

I just found this on the Screens documentation at https://www.renpy.org/doc/html/screens.html:
Input
Creates a text input area, which allows the user to enter text. When the user presses return, the text will be returned by the interaction. (When the screen is invoked through call screen, the result will be placed in the _return variable.)

The input statement takes no parameters, and the following properties:

value
An input value object that this input uses. InputValue objects determine where the default value is taken from, what happens when the text is changed, what happens when enter is pressed, and if the text is editable by default.

This should not be given at the same time as default and changed.
Should I be trying to figure out how to get the changed to work from the Input Value object instead? I tried reading that section of the docs located here: https://www.renpy.org/doc/html/screen_a ... put-values

...but I don't really understand what I'm looking at :( I'm a real Python newb

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#9 Post by hell_oh_world »

duck-and-wolf wrote: Thu Sep 26, 2019 3:08 pm
hell_oh_world wrote: Thu Sep 26, 2019 2:22 pm Yup, but you're using a screen now for input and not the renpy.input() function directly.
But I am using the renpy.input() function directly, right? I haven't taken that line out of my main game script, this is the line that calls up the input prompt:

Code: Select all

python:
        nameHero = renpy.input(_("What {i}is{/i} your name?"), length = 24)
Wait... What? So what's the purpose of the screen that you made then? What are you trying to get from the prompt in the screen that you made? I thought you made the screen to be an alternative for the renpy.input function for the namehero, because I purely suggested the ui.input function at first knowing that you will replace your renpy.input() with it. If you'll ask me, its way better using a screen to prompt an input rather than calling the function directly. Because you have more freedom in styling your input prompt. As far as i know, I had issues like these, where input behaves strangely especially if I have multiple inputs shown on a screen that I made. It turns out that removing the other input and showing only one input at a time solves my problem. Maybe try that to see how it works.
Should I be trying to figure out how to get the changed to work from the Input Value object instead? I tried reading that section of the docs located here: https://www.renpy.org/doc/html/screen_a ... put-values
Yes, you can use the value property as an alternative for getting the input value, I've seen examples where they made use of it. Just like this.

Code: Select all

default nameHero = ""
screen sample:
	input:
		value VariableInputObject("nameHero")

duck-and-wolf
Regular
Posts: 47
Joined: Thu Aug 29, 2019 6:20 pm
Completed: Head of the Class
Organization: Duck & Wolf
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#10 Post by duck-and-wolf »

I didn't make that screen. That is the default Input screen that comes in screens.rpy:

Code: Select all

## Input screen ################################################################
##
## This screen is used to display renpy.input. The prompt parameter is used to
## pass a text prompt in.
##
## This screen must create an input displayable with id "input" to accept the
## various input parameters.
##
## https://www.renpy.org/doc/html/screen_special.html#input

screen input(prompt):
    style_prefix "input"

    window:

        vbox:
            xalign gui.dialogue_text_xalign
            xpos gui.dialogue_xpos
            xsize gui.dialogue_width
            ypos gui.dialogue_ypos

            text prompt style "input_prompt"
            input id "input":
                changed typewriter

style input_prompt is default

style input_prompt:
    xalign gui.dialogue_text_xalign
    properties gui.text_properties("input_prompt")

style input:
    xalign gui.dialogue_text_xalign
    xmaximum gui.dialogue_width
Literally all I did to it was add the changed typewriter keyword to the input.

And in my main game script, all I have is this:

Code: Select all

label name_loop:

    python:

        nameHero = renpy.input(_("What {i}is{/i} your name?"), length = 24) #, changed = typewriter()

        nameHero = nameHero.strip()

    if nameHero == "":

        jump name_loop

    else:

        jump name_valid
I got that code from this documentation page: https://www.renpy.org/doc/html/input.html

Again, that was working completely fine until I added the changed typewriter keyword to the input. And if I remove the changed typewriter keyword from the input in the screen, it works again.
its way better using a screen to prompt an input rather than calling the function directly. Because you have more freedom in styling your input prompt
How do I do that? The only example for doing an input I can find anywhere is the above linked Text Input documentation. That's also how they do it in the included tutorial:

Code: Select all

label tutorial_input:

    e "Some games might prompt the player for input."

    example input hide:
        python:
            name = renpy.input(_("What's your name?"))

            name = name.strip() or __("Guy Shy")
Is there a better way?

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#11 Post by hell_oh_world »

duck-and-wolf wrote: Thu Sep 26, 2019 6:05 pm Is there a better way?
First of all, as far as you can compromise don't touch the default pre-made screens, rather make your own. If you'll ask me this will be my way of doing input prompts like this.

Code: Select all

default player_name = ""

init python:
	def getInput(input_val):
		renpy.play("key_stroke.mp3")
		store.player_name = input_val.strip()

screen get_player_name:
	input:
		align (0.5, 0.5)
		default "Enter Player Name"
		changed getInput
		
label start:
	"The next step is to add name to your Player"
	show screen get_player_name
	"Great now your player's name is [player_name]"
Through these codes you have more flexibility, you can customize the input, you can even add pictures around it if you want. And you can achieve all those without altering the pre-made screens. Calling the renpy.input function invokes the input screen, which is right with you did, that you altered the screen. But it also applies to all the other inputs around renpy. So technically speaking the key stroke sound will also work with your other input workarounds. Thus, altering the input screen applies in a more general sense.
How do I do that? The only example for doing an input I can find anywhere is the above linked Text Input documentation. That's also how they do it in the included tutorial:
If you already made a screen then you already know how to style things. You style the input in a screen that you made just like how you normally style in a screen.

And one more thing, be sure that the cursor is on top of the input whenever your doing an input or pressing enter after an input. Because input in screens behaves like that, if you want to input or submit the input using enter, always make sure that the cursor is hovering the input.

duck-and-wolf
Regular
Posts: 47
Joined: Thu Aug 29, 2019 6:20 pm
Completed: Head of the Class
Organization: Duck & Wolf
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#12 Post by duck-and-wolf »

Holy crap, man, that's really awesome!!! Thank you so much for showing me all of that, it's gonna take me a second to process all the above.

I'm a little confused because this part:

Code: Select all

"The next step is to add name to your Player"
show screen get_player_name
"Great now your player's name is [player_name]"
Brings up the get_player_name screen in the center, but ALSO displays the next text box, which is: "Great now your player's name is "

Then when I hit enter, the get_player_name screen doesn't ever leave, and the game moves to the next text box, it doesn't actually show "Great now your player's name is [WHATEVER]" first. But I think I understand I have to hide the default window and then hide the get_player_name screen when I'm done with it, etc. I will play with what you've given me above and see if I can't finish it up from there. And the sound definitely works!

Thank you a ton, man, this is so, so helpful. Why don't the docs say to do it this way!?

duck-and-wolf
Regular
Posts: 47
Joined: Thu Aug 29, 2019 6:20 pm
Completed: Head of the Class
Organization: Duck & Wolf
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#13 Post by duck-and-wolf »

Oh, and how would I limit the input to only 24 characters with what you've shown me above?

EDIT: Nevermind, lol, I was able to figure out the 'length' keyword also works with this input: method you've shown me :roll:

duck-and-wolf
Regular
Posts: 47
Joined: Thu Aug 29, 2019 6:20 pm
Completed: Head of the Class
Organization: Duck & Wolf
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#14 Post by duck-and-wolf »

I got it working!!!!

Code: Select all

####################################################################################################################################

    # FUNCTIONS

init python:
    def getInput(input_val):
        renpy.play("sounds/typewriter.ogg", channel="audio")
        store.nameHero = input_val.strip()



####################################################################################################################################

    # SCREENS

screen nameHeroInput:
    frame:
        xpos 0
        ypos 0
        background "gui/nametag.png"

    frame:
        xalign 0.5
        yalign 0.55
        background "#FFF0"

        input:
            size 48
            align (0.5, 0.5)
            length 16
            color "F00"
            default ""
            changed getInput



####################################################################################################################################
And then I call it with this:

Code: Select all

####################################################################################################################################

label name_loop:

    $ quick_menu = False

    window hide

    $ nameHero = ""

    show screen nameHeroInput

    pause

    hide screen nameHeroInput

    if nameHero == "":

        jump name_loop

    else:

        jump name_valid



####################################################################################################################################

label name_valid:

    $ quick_menu = True

    window auto

    y "“It’s [nameHero].”"
    
    ...
Dude! This is so awesome! Thank you so so so so so so so much!!!! :D :D :D :D :D :D :D :D :D :D :D

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Text Input: problem with 'with_none' and 'changed' keywords

#15 Post by hell_oh_world »

duck-and-wolf wrote: Fri Sep 27, 2019 2:25 pm I got it working!!!!

Code: Select all

####################################################################################################################################

    # FUNCTIONS

init python:
    def getInput(input_val):
        renpy.play("sounds/typewriter.ogg", channel="audio")
        store.nameHero = input_val.strip()



####################################################################################################################################

    # SCREENS

screen nameHeroInput:
    frame:
        xpos 0
        ypos 0
        background "gui/nametag.png"

    frame:
        xalign 0.5
        yalign 0.55
        background "#FFF0"

        input:
            size 48
            align (0.5, 0.5)
            length 16
            color "F00"
            default ""
            changed getInput



####################################################################################################################################
And then I call it with this:

Code: Select all

####################################################################################################################################

label name_loop:

    $ quick_menu = False

    window hide

    $ nameHero = ""

    show screen nameHeroInput

    pause

    hide screen nameHeroInput

    if nameHero == "":

        jump name_loop

    else:

        jump name_valid



####################################################################################################################################

label name_valid:

    $ quick_menu = True

    window auto

    y "“It’s [nameHero].”"
    
    ...
Dude! This is so awesome! Thank you so so so so so so so much!!!! :D :D :D :D :D :D :D :D :D :D :D
Give yourself some credit :wink: . You earned it. You figured the rest while I was asleep. Nice hearing that I was able to help. :D

Also, if you want to make the player unable to interact to other things and only to the input when the screen shows up, set the screen property modal to True.
And the renpy.play() function automatically plays in the audio channel based on the doc, so I guess it's not necessary to specify the keyword argument.

Code: Select all

        renpy.play("sounds/typewriter.ogg")

Code: Select all

screen nameHeroInput:
    modal True

Post Reply

Who is online

Users browsing this forum: No registered users