[SOLVED] Problems with screen input

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
User avatar
amaame
Newbie
Posts: 3
Joined: Sat Jan 27, 2024 3:34 pm
Contact:

[SOLVED] Problems with screen input

#1 Post by amaame »

Ren'py Version: 8.1.3

Hello there. I'm trying to insert a screen which performs like a console, so that a player can input some command and get response. I do not know much about python and the Ren'py console example is too complex for me now. But with the help of many topics in this forum, part of the functions have been realized.

However, there are still two problems I cannot understand:
1) I have removed K_RETURN from the keymap say column, and in normal gameplay K_RETURN just doesn't work. But when the screen is shown, it works again. More than that, in the screen the mouse1 seems to be bound with K_RETURN. When mouse1 is clicked, the input text also returns. I understand that the document says "This may also raise renpy.IgnoreEvent to ignore the press. Otherwise, the enter-press is propagated to other displayables." However, I'm not sure how to use "raise renpy.IgnoreEvent()" correctly. If it is inserted after enter(self) return, it doesn't work, if before, the input cannot return. I use a scissors-and-paste InputValue class:

Code: Select all

init python:
    class EnterInputValue(InputValue, FieldEquality):
        default = True
        editable = True
        returnable = False
        identity_fields = [ ]
        equality_fields = [ "variable", "returnable" ]
        def __init__(self, variable, default=True, returnable=False):
            self.variable = variable
            self.default = True
            self.returnable = returnable
        def get_text(self):
            return ""
        def set_text(self, s):
            _set_field(store, self.variable, s, "variable")
            #renpy.restart_interaction()
        def enter(self):                
            return 0  
            raise renpy.IgnoreEvent()        
            #renpy.restart_interaction()
2)The screen works just as I expected, except that along with every message returns, the dialog goes forward. However, another problem is that everytime I try to roll back, exception occurs: "Exception: renpy.restart_interaction( was called 100 times without processing any input." I need to refresh the screen to update the "idelog", and "renpy.config.periodic_callbacks.append( renpy.restart_interaction )" is not applicable because the input cannot proceed normally. How should I resolve this? To forbid the screen to rollback is also a choice but I don't know how.

Code: Select all

image bg white= "#FFFFFF"
define ideinput = ""
define ideinput2 = ""
define ideoutput = ""
default idelog = ""
    screen ide_screen:
          
        $yadj.value = yadjValue      
        modal False 
        dismiss action Return()                
        window:
            background  "bg white"             
            xalign 0.5
            ypos 1080
            ysize 250
            
            viewport yadjustment yadj:
                scrollbars "vertical"
                draggable True 
                mousewheel True
                
                vbox:
                    if  idelog != "":
                        text "[idelog]" size 28   
                    
                    input: 
                        size 28
                        #default ""
                        prefix "Mir3>" 
                        multiline False
                        copypaste True 
                        ypos 0
                        value EnterInputValue('ideinput')#, default=True,returnable=True)
                                                
                    if ideinput != "":  
                        $ ideinput2 = str.lower(ideinput)
                        $ ideinput2 = ideinput2.strip()
                        #$ ideinput2 = ideinput2.replace(' ','')
                        if  idelog == "":
                            $ idelog =idelog+"Mir3>"+ideinput +'\n' 
                        else:
                            $ idelog =idelog+'\n' +"Mir3>"+ideinput +'\n'   
                                 

                        if ideinput2  == "mir3":
                            $ideoutput =  "notbad"
                        elif ideinput2  == "clear":
                            $ideoutput = ""
                            $idelog =""
                        else:
                            $ideoutput = "?"
                        #text "[ideinput]" size 28
                        #text "[ideoutput]" size 28
                        $ idelog =idelog +ideoutput 
                        #$ renpy.config.periodic_callbacks.append(keep_ticking)
                        $ renpy.restart_interaction()
show screen ide_screen()                  
Thanks in advance for your help)
Last edited by amaame on Mon Jan 29, 2024 4:55 am, edited 1 time in total.

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2406
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: Problems with screen input

#2 Post by Ocelot »

What do you mean by "When mouse1 is clicked, the input text also returns"? How do you determine that it is a return, because in your code I see nothing that can even return at all? Could it be a simple screen refresh that recreates your input value and you think that text disappearing is a return?

Hint: if you want more than a simple text input on static screen, make InputValue a Screen Variable by using default input_value = EnterInputValue(... in the beginning of your screen.

Another problem is overuse of Python in screens.
First of all:
Documentation wrote:Python must not cause side effects that are visible from outside the screen. Ren'Py will run a screen multiple times, as it deems necessary. It runs a screen as part of the image prediction process, before the screen is first shown. As a result, if a screen has side effects, those side effects may occur at unpredictable times.
https://www.renpy.org/doc/html/screens.html#python
Second: remember that RenPy will reevaluate and rerun all statements in your screen if you do so mich as blink. idelog variable will be probably several hundred lines in length before you can even press a second button.
< < insert Rick Cook quote here > >

User avatar
amaame
Newbie
Posts: 3
Joined: Sat Jan 27, 2024 3:34 pm
Contact:

Re: Problems with screen input

#3 Post by amaame »

Thank you for your reply.
How do you determine that it is a return, because in your code I see nothing that can even return at all?
Yes, I thought it is a return when the idelog updates, the input and one more "?" appears in the screen.
Could it be a simple screen refresh that recreates your input value and you think that text disappearing is a return?
You are right, it seems when the dialog refreshes, the screen refreshes together, and vice versa. Can I refresh the screen while keeping the dialog unchanged?

On the second problem, thank you for your suggestion. I shall manage it afterwards.

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2406
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: Problems with screen input

#4 Post by Ocelot »

I made a quick example:

Code: Select all

init python:
    class ConsoleInput(InputValue):
        def __init__(self, log=None, actions={}):
            self.text = ""
            self.log = log
            self.actions = actions

        def get_text(self):
            return self.text

        def set_text(self, text):
            self.text = text

        def enter(self):
            if self.log is not None:
                self.log.append(self.text)
            if self.text in self.actions:
                renpy.run(self.actions[self.text])
            self.text = ""
            renpy.restart_interaction()    
            raise renpy.IgnoreEvent()

screen console(log):
    default cinput = ConsoleInput(log, {"clear": Function(log.clear), "mir3": SetScreenVariable("output", "Nice!")})
    default output = ""
    vbox:
        ysize .5
        box_reverse True
        text output
        input value cinput prefix "Mir3>"
        viewport:
            yinitial  1.0
            has fixed
            yfill True
            vbox:
                yalign 1.0
                for i in log:
                    text "Mir3>" + i

default log = [] 

label start:

    show screen console(log)
    "..."
    ".."
    "."

    return
It looks like this:
https://drive.google.com/file/d/109GDcl ... p=drivesdk

Might be some bugs, but it should give you some pointers.
< < insert Rick Cook quote here > >

User avatar
amaame
Newbie
Posts: 3
Joined: Sat Jan 27, 2024 3:34 pm
Contact:

Re: Problems with screen input

#5 Post by amaame »

This example is very helpful. With a little modification, it works very well. Really appreciate!

Post Reply

Who is online

Users browsing this forum: Google [Bot], Ocelot