[Solved]Only one of two variables is updated in UDD

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
tornsoul
Regular
Posts: 29
Joined: Sat Jun 19, 2021 7:32 pm
Contact:

[Solved]Only one of two variables is updated in UDD

#1 Post by tornsoul » Sun Jul 04, 2021 12:27 pm

Small UDD test code below.
This question is not about the UDD functionality, but simply why on earth only one of my two variables (bucket, xy_pos) are getting updated in the event function.

Run the code - move/click the mouse - Then use the inspector to inspect the variables

bucket has tons of data in it.
But xy_pos remains unchanged (at 0.0) - Which, to me, is baffling.

Both are declared and used in the same places.
Only difference is that one is a list, and the other a tuple.

I'm new to both Renpy and Python - So I'm guessing (hoping) it's simply some quirk in either I'm unaware of.

Any suggestions as to what is going on?

Code: Select all

init python:
    bucket = []
    xy_pos = (0,0)

    class Udd_tester(renpy.Displayable):
        def __init__(self, **kwargs):
            super(Udd_tester, self).__init__(**kwargs)

            self.tile_size = 5
            self.board = [[0,0],[0,0]]
            self.tiles = [
                Solid("FFF", xysize=(self.tile_size, self.tile_size)),
                Solid("F00", xysize=(self.tile_size, self.tile_size))
            ]

            self.width = len(self.board) * self.tile_size
            self.height = self.width

        def render(self, width, height, st, at):
            render = renpy.Render(self.width, self.height)

            for y, row in enumerate(self.board):
                for x, val in enumerate(row):
                    render.place(self.tiles[self.board[y][x]] , x * self.tile_size, y * self.tile_size)

            return render

        def event(self, ev, x, y, st):
            global xy_pos
            bucket.append((x,y))
            xy_pos = (x,y)
            if renpy.map_event(ev, 'mousedown_1'):
                self.board[0][0] = 1

                renpy.redraw(self, 0)

        # def visit(self):
        #     return  [self.child]

screen udd_screen():
    add Udd_tester():
        xalign 0.5
        yalign 0.5


label udd_test:
    call screen udd_screen
    "Testing"
    return
Last edited by tornsoul on Mon Jul 05, 2021 12:32 pm, edited 2 times in total.

strayerror
Regular
Posts: 154
Joined: Fri Jan 04, 2019 3:44 pm
Contact:

Re: Only one of two variables is updated in UDD

#2 Post by strayerror » Sun Jul 04, 2021 7:59 pm

When you append to bucket you modify the originally empty list that you declared at the top of your init python block.
However, when you assign a new tuple to xy_pos you're actually creating a new xy_pos variable inside the scope of the function. This is known as variable shadowing, where a variable within a scope occludes one in a broader scope.
In order to have the original xy_pos updated you need to first pull it into the function scope via the global keyword like so:

Code: Select all

        def event(self, ev, x, y, st):
            global xy_pos
            bucket.append((x,y))
            xy_pos = (x,y)
This isn't specific to Ren'Py but rather to Python. I'd suggest doing a bit of Googling and reading up on variable scopes in Python to better understand what's happening and how it will affect your project in other ways.

Hope this helps! :)

tornsoul
Regular
Posts: 29
Joined: Sat Jun 19, 2021 7:32 pm
Contact:

Re: Only one of two variables is updated in UDD

#3 Post by tornsoul » Mon Jul 05, 2021 4:02 am

ups - I swear there was a global xy_pos in there at one time :-)

But even with that, xy_pos stays unchanged at (0, 0) - Which is what is so baffling.

FYI: I understand shadowing etc (I'm an experienced programmer, just not with python/renpy)

(I've edited the first code - I apologize if it leaves your comment looking a bit weird)

philat
Eileen-Class Veteran
Posts: 1853
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: Only one of two variables is updated in UDD

#4 Post by philat » Mon Jul 05, 2021 9:10 am

If you're using watch xy_pos, then it's just not getting updated. I don't know what you're trying to DO with that xy_pos so I can't offer real advice, but you'll see it being updated in watch if you throw a renpy.restart_interaction() in there. If you're using the watcher in the developer tools, that one probably works wonky with called screens - using the developer tools or console usually rolls you back to the start of the interaction.

tornsoul
Regular
Posts: 29
Joined: Sat Jun 19, 2021 7:32 pm
Contact:

Re: Only one of two variables is updated in UDD

#5 Post by tornsoul » Mon Jul 05, 2021 10:24 am

philat wrote:
Mon Jul 05, 2021 9:10 am
using the developer tools or console usually rolls you back to the start of the interaction.
yeah - I've observed that happening sometimes (sometimes it happens, sometimes not)

That could be why it shows as (0.0) in CTR+O console I suppose - while actually getting updated as expected while the program is running?


(and I'm not doing anything with xy_pos just yet - this is just a "prototype" toy example to explore what I can and can not do - To figure out if a CDD is the correct tool for my final goal)

tornsoul
Regular
Posts: 29
Joined: Sat Jun 19, 2021 7:32 pm
Contact:

Re: Only one of two variables is updated in UDD

#6 Post by tornsoul » Mon Jul 05, 2021 10:41 am

hmm..

Add an initial item to the bucket to make the following not fail (bucket = [0])

Code: Select all

screen udd_screen():
    hbox:
        vbox:
            text str(xy_pos)
            text str(bucket[-1])

        add Udd_tester():
            xalign 0.1
            yalign 0.1
Neither text string is getting updated...

I got other toy "prototypes" (not using CDD - but passing in an object to the screen) where the screen does update the text output dynamically (as the value of the objects attribute changes)
(EDIT: and setattribute and similar all call the renpy.restart_interaction() which is why those work - as I've come to find out)

Guess this doesn't work with globals (as in this case) ??

Really confused here...
Last edited by tornsoul on Mon Jul 05, 2021 11:47 am, edited 1 time in total.

tornsoul
Regular
Posts: 29
Joined: Sat Jun 19, 2021 7:32 pm
Contact:

Re: Only one of two variables is updated in UDD

#7 Post by tornsoul » Mon Jul 05, 2021 11:20 am

Lots more experimenting..

Weird results.

Looks more and more like a class Udd_tester(renpy.Displayable) (CDD) gets put in it's own (another) scope entirely while executing???
But that doesn't sound right either...

What I would ultimately like to achieve is to pass a "game object" object to the CDD, and setting/updating values in that game object, from the CDD's event function - mouse moves, is clicked etc => game object state changes.

Thus being able to mutate the game object and have the consequences of that show in the screen (which will be passed the same object)

(Did run into a few issues, where I had to quit the renpy launcher entirely to get it to react to changes made to code - ie. CTRL+R was not enough. Just to confuse me further...)

tornsoul
Regular
Posts: 29
Joined: Sat Jun 19, 2021 7:32 pm
Contact:

Re: Only one of two variables is updated in UDD

#8 Post by tornsoul » Mon Jul 05, 2021 11:28 am

I guess I wasn't paying attention to the right things.

I put in a renpy.restart_interaction() right after where I update the mouse position - and I now see the text updating....

Post Reply

Who is online

Users browsing this forum: Bing [Bot]