Ren'Py [SOLVED]Renpy : how to call functions ?

GoldenD

Member
Sep 30, 2018
102
70
Hey guys,

happy new years at all. But that's all, i'm not here for that, we have work, guys ;)

My problem is certainly very simple for you. I don't understand how to call an user defined function in the following case. Read the code, problems are in the comments
What I call Function is OK, but what I call procedure is Bad ???

Python:
        #GOOD
        "Call User Defined Function":
            # I call function because return a value
            init python:
                def myFunction(myParam):
                    return myParam * 2

            $ resultFunction = myFunction(7)
            "[resultFunction]"

        #BAD
        "Call User Defined Procedure":
            # I call procedure because no value in return
            # 2 problems :
                #   1 - how to display what i want from the python procedure to renpy screen
                #   2 - how to call my procedure without $ resultProcedure = myProcedure("My Name is Ethan")
                #       I tried call myProcedure("My Name is Ethan")    => Not good
                #       I tried      myProcedure("My Name is Ethan")    => Not good

            init python:
                def myProcedure(myParam):
                    "[myParam]"                 # First problem here : don t know how to print on renpy screen
                    "Test"                      # First problem here : don t know how to print on renpy screen
                    return

            $ resultProcedure = myProcedure("My Name is Ethan") # 2nd problem here : don t know how to call,
                                                                # dont want a variable like $ resultProcedure
Thanks a lot for your feed back.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,302
15,172
Er... What do you really want to achieve ? There's so many possible use that can imply your "don't know how to print on Ren'py screen" that there isn't an effective answer to your question.


You can want to notify the player than something happened, in which case one of the possible solution would be this :
Code:
init python:
    def myFunc():
        renpy.notify( "Something happened" )

[...]
label whatever:
    menu:
        "wait":
            pass
        "do something":
            $ myFunct()
But it can also be done like that :
Code:
label whatever:
    menu:
        "wait":
            pass
        "do something":
            $ renpy.notify( "Something happened" )
You can want to make a character say something, in which case one way to do it can be this one :
Code:
default mc = Character( "the MC" )

init python:
    def myFunc():
        say( mc, "I did something" )

[...]
label whatever:
    menu:
        "wait":
            pass
        "do something":
            $ myFunct()
But it's really not the good way to do, you should use the say Python equivalent only in case of absolute necessity, and there's really really few case that are absolute necessity.

There's also the obvious text interpolation :
Code:
init python:
    def myFunc():
        return "I did something"

[...]
label whatever:
    menu:
        "wait":
            pass
        "do something":
            $ tmpVar = myFunct()
            "[tmpVar]"
