Page 1 of 2

Insert variables into code instead of into strings?

Posted: Fri Jan 06, 2017 7:36 pm
by unicodepepper
So, I know there's a way to put a variable inside a string of text, like "Let's go to [place]"

But in the game I want to make right now, there's a (fairly large) list of places, and the have certain connections with each others, so right now, what I do is to add this menu for each place:

Code: Select all

label home:
    nvl clear
    scene bg home with fade
    call home_before_event
    menu:
        "go to the back yard"
            jump yard
        "go to the city":
            jump city
        "stay here":
            call home_event
            call time_advance
            call home_after_event
    return
However, since they're 10+ places, every time I want to add an update for the code (say, another type of event or an option to not advance the time after it) it's a huge pain to go through each instance of the code, and it's even worse if there's a bug.

So I wanted to know if there's a way to make a single menu and invoke it, while keeping a variable called "location" (for example), which would then be evaluated and the correct menu shown. Like, "call %location%_after_event"

Re: Insert variables into code instead of into strings?

Posted: Fri Jan 06, 2017 8:43 pm
by Milkymalk
You want to use "call expression location", which treats the word "location" as a variable.

Re: Insert variables into code instead of into strings?

Posted: Sat Jan 07, 2017 2:48 am
by Apa
Milkymalk wrote:You want to use "call expression location", which treats the word "location" as a variable.
I guess, unicodepepper meant something really simple:
There are multiple locations.
Available jumps between locations described by a [directional] graph.
He wants to have a function to show menu from a location.
Menu items are available jumps from the location.
Naturally, as game progress the graph is updated with more moves and locations.

Am i wrong about it? :oops:

Re: Insert variables into code instead of into strings?

Posted: Sat Jan 07, 2017 1:15 pm
by Milkymalk
Ah, so basically a map stored that can be read to determine if you can go to a certain place from another?

You could make a list that stores your possible ways:

Code: Select all

default ways = [[1,2],[0],[1]]  # map looks like this:  (1)-(0)-(2)
default room = 0

label gameloop:
    call walk_menu(room)
    jump gameloop

label walk_menu(r):
    menu:
        "Go to Room 0" if 0 in ways[r]:
            $ room = 0
        "Go to Room 1" if 1 in ways[r]:
            $ room = 1
        "Go to Room 2" if 2 in ways[r]:
            $ room = 2
    return

Re: Insert variables into code instead of into strings?

Posted: Sat Jan 07, 2017 1:19 pm
by Ocelot
Note that you can build menu dynamically using menu or renpy.display_menu functions: https://www.renpy.org/doc/html/statemen ... oice-menus

Re: Insert variables into code instead of into strings?

Posted: Sat Jan 07, 2017 3:00 pm
by Apa
Ocelot wrote:Note that you can build menu dynamically using menu or renpy.display_menu functions: https://www.renpy.org/doc/html/statemen ... oice-menus
Yep, that’s more like it!
Milkymalk wrote:

Code: Select all

default ways = [[1,2],[0],[1]]  # map looks like this:  (1)-(0)-(2)
I’d rather take example from here or here, so I don’t have to retype it.

With labels defined like these

Code: Select all

label a:
    scene bg background(a) with fade
    call before_event(a)
    renpy.display_menu(built_menu(a))
* the code above can be put into another function too!

Can labels be used as graph vertices, so lint can catch errors there?
And/or what would be the optimal/minimum approach to keep it all together?

Re: Insert variables into code instead of into strings?

Posted: Sat Jan 07, 2017 3:54 pm
by Milkymalk
Apa wrote:
Milkymalk wrote:

Code: Select all

default ways = [[1,2],[0],[1]]  # map looks like this:  (1)-(0)-(2)
I’d rather take example from here or here, so I don’t have to retype it.
Somehow I get the impression that this would make the whole problem unnecessarily complicated.

Re: Insert variables into code instead of into strings?

Posted: Sat Jan 07, 2017 7:26 pm
by Apa
Milkymalk wrote:Somehow I get the impression that this would make the whole problem unnecessarily complicated.
I meant something really simple:

