Page 1 of 1

Renpy Controlflow - Ren'py-return after label-call by Python-function

Posted: Sat Jul 24, 2021 12:35 pm
by Livinginafreeworld
Hi,

I have a question about the control flow of ren'py (7.4.1).
For a VN, I wanted to build kind of a replay function in which you can decide to view one or many scenes in one go.
The replayed scenes are called by label and have a return command to return to the gallery.
To view many scenes at once, I have created a python function which when it is called, should loop through many labels and call the scenes.
But the return of the scene-call goes not into the function-loop but rather directly after the function in the script.
I just found a workaround to that problem (saved the replay-labels in a global list and called an outside label from where I could call all the replays with a while-loop in ren'py code.
But I'm still interested in, why this happened and whether there is a solution, that is more clean.
I attach a simplified version of my problem as script:

Code: Select all

#function declaration
init python:
    def testfunction():
        for i in range(1,4):
            renpy.call("repeat"+str(i))

#script
label start:
    "Start of Loop."
    $testfunction()
    "End of Loop"
    return

label repeat1:
    "Loop 1"
    return

label repeat2:
    "Loop 2"
    return

label repeat3:
    "Loop 3"
    return

I expected the control flow to jump after a return statement back to the for-loop in the python-function. So the flow should be:

Start of Loop
Loop 1
Loop 2
Loop 3
End of Loop

But what I get is:

Start of Loop
Loop 1
End of Loop

Does anybody know why this is?

Best regards

Living

Re: Renpy Controlflow - Ren'py-return after label-call by Python-function

Posted: Sat Jul 24, 2021 1:33 pm
by Alex
Livinginafreeworld wrote: Sat Jul 24, 2021 12:35 pm ...But the return of the scene-call goes not into the function-loop but rather directly after the function in the script....
That's how it works. Call statement has a 'from_current' property to let game return to the line of code where it was called - https://www.renpy.org/doc/html/statemen ... renpy.call

Also, Ren'Py has a replay function that is let player to replay a part of game and easy to use - https://www.renpy.org/doc/html/rooms.html#replay

Re: Renpy Controlflow - Ren'py-return after label-call by Python-function

Posted: Sat Jul 24, 2021 1:47 pm
by PyTom
That's not 100% right. renpy.call leaves the current Ren'Py statement, which might consist of many Python statements. It can return to either the start or the end of the current Ren'Py statement, but it can't return into the middle of a Python loop - there simply isn't a way to stick Ren'Py in the middle of a block of Python.

Re: Renpy Controlflow - Ren'py-return after label-call by Python-function

Posted: Sat Jul 24, 2021 1:50 pm
by strayerror
The problem you have is that $testfunction() is a single Ren'Py "statement". And calls return control to the next statement, so any call triggered within your python code will return control flow to the next statement, i.e. "End of Loop".

The from_current argument mentioned by Alex alters this behaviour such that call will return control to the current statement ($testfunction()) which will result in your function being re-executed, I suspect this would lead to just playing repeat1 over and over again.

Your best bet is probably to have Ren'Py handle the loop for you. Something like:

Warning: Untested!

Code: Select all

label start:
    "Start of Loop."
    $ x = 1
    while x < 4:
        call expression 'repeat' + x
        $ x += 1
    "End of Loop"
    return

label repeat1:
    "Loop 1"
    return

label repeat2:
    "Loop 2"
    return

label repeat3:
    "Loop 3"
    return

Re: Renpy Controlflow - Ren'py-return after label-call by Python-function

Posted: Sun Jul 25, 2021 12:24 pm
by Livinginafreeworld
Thank you very much for your answers. so in my own words, it's mainly because everything inside of a "python:-statement" is only counted as one renpy statement, where the call returns before or after, if I understand it right.

Special thanks to strayerror for the source code. With addition of a str() statement to transform the int to string the code works fine.

Code: Select all

label start:
    "Start of Loop."
    $ x = 1
    while x < 4:
        call expression 'repeat' + str(x)
        $ x += 1
    "End of Loop"
    return

label repeat1:
    "Loop 1"
    return

label repeat2:
    "Loop 2"
    return

label repeat3:
    "Loop 3"
    return