How to make a Button action do a "call"?

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.
Message
Author
klaim
Newbie
Posts: 19
Joined: Fri Jan 17, 2014 8:55 am
Contact:

How to make a Button action do a "call"?

#1 Post by klaim »

I am discovering the screen system.
My final goal is to be able to insert a bit of additional dialogue in the current one, at any point,
when the player press a specific button.

I managed to get almost what I want:

Code: Select all

label wat:
    thedog "WAF WAF, WAF WAF WAF!!!"
    return

label scene_intro:

    screen hello_world():
        window id "test_window":
            xcenter 0.5
            ycenter 0.5
            xsize 500
            ysize 500
            vbox:
                spacing 10
                text "HELLO"
                text "WORLD"
                button:
                    text "WAF WAF"
                    action Jump("wat")
                    

    scene white with fade
    
    show screen hello_world
    
    thedog "WAF WAF!"

    thedog "Who let the dogs out?"

    return
My goal: when 'wat' returns, it gets back at the exact point of the dialogue when the "WAF WAF" button was called.

Here I use the Jump action to be called when the button is pressed.
Unfortunately it does exactly like 'jump': once 'wat' returns from last label that was "called",
not from the current label 'wat'.
If I remove the return from the 'wat' label, I obviously get back to the 'scene_intro' label, which seems logic.
The Jump action does what you would expect from 'jump' command, but I can't find an Action which would do what you would expect from 'call'.

Am I missing something? Is there an equivalent of 'call' that can be used as action?

/-----

After writing this I found a solution but it looks like a "hack":

Code: Select all

action Function(renpy.call, label="wat")
It does exactly what I want but I feel like it should be encapsulated in a Call object or something cleaner.
Any suggestion for a better way to do it?

User avatar
namastaii
Eileen-Class Veteran
Posts: 1350
Joined: Mon Feb 02, 2015 8:35 pm
Projects: Template Maker for Ren'Py, What Life
Github: lunalucid
Skype: Discord: lunalucid#1991
Soundcloud: LunaLucidMusic
itch: lunalucid
Location: USA
Contact:

Re: How to make a Button action do a "call"?

#2 Post by namastaii »

cleaner how?

The only thing I can think of is changing that button into this format:

textbutton "waf waf" action Jump("wat")

maybe even possibly put the scenes you want separate in separate files/pages.

klaim
Newbie
Posts: 19
Joined: Fri Jan 17, 2014 8:55 am
Contact:

Re: How to make a Button action do a "call"?

#3 Post by klaim »

Using Jump() won't allow to return back to the interrupted scene (as explained in the initial example).
Moving scenes in separate files/pages won't change anything about that as it's a label flow issue apparently.

By cleaner I mean something like a Call("somelabel") action which would do exactly Function(renpy.call, "somelabel")
which then allow me to return from "somelabel" to get back to the point the button was pushed.

User avatar
namastaii
Eileen-Class Veteran
Posts: 1350
Joined: Mon Feb 02, 2015 8:35 pm
Projects: Template Maker for Ren'Py, What Life
Github: lunalucid
Skype: Discord: lunalucid#1991
Soundcloud: LunaLucidMusic
itch: lunalucid
Location: USA
Contact:

Re: How to make a Button action do a "call"?

#4 Post by namastaii »

Hmm could you explain more in detail how it goes? Are you calling a separate scene in or a screen or a sound or what? what kind of interruption?

User avatar
namastaii
Eileen-Class Veteran
Posts: 1350
Joined: Mon Feb 02, 2015 8:35 pm
Projects: Template Maker for Ren'Py, What Life
Github: lunalucid
Skype: Discord: lunalucid#1991
Soundcloud: LunaLucidMusic
itch: lunalucid
Location: USA
Contact:

Re: How to make a Button action do a "call"?

#5 Post by namastaii »

The thing with labels is, is basically no matter what, if you're jumping to a label it's starting the scene over. So you'll have to treat whatever you're calling in something different than another label if you don't want it to start anything over

klaim
Newbie
Posts: 19
Joined: Fri Jan 17, 2014 8:55 am
Contact:

Re: How to make a Button action do a "call"?

#6 Post by klaim »

Ok let me try to re-explain what I am doing (full demo script at the end of this block):

Here is a simple dialog script:

Code: Select all

label scene_1: 

  A "Hello!"
  B "Hello, how are you?"
  A "I'm fine, thank you! And you?"
  B "I'm fine too, let's have fun now!"
  A "Yes! Here are the sausages!"

While playing this, I want the player to have, at any time, the ability to do special actions.
Special actions are basically like choices BUT you can do them at any moment in a dialog, so you don't have to actual hint that tells you that the story is branching now.
It's just a gameplay feature.
So, I have this menu with buttons displayed, which is defined something like this:

Code: Select all

screen special_actions_screen():
        window id "special_actions_window":
            # place the window on the right of the screen
            vbox:
                # ...
                button:
                    text "Smile/Grin"
                    action Jump("on_smile_1") # for this example, let's assume that this never change
                button:
                    text "Punch In The Face"
                    action Jump("on_punch_1") # for this example, let's assume that this never change