Code: Select all

default room = "home"
default rooms = { 
    "home" : ["yard", "city"],
    "yard" : ["home",],
    "city" : ["home",],
}

label home:
    "It's boring at home..."
    return

label yard:
    "Wow, back yard!"
    return

label city:
    "No way!"
    return

label start:
    "You are here: [room]"
    call expression room
    $ items = [(i, i) for i in rooms[room]]
    $ room = renpy.display_menu(items)
    jump start

label splashscreen:
    # "Lint..."
    $ missing = check_labels()
    if missing:
        "missing labels: [missing]"
    return

init python:
    def check_labels():
        z = [l for w in rooms for l in rooms[w]]
        z.extend([w for w in rooms])
        return [w for w in set(z) if not renpy.has_label(w)]
Naturally, the biggest problem is how to lint it.
If "home" is misspelled as "h0me" - there is no way to catch it easily during compile time, I have to add check_labels() function to do it...

I.e. what I really want it to use label names/objects (not strings!) to populate graph:

Code: Select all

default _room = home
default _rooms = { 
    home : [yard, city],
    yard : [home,],
    city : [home,],
}
But it'll throws on me:

Code: Select all

    default _room = home
NameError: name 'home' is not defined
Anyway to fix it?
Sorry, I'm complete Ren'Py newbie... :oops:

Re: Insert variables into code instead of into strings?

Posted: Sat Jan 07, 2017 8:01 pm
by Alex
Try it like

Code: Select all

default _rooms = { 
    home : [yard, city],
    yard : [home,],
    city : [home,],
}
default _room = _rooms["home"]

Re: Insert variables into code instead of into strings?

Posted: Sat Jan 07, 2017 8:29 pm
by Apa
Same error:

Code: Select all

    home : [yard, city],
NameError: name 'yard' is not defined
Looks like home in

Code: Select all

    home : [yard, city],
and

Code: Select all

label home:
are different objects. :oops:
BTW: The code I posted is really small - just load and try it out?
BTW2: I can use stringed version of graph and do lint work myself by iterating graph and checking each label existence via renpy.has_label(name), but that’s not the point I’m trying to make.

Re: Insert variables into code instead of into strings?

Posted: Sat Jan 07, 2017 8:37 pm
by Alex
Oops, keys and values should be in quotes otherwise they treated as variables (it also shown in the first link you've referenced to).

Re: Insert variables into code instead of into strings?

Posted: Sat Jan 07, 2017 8:46 pm
by Apa
Alex wrote:Oops, keys and values should be in quotes otherwise they treated as variables (it also shown in the first link you've referenced to).
Yep, that’s exactly what I want to do - populate graph with variables (which represent my script labels), not strings.
Are saying, it’s not possible and the DIY lint is the only way to go...? :?

Re: Insert variables into code instead of into strings?

Posted: Sat Jan 07, 2017 9:22 pm
by Alex
Mmm, if you need to jump to this labels you could try

Code: Select all

jump expression _room[0]
or

Code: Select all

$ renpy.jump(_room[0])
https://www.renpy.org/doc/html/label.ht ... -statement
https://www.renpy.org/doc/html/statemen ... renpy.jump

Re: Insert variables into code instead of into strings?

Posted: Sat Jan 07, 2017 9:53 pm
by Apa
Alex wrote:Mmm, if you need to jump to this labels you could try...
I have no problem with it - I did just that in the code I posted.
They only problem is how to catch errors (with lint, not at runtime!) like these:

Code: Select all

default rooms = { 
    "h0me" : ["yard", "city"],
    "yard" : ["Home",],
    "city" : ["hone",],
}

label home:
   ...
BTW: Speaking of DIY lint:
Anyway to define a custom lint code, to run by lint only AND not included released application?
Something like reserve lint.rpy file name for this purpose?
Sorry, I’m really "get 'em all during compile|lint time" type...

Re: Insert variables into code instead of into strings?

Posted: Sat Jan 07, 2017 10:03 pm
by Alex
I'm unable to help with this. Hope someone else will.