Which imply the use of an external variable (that can be unique for all use), but it also imply that you'll benefit a 100% of the say statement, and don't risk to encounter problems due to the "interactions" (what Ren'py call this).

It can also be the update of a status, which can be, among other way, done like this :
Code:
default status = None
init python:
    def myFunc():
        store.status = "I did something"

screen whatever():
    if not status is None:
        text "Status: [status]"

label start:
    show screen whatever

[...]
label whatever:
    menu:
        "wait":
            pass
        "do something":
            $ myFunct()
And there's more possible case, which can be dealt with one of those answer, or need another one. But globally speaking, if what you want to achieve isn't the first or third case, then I would say that the problem come more surely from the thinking process than anything else.
 

GoldenD

Member
Sep 30, 2018
102
70
Er... What do you really want to achieve ? There's so many possible use that can imply your "don't know how to print on Ren'py screen" that there isn't an effective answer to your question.


You can want to notify the player than something happened, in which case one of the possible solution would be this :
Code:
init python:
    def myFunc():
        renpy.notify( "Something happened" )

[...]
label whatever:
    menu:
        "wait":
            pass
        "do something":
            $ myFunct()
But it can also be done like that :
Code:
label whatever:
    menu:
        "wait":
            pass
        "do something":
            $ renpy.notify( "Something happened" )
You can want to make a character say something, in which case one way to do it can be this one :
Code:
default mc = Character( "the MC" )

init python:
    def myFunc():
        say( mc, "I did something" )

[...]
label whatever:
    menu:
        "wait":
            pass
        "do something":
            $ myFunct()
But it's really not the good way to do, you should use the say Python equivalent only in case of absolute necessity, and there's really really few case that are absolute necessity.

There's also the obvious text interpolation :
Code:
init python:
    def myFunc():
        return "I did something"

[...]
label whatever:
    menu:
        "wait":
            pass
        "do something":
            $ tmpVar = myFunct()
            "[tmpVar]"
Which imply the use of an external variable (that can be unique for all use), but it also imply that you'll benefit a 100% of the say statement, and don't risk to encounter problems due to the "interactions" (what Ren'py call this).

It can also be the update of a status, which can be, among other way, done like this :
Code:
default status = None
init python:
    def myFunc():
        store.status = "I did something"

screen whatever():
    if not status is None:
        text "Status: [status]"

label start:
    show screen whatever

[...]
label whatever:
    menu:
        "wait":
            pass
        "do something":
            $ myFunct()
And there's more possible case, which can be dealt with one of those answer, or need another one. But globally speaking, if what you want to achieve isn't the first or third case, then I would say that the problem come more surely from the thinking process than anything else.
Hi anne O'nymous,

you gave me the answer. I was searching after "renpy.notify".

And that's great that's You who answer cause i've read a lot of your work and explanations on the web. Clear and succinct.
I searched about another subject, the reading and writing files (txt, ini), which seems interested some people. I can read and write with renpy, but i need something more specific. I think i found the tools to do it, but i need someone who knows renpy and python to make me time earning. Is that clear and can i submit you hthe elements ?

In all case, thanks a lot for your answer.

? Is there a flag to note this post Close ?
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,302
15,172
I can read and write with renpy, but i need something more specific.
If you really need something specific, then there's nothing better than using a JSON file, and it's really easy to do, you don't need a tool for this :
Code:
init python:
    import json

    def myImport( fileName ):
        JSON = ""
        FH = open( renpy.os.path.join( config.gamedir, fileName ), "r" )
        for line in FH: JSON += line
        return json.loads( JSON )
    
label whatever:
    $ myConfig = myImport( "config.json" )
    $ shopInventory = myImport( "inventory.json" )
"myConfig" and "shopInventory" will now be dictionaries built according to the JSON file.

JSON files are really easy do write manually, they looks like a basic Python structure. By example the shop inventory can looks like this :
Code:
{
    "candy" : [ 10, "Those are tasty candies", "shop/item/candy.jpg" ],
    "binoculars" : [ 100, "Do you want to look at birds, or girls ?", "shop/item/binoculars.jpg" ]
}
You define an anonymous dictionary that will be the base. Inside you've two ("candy" and "binoculars") which are lists. The first entry in the list is a number (the price), and the two others a string (the description of the item, and the path to the image representing it).

Once loaded, you access them like regular Python/Ren'py variables :
Code:
label whatever:
    menu:
        "buy one candy":
              $ money -= shopInventory["candy"][0]
I used a list to store the information related to each item to show how it's wrote, but in this particular case, having a dict would be better.

You can also write relatively into a JSON file from Ren'py.


But all this said, do you really need to rely on an external file ?
From my point of view, there's really few cases that need this, and it will always better to rely on a Ren'py label :
Code:
label createInventory:
    python:
        shopInventory = {}
        shopInventory["candy"] = [ 10, "Those are tasty candies", "shop/item/candy.jpg" ]
        shopInventory["binoculars"] =  [ 100, "Do you want to look at birds, or girls ?", "shop/item/binoculars.jpg" ]
    return

image flowers = "shop/item/flowers.jpg"
image gift =  "shop/item/gift.jpg"
label alteranateInventory:
    python:
        shopInventory = {}
        shopInventory["flowers"] = [ 5, "Her birthday was yesterday !",  flowers ]
        shopInventory["gifts"] =  [ 500, "An amazing gift for her", gift ]
    return

label start:
    if regularGame is True:
        call createInventory
    else:
        call alternateInventory
And the "alternateInventory" as well as the "createInventory" don't need to be in the same file.

It will always be a better approach than an effective external file. This especially since this way Ren'py will tell you if something is wrong or odd, and you can also use Ren'py data structures directly.
 

GoldenD

Member
Sep 30, 2018
102
70
If you really need something specific, then there's nothing better than using a JSON file, and it's really easy to do, you don't need a tool for this :
Code:
init python:
    import json

    def myImport( fileName ):
        JSON = ""
        FH = open( renpy.os.path.join( config.gamedir, fileName ), "r" )
        for line in FH: JSON += line
        return json.loads( JSON )
   
label whatever:
    $ myConfig = myImport( "config.json" )
    $ shopInventory = myImport( "inventory.json" )
"myConfig" and "shopInventory" will now be dictionaries built according to the JSON file.

JSON files are really easy do write manually, they looks like a basic Python structure. By example the shop inventory can looks like this :
Code:
{
    "candy" : [ 10, "Those are tasty candies", "shop/item/candy.jpg" ],
    "binoculars" : [ 100, "Do you want to look at birds, or girls ?", "shop/item/binoculars.jpg" ]
}
You define an anonymous dictionary that will be the base. Inside you've two ("candy" and "binoculars") which are lists. The first entry in the list is a number (the price), and the two others a string (the description of the item, and the path to the image representing it).

Once loaded, you access them like regular Python/Ren'py variables :
Code:
label whatever:
    menu:
        "buy one candy":
              $ money -= shopInventory["candy"][0]
I used a list to store the information related to each item to show how it's wrote, but in this particular case, having a dict would be better.

You can also write relatively into a JSON file from Ren'py.


But all this said, do you really need to rely on an external file ?
From my point of view, there's really few cases that need this, and it will always better to rely on a Ren'py label :
Code:
label createInventory:
    python:
        shopInventory = {}
        shopInventory["candy"] = [ 10, "Those are tasty candies", "shop/item/candy.jpg" ]
        shopInventory["binoculars"] =  [ 100, "Do you want to look at birds, or girls ?", "shop/item/binoculars.jpg" ]
    return

image flowers = "shop/item/flowers.jpg"
image gift =  "shop/item/gift.jpg"
label alteranateInventory:
    python:
        shopInventory = {}
        shopInventory["flowers"] = [ 5, "Her birthday was yesterday !",  flowers ]
        shopInventory["gifts"] =  [ 500, "An amazing gift for her", gift ]
    return

label start:
    if regularGame is True:
        call createInventory
    else:
        call alternateInventory
And the "alternateInventory" as well as the "createInventory" don't need to be in the same file.

It will always be a better approach than an effective external file. This especially since this way Ren'py will tell you if something is wrong or odd, and you can also use Ren'py data structures directly.
Ok,
i understand your point of view and effectively, maybe i don't need of external file. I begin with renpy, 3 days in fact, and i try to cover all my basical needs to know if renpy is a tool i can use or no.
Today, i can say it's ok for variables, functions, modules (or packages), playing movies and it seems files use is ok. So I think i'll soon try to remastered a game in renpy.

Thanks a lot guy.