The player then have the possibility to punch anyone in the face at any moment and to smile/grin at any moment too,
which might have or not an actual effect on the ongoing context.

Now let's say I have these reactions:

Code: Select all

label on_smile_1:
   "My grin shines a lot."
   "It makes everybody smile in the room too!"
   "I feel happy but a bit dumb too, but oh well..."
   return #Back to the previous dialog.

label on_punch_1:
   "After this, everything went very fast."
   "I ended up in jail..."
   "...and stayed there until the end of my life."
   # The game ends here.
Take notice of the "return" command at the end of on_smile_1.

on_punch_1 is designed as a simple branch in the story: if the player punch someone in the face with no reason,
he ends up in jail. It's just a branch.
In this case, defining the punch button action as shown before:

Code: Select all

    action Jump("on_punch_1")
does work because "jump" just branch the story to somewhere else without keeping the call "stack".
So it is fine.

However, on_smile_1 is designed so that this small bit of dialogue gets "injected" into the dialog being played at the point the player pressed the button.

In this example's code, you can see that at the end of on_smile_1 we "return" because after this small ellipsis we need to get back
to the previous dialog, whatever it is, at whatever point it was when the player pressed the button.
So at this point, what I need is actually the "call" statementas the action to be run when the smile/grin button is pressed.
Something that would look like this:

Code: Select all

    action Call("on_smile_1") # Error: Call does not exists
Unfortunately this does not work. I see a "renpy.Call" class in the Renpy source code but it does not seem to be accessible from this point.
This seems consistent with the actions documentation describing a Jump action (equivalent to the jump statement) but not a Call action (which would have been equivalent to the call statement).

Now, another way to do what I want here, that actually seem to work, is to use the Function action which calls an arbitrary python callable. I assumed that the "call" statement was a callable and wrote something like this:

Code: Select all

    action Function(renpy.call, label="on_smile_1") # equivalent to "call on_smile_1", ugly but seems to work
This works: pressing the button will run the on_smile_1 dialog, and it's "return" statement will jump back to the previous dialog.
Now a run of the game where I press the smile button at a random point of the scene would look like this (from the player POV):
A "Hello!"
B "Hello, how are you?"
# HERE I PRESS THE SMILE BUTTON
"My grin shines a lot."
"It makes everybody smile in the room too!"
"I feel happy but a bit dumb too, but oh well..."
A "I'm fine, thank you! And you?"
B "I'm fine too, let's have fun now!"
# HERE I PRESS THE SMILE BUTTON AGAIN, BECAUSE I CAN
"My grin shines a lot."
"It makes everybody smile in the room too!"
"I feel happy but a bit dumb too, but oh well..."
A "Yes! Here are the sausages!"
Here is a complete renpy script demonstrating how it works.

Code: Select all

    
screen special_actions_screen():
    window id "special_actions_window":
        
        at topright        
        
        # place the window on the right of the screen
        vbox:
            at right
            # ...
            button:
                text "Smile/Grin"
                action Function(renpy.call, label="on_smile_1") # ugly but works as expected
            button:
                text "Punch In The Face"
                action Jump("on_punch_1")

label start:

                
    show screen special_actions_screen
    
    define A = Character(name="Anna")
    define B = Character(name="Barbara")
    
    jump scene_1


label scene_1: 

    A "Hello!"
    B "Hello, how are you?"
    A "I'm fine, thank you! And you?"
    B "I'm fine too, let's have fun now!"
    A "Yes! Here are the sausages!"
    "Happy Ending."
    return
  
label on_smile_1:
   "My grin shines a lot."
   "It makes everybody smile in the room too!"
   "I feel happy but a bit dumb too, but oh well..."
   return #Back to the previous dialog.

label on_punch_1:
   "After this, everything went very fast."
   "I ended up in jail..."
   "...and stayed there until the end of my life."
   "BAD ENDING"
   return
   
Just try to "smile" at any point in the dialog and you will see that you get back right at the point you branched out.

Now, my question is: why isn't there a "Call" action already? There is a "Jump" one, but no "Call".

Or does the developers need a pull request? I'm not sure I can find the time but I can try.

klaim
Newbie
Posts: 19
Joined: Fri Jan 17, 2014 8:55 am
Contact:

Re: How to make a Button action do a "call"?

#7 Post by klaim »

namastaii wrote:The thing with labels is, is basically no matter what, if you're jumping to a label it's starting the scene over. So you'll have to treat whatever you're calling in something different than another label if you don't want it to start anything over
You are correct IFF I use "jump" to jump to another label.
My understanding is that this is not the case IFF you use "call" to jump to the label AND the label ends with a "return" statement, in which case the story goes back at the last"call" point. (which is basically how procedural programming works).

The control flow documentation pageexplains it well too:
The call statement is used to transfer control to the given label. It also pushes the next statement onto the call stack, allowing the return statement to return control to the statement following the call.
Or did I miss something?


