Ren'Py Display Variables From Class

Jun 15, 2022
11
18
Alright so, I'm trying to figure out how to do this exactly. I see there are some threads already about this kind of but I'm doing it a different way so I'm hoping someone can help.

So I'm storing a few variables within a class

Code:
class Actor:
        def __init__(self, character, name, trust, health, thirst, affection, threat):
            self.c = character
            self.name = name
            self.trust = trust
            self.health = health
            self.thirst = thirst
            self.affection = affection
            self.threat = threat
Now I've created another script and menu thingy to display variables however, I get an error doing it this way. The error that I get says "NameError: name 'self' is not defined"

Code:
screen StatsUI:
    frame:
        xalign 0.5
        yalign 0.5
        xpadding 30
        ypadding 30

        hbox:
            spacing 40

            vbox:
                spacing 10
                text "Thirst" size 40

            vbox:
                spacing 10
                text str(self.thirst) size 40
Now the only thing I found on here is when people do the typical method like

Code:
define health = 100

vbox:
    text "[health]"
however that doesn't work in my case, so if anyone can help me that would be amazing.
 

noping123

Well-Known Member
Game Developer
Jun 24, 2021
1,433
2,272
There's a couple of issues, but here is your biggest one:

ANY time you want to call something from that class outside of the python init, you wouldn't use self.thirst (or self.anything).

You call it via Actor.thirst
 
Jun 15, 2022
11
18
There's a couple of issues, but here is your biggest one:

ANY time you want to call something from that class outside of the python init, you wouldn't use self.thirst (or self.anything).

You call it via Actor.thirst
Thanks for the quick reply.
I change it from self. to Actor. however now I get the following error

AttributeError: type object 'Actor' has no attribute 'thirst"

is there anything else I'm missing?
 

MidnightArrow

Member
Aug 22, 2021
496
416
You're not supposed to use "Actor". They're saying to use the name you gave your object. That needs to be passed into your screen as an argument.

If your object is named "the_blind_dev" you do this

Code:
call screen StatsUI(the_blind_dev)
and write your screen like this

Code:
screen StatsUI(the_blind_dev_character):
    frame:
        xalign 0.5
        yalign 0.5
        xpadding 30
        ypadding 30

        hbox:
            spacing 40

            vbox:
                spacing 10
                text "Thirst" size 40

            vbox:
                spacing 10
                text str(the_blind_dev_character.thirst) size 40
 
Last edited:

noping123

Well-Known Member
Game Developer
Jun 24, 2021
1,433
2,272
Thanks for the quick reply.
I change it from self. to Actor. however now I get the following error

AttributeError: type object 'Actor' has no attribute 'thirst"

is there anything else I'm missing?

That means the value isn't assigned.

1 sec.


here's a really quick and dirty example script

Code:
init python:
    class Actor:
            def __init__(self, character, name, trust, health, thirst, affection, threat):
                self.c = character
                self.name = name
                self.trust = trust
                self.health = health
                self.thirst = thirst
                self.affection = affection
                self.threat = threat


label start:

$Actor.trust = 10

"Hi"

"Test [Actor.trust]"

"test"

return
That works, and displays "Hi" then "Test 10" then "test".

If you delete the line $Actor.trust = 10

then you get the AttributeError.

Basically it means you haven't actually assigned a value to it before calling it.
 

MidnightArrow

Member
Aug 22, 2021
496
416
Also it's bad coding to access fields outside a class. You call a method that returns the value to handle errors and invalid states.
 
Jun 15, 2022
11
18
Well maybe I'm assigning them wrong.

So this is how I currently have it setup basically to give you a better idea since I thought I already did assign a value to it.

Code:
init python:
    class Actor:
        def __init__(self, character, name, trust, health, thirst, affection, threat):
            self.c = character
            self.name = name
            self.trust = trust
            self.health = health
            self.thirst = thirst
            self.affection = affection
            self.threat = threat
            
define ke = Actor(Character("Kelly", color="#7cf313"), "Kelly", 0, 100, 0, 0, 0)
so the end numbers meaning the following default values for each attribute.

Code:
Actor Kelly default attribute vales would be

0 trust
100 health
0 thirst
0 affection
0 threat
 

MidnightArrow

Member
Aug 22, 2021
496
416
The assignment is wrong but not the way you mean. Iirc define is for constants, values that never change. Ren'py doesn't save those.

You want default instead.

A character can be declared with define because it never changes but you're tacking on all kinds of extra data that is mutable and needs to be saved.

Read my sample code again. Your screen needs a parameter and you need to use the parameter to access the variable you pass in while running the game.
 

cisco_donovan

Member
Game Developer
Sep 18, 2020
218
283
Hi, look, I say this with respect and even love: but you need to go and read up on python classes. There are many tutorials online, spend some time finding one that works for you. This is absolutely fundamental stuff and if you don't take the time to understand it, you'll be spinning your wheels on problems like this forever.

A couple of pointers.

A class is a blueprint, a definition, for a data structure. When you declare your class Actor, you are defining what an actor looks like, as in, what properties (variables) does the actor have. But no actor exists yet: there is no object or instance to represent the actor, and there are no properties to read from or write to.

The self object isn't visible to things outside the class definition. The self object represents one instance of the class from the class's point of view.

After defining a class, you need to create an instance of it and assign it to a variable:

Code:
john = Actor(character, name, trust, health, thirst, affection, threat)
This is just the same as when you create a renpy Character. Pass in whatever arguments you need.

Now you can read and write the properties of that actor as you like:

Code:
john.name # read the name property of john
john.name ='jane' # change the name property of john
I hope this helps a bit but please invest some time in learning the basics of the language. Honestly it will repay itself 1000x over.
 
  • Like
Reactions: hector333

noping123

Well-Known Member
Game Developer
Jun 24, 2021
1,433
2,272
Also it's bad coding to access fields outside a class. You call a method that returns the value to handle errors and invalid states.

Technically correct, but I'm doing like 7 things at once and couldnt focus enough to give a proper answer so i settled for "Technically correct".

Luckily 2 more people stepped in and gave better ones!
 
Jun 15, 2022
11
18
Again thank you everyone for your help.
With the information provided I figured out what exactly I was doing wrong and what I needed to change to do what I wanted to do so again thank you all very much.
 
  • Like
Reactions: cisco_donovan

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,135
14,818
Also it's bad coding to access fields outside a class. You call a method that returns the value to handle errors and invalid states.
While I agree, this don't apply to Python.

The language is partly built around the paradigm, making it one of their motto. This lead pythoners to not care about this kind of issues and goes to the essential. Python relying mostly on exceptions, and having a wide granularity range for them, it works relatively fine ; to really few exception (mostly boundaries), Python do natively what you would do in your validation code.
But, as I said, I agree with you, to one exception. You shouldn't validate the value you return, but the value you get. What mean that accessing fields outside of a class is not a problem, as long as you're looking at its value, not providing a new one.
 

MidnightArrow

Member
Aug 22, 2021
496
416
While I agree, this don't apply to Python.

The language is partly built around the paradigm, making it one of their motto. This lead pythoners to not care about this kind of issues and goes to the essential. Python relying mostly on exceptions, and having a wide granularity range for them, it works relatively fine ; to really few exception (mostly boundaries), Python do natively what you would do in your validation code.
But, as I said, I agree with you, to one exception. You shouldn't validate the value you return, but the value you get. What mean that accessing fields outside of a class is not a problem, as long as you're looking at its value, not providing a new one.
So Python is an OOP language but they ignore encapsulation and interfaces? Why am I not that surprised?
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,135
14,818
So Python is an OOP language but they ignore encapsulation and interfaces?
It's not that Python ignore them, more that it don't promote them when they are not required. Python is centered around duck typing and (paradoxically, due to its immutable nature) dynamism, following a way at the exact opposite of the strictness that can be found in traditional OOL. Each approach having its advantages and use.