Ren'Py Dynamically determining variables

Alfius

Engaged Member
Modder
Sep 30, 2017
2,348
4,917
Hi,

I'm trying to assist one of the developers on here, but I'm a complete noob when it comes to Renpy/Python.


What I'm trying to do is simply the following:-

There is an object from a class
init python:
class Person:
def __init__ (self, fname, lname, age):
self.fname = fname
self.lname = lname
self.age = age


So I create a "Person" object
default TClaire = Person("Claire","White",27)

Now I want to access TClaire and I'm able to access it via "text" like so:
(CharName = "TClaire")

hbox:
text "[" + CharName+ ".Name]":
size 10

And it Correctly outputs "Claire"


However, IF I assign it to a string. I get the following:
$ Playername ="[" + CharName+ ".Name]";

it outputs "[TClaire.Name} "
This is obviously not what I want.

IS it possible to do this in Renpy, It seems obvious, but I could not find any way that this will work.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
However, IF I assign it to a string. I get the following:
$ Playername ="[" + CharName+ ".Name]";

it outputs "[TClaire.Name} "
This is obviously not what I want.

IS it possible to do this in Renpy, It seems obvious, but I could not find any way that this will work.
Text interpolation isn't recursive. Therefore, this :
Code:
label whatever:
    $ variable = "[" + whatever + "]"
    "[variable]"
Will always interpolate the content of variable and display it as a literal strinng ; even if this said string have bracket in it.


Python is designed to works as dynamically as possible, you don't need to rely on Ren'py for this, just do it natively :
Code:
label whatever:
    $ charName = "TClaire"
    $ playerName = getattr( store, CharName ).Name
    "[playerName]"
Or even :
Code:
label whatever:
    $ playerName = getattr( store, "TClaire").Name
    "[playerName]"
 

Alfius

Engaged Member
Modder
Sep 30, 2017
2,348
4,917
Text interpolation isn't recursive. Therefore, this :
Code:
label whatever:
    $ variable = "[" + whatever + "]"
    "[variable]"
Will always interpolate the content of variable and display it as a literal strinng ; even if this said string have bracket in it.


Python is designed to works as dynamically as possible, you don't need to rely on Ren'py for this, just do it natively :
Code:
label whatever:
    $ charName = "TClaire"
    $ playerName = getattr( store, CharName ).Name
    "[playerName]"
Or even :
Code:
label whatever:
    $ playerName = getattr( store, "TClaire").Name
    "[playerName]"

How can I like this 1000 times :D

Awesome man, it works like a charm :)
 

Alfius

Engaged Member
Modder
Sep 30, 2017
2,348
4,917
Text interpolation isn't recursive. Therefore, this :
Code:
label whatever:
    $ variable = "[" + whatever + "]"
    "[variable]"
Will always interpolate the content of variable and display it as a literal strinng ; even if this said string have bracket in it.


Python is designed to works as dynamically as possible, you don't need to rely on Ren'py for this, just do it natively :
Code:
label whatever:
    $ charName = "TClaire"
    $ playerName = getattr( store, CharName ).Name
    "[playerName]"
Or even :
Code:
label whatever:
    $ playerName = getattr( store, "TClaire").Name
    "[playerName]"
First of...Thanks again for the help, this worked Perfectly.

I now want to do the inverse of this....Setting a Attribute of an object using the object name

So what I have tried is the following
Code:
$ playerName = getattr( store, "TClaire").Name
setattr(store,"lname ","Black")
This does not seem to work. (I know it was a long shot... :) )
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
Code:
setattr(store,"lname ","Black")
There's an unwanted space after "lname". Is it a typo when copying the code here, or is the typo also on the original code ?

This said, using setattr to add an attribute is a little more complicated. With what you wrote (minus the typo), you are assigning the value "Black" to the variable "lname".
But, according to what you said, I guess that you want to add the attribute "Black" to the "lname" object, which should be wrote like this :
Code:
setattr( store.lname, "Black", None )
I used None as value because it mean "the attribute exist, but have no value", but obviously you can use whatever value you want.

And if you want to do this in a more automated process, it's not really more complicated :
Code:
for objName in ["TClaire", "lname", "anotherObject" ]:
    setattr( getattr( store, objName ), "Black", None )
It will add the "Black" attribute to the objects named, "TClaire", "lname" and "anotherObject".
 

Alfius

Engaged Member
Modder
Sep 30, 2017
2,348
4,917
There's an unwanted space after "lname". Is it a typo when copying the code here, or is the typo also on the original code ?
It's a typo. I do not copy and paste code from the project, as it's not my game. I do not feel comfortable sharing any code from his project.
This is example is hypothetical, but it is directly related to the code I use in-game. (ie. I just change object names and attributes etc. so code is essentially the same, but typos can occur)

This said, using setattr to add an attribute is a little more complicated. With what you wrote (minus the typo), you are assigning the value "Black" to the variable "lname".
But, according to what you said, I guess that you want to add the attribute "Black" to the "lname" object, which should be wrote like this :
Code:
setattr( store.lname, "Black", None )
I used None as value because it mean "the attribute exist, but have no value", but obviously you can use whatever value you want.
I feel I have not explained clearly what I want to do.

So there is an Object TClaire of type Person with attributes fname, lname and age. (There are numerous other Person objects as well. TClaire is just one of the NPCs)
define TClaire = Person("Claire","White",27)

So I want to change TClaire.lname from "White" to "Black".

The problem is, at the time where I want to change the attribute, I do not have a handle on the actual object.
I only have the text value of the object "TClaire". I do not have The actual object TClaire.

So my request is to change TClaire.lname from "White" to "Black", BUT with me only having the text of the Objectname "TClaire" not the actual object TClaire.

I hope I'm making better sense this time around :)


And if you want to do this in a more automated process, it's not really more complicated :
Code:
for objName in ["TClaire", "lname", "anotherObject" ]:
    setattr( getattr( store, objName ), "Black", None )
It will add the "Black" attribute to the objects named, "TClaire", "lname" and "anotherObject".
These sugestions might be able to help. Will see if I got them to work.

Thanks for the help so far.
 
Last edited:

Alfius

Engaged Member
Modder
Sep 30, 2017
2,348
4,917
Just so that there is no confusion... I do not want to add an attribute. I want to change an existing attribute.
Apologies for not being clear on that.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
So my request is to change TClaire.lname from "White" to "Black", BUT with me only having the text of the Objectname "TClaire" not the actual object TClaire.
Which is what I answered to. Here, "adding an attribute to an object", and "changing the value of an attribute" are exactly the same thing.

You don't have permission to view the spoiler content. Log in or register now.


It didn't works because what you wrote isn't what you want to do :
Code:
setattr(store,"lname","Black")
setattr works like this : setattr( object, attribute_as_string, value )
So, here you asked to assign the value "Black" to an attribute named "lname" and which is part of the "store" object.

What you want is setattr( store.TClaire, "lname", "Black" ).

But, like you don't have the object, just it's name, what you need is the setattr( getattr( store, "TClaire" ), "lname", "Black" ) I implied at the end of my answer.

Note that the use of setattr isn't mandatory here. The same thing can be achieved with getattr( store, "TClaire" ).lname = "Black".
 

Alfius

Engaged Member
Modder
Sep 30, 2017
2,348
4,917
Which is what I answered to. Here, "adding an attribute to an object", and "changing the value of an attribute" are exactly the same thing.

You don't have permission to view the spoiler content. Log in or register now.


It didn't works because what you wrote isn't what you want to do :


setattr works like this : setattr( object, attribute_as_string, value )
So, here you asked to assign the value "Black" to an attribute named "lname" and which is part of the "store" object.

What you want is setattr( store.TClaire, "lname", "Black" ).

But, like you don't have the object, just it's name, what you need is the setattr( getattr( store, "TClaire" ), "lname", "Black" ) I implied at the end of my answer.

Note that the use of setattr isn't mandatory here. The same thing can be achieved with getattr( store, "TClaire" ).lname = "Black".
Thanks man your explanations is very helpful. Will try it now and let you know:)

Just a quick question. where does "store" comes form? I assume it's a Renpy/Python feature?
(Apologies if this is a very basic question. I'm very new at Python/Renpy)