Is my previous explanation clear enough? I think the demo show the idea but maybe I am still not really clear...

philat
Eileen-Class Veteran
Posts: 1912
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: How to make a Button action do a "call"?

#8 Post by philat »

Well... you already know how to do what you want, so I don't see what the fuss is, to be honest. There is no pre-defined Call action, if that's what you're asking.

klaim
Newbie
Posts: 19
Joined: Fri Jan 17, 2014 8:55 am
Contact:

Re: How to make a Button action do a "call"?

#9 Post by klaim »

philat wrote:Well... you already know how to do what you want,
It's definitely a hack, not really what I expect...(at least as a programmer)
so I don't see what the fuss is, to be honest. There is no pre-defined Call action, if that's what you're asking.
Again, the fuss is: why isn't Call action defined already by Renpy? Or: why is Jump defined but not Call? Is there an actual reason?

As said before, what I'm doing is definitely a hack and it seems either nobody tried to do that before (which I can't believe) or Call action was just forgotten (which means nobody tried that before, which I can't believe).
Or there might be a technical reason I'm missing.

I'll post an issue in github so that the developers see my question.
EDIT: https://github.com/renpy/renpy/issues/784

philat
Eileen-Class Veteran
Posts: 1912
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: How to make a Button action do a "call"?

#10 Post by philat »

The reason it's not supported by default has to do with save/rollback issues, I believe. I frankly don't think it matters for use cases like yours.

http://lemmasoft.renai.us/forums/viewto ... =8&t=32971
http://lemmasoft.renai.us/forums/viewto ... =8&t=13187

User avatar
namastaii
Eileen-Class Veteran
Posts: 1350
Joined: Mon Feb 02, 2015 8:35 pm
Projects: Template Maker for Ren'Py, What Life
Github: lunalucid
Skype: Discord: lunalucid#1991
Soundcloud: LunaLucidMusic
itch: lunalucid
Location: USA
Contact:

Re: How to make a Button action do a "call"?

#11 Post by namastaii »

Hmmm
Okay I understand perfectly what you want to do.

Honestly I've never thought about implementing something like that before so I'm not sure what the best way is.

If you could somehow turn the smile action into a call or something like you said (and not a label) then it could potentially return back to the previous dialogue.

Is the smile dialogue just thinking to yourself? If so, maybe you could turn this into something other than dialogue. Something that pops up and then goes away when you're doing reading it? That way, it's like calling in a screen of some sort then you can just continue on with the story without jumping to any scene or changing the dialogue. If that makes sense.

klaim
Newbie
Posts: 19
Joined: Fri Jan 17, 2014 8:55 am
Contact:

Re: How to make a Button action do a "call"?

#12 Post by klaim »

namastaii wrote:
Is the smile dialogue just thinking to yourself? If so, maybe you could turn this into something other than dialogue. Something that pops up and then goes away when you're doing reading it? That way, it's like calling in a screen of some sort then you can just continue on with the story without jumping to any scene or changing the dialogue. If that makes sense.

Yes it's one possibility among a lot of others. I got to that idea through a game idea which would imply this kind of thing, but also allow some hidden paths when we don't return from the label. It's basically a way to manage the cases where the player have a reaction but it have no impact on the story. Trying buttons at every dialog line is not very efficient so most players would just try to find the right reaction to the right context.

If there was a way to provide a statement instead of Python code in the action of the button, it would have been ideal. But it does not seem possible at the moment.

klaim
Newbie
Posts: 19
Joined: Fri Jan 17, 2014 8:55 am
Contact:

Re: How to make a Button action do a "call"?

#13 Post by klaim »

philat wrote:The reason it's not supported by default has to do with save/rollback issues, I believe. I frankly don't think it matters for use cases like yours.

http://lemmasoft.renai.us/forums/viewto ... =8&t=32971
http://lemmasoft.renai.us/forums/viewto ... =8&t=13187

Interesting, didn't thought about that... thanks!

EDIT: By the way, Thanks to everybody, you're very helpful! (compared to other places XD)

User avatar
Evildumdum
Regular
Posts: 191
Joined: Sun Jan 18, 2015 8:49 am
Projects: ApoclypseZ
Contact:

Re: How to make a Button action do a "call"?

#14 Post by Evildumdum »

Try using ui.callsinnewcontext instead of Call when you tell the button what action to do.
"If at first you don't succeed, try hitting it with a shoe."

User avatar
namastaii
Eileen-Class Veteran
Posts: 1350
Joined: Mon Feb 02, 2015 8:35 pm
Projects: Template Maker for Ren'Py, What Life
Github: lunalucid
Skype: Discord: lunalucid#1991
Soundcloud: LunaLucidMusic
itch: lunalucid
Location: USA
Contact:

Re: How to make a Button action do a "call"?

#15 Post by namastaii »

Usually that just opens up a screen though, doesn't it? and you'd have to init python it and change everything into that format for that chunk

Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot]