NameError: Variable does not exist in screen

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
User avatar
Mole-chan
Veteran
Posts: 328
Joined: Thu Aug 27, 2009 12:46 am
Completed: DUAEL, Escape from Puzzlegate
Projects: A Bird with Gold-Mended Wings
Deviantart: mole-chan
Skype: mole-chan
itch: moleworks
Contact:

NameError: Variable does not exist in screen

#1 Post by Mole-chan » Mon Sep 12, 2022 3:12 pm

Hello,
I'm trying to get a screen to create a series of buttons from a dictionary that holds, among other things, the button's text and a variable and value to set. The variable has already been established in screen space before the buttons are created, however, they consistently complain that the variable does not exist. At first I thought it was because it was a new screen being called from the first, so it may be a scope issue. However, it does this even when being created in the same screen.

The relevant code is below:

Code: Select all

screen skinsh_dialogue(who, convo_dict, question_dict, default_dial, two_window):
    $dial = list(convo_dict.values())   
    $dial_last = dial[-1] 
    $dial_range = dial[:-1]
    $dial_random = (random.choice(dial_range))
    $dial_disp = ""
    
    if show_dialogue:
        

        timer 5.0 action SetVariable ("dial_random",(random.choice(dial_range))) repeat True #TODO: Stop cycling when finished? Perhaps use the last key in dict as final dialogue and settle on that.
        
        if arProg < .9:
            if random_dialogue:
                $dial_disp = dial_random
            else:
                $dial_disp = default_dial
        else:
            $dial_disp =  dial_last
            
            # Decide if we want to use the one-window or two-window variant.
        if not two_window:
    
            # The one window variant.
            window:
                id "window"
    
                has vbox:
                    style "say_vbox"
    
                if who:
                    text who
                text _(dial_disp)
    
        else:
    
            # The two window variant.
            vbox:
                style "say_two_window_vbox"
    
                if who:
                    window:
                        style "say_who_window"
    
                        text who
    
                window:
                    id "window"
    
                    has vbox:
                        style "say_vbox"
    
                    text _(dial_disp)
                    
                    
        for d in question_dict.values(): #iterate through question dictionary
            if d['question'] == dial_disp: #if the currently displayed dialogue matches the question in the nested dict....
                $show_buttons = True
                $button_dict = d
                
        if show_buttons:
            #on "show" action Show("skinsh_question",button_dict=d)  #show the question screen
            hbox yalign .5 xalign .5:
                for k in set(button_dict) - {"question"}: #convert dict to set to iterate through all but the question entry
                    $bttn_label = button_dict[k]['dialogue'] #make label from dialogue key of entry, the answer itself
                    $v = button_dict[k]['var'][0] #get variable name from var entry. This points to a string "dial_disp", which in turn should point to established var.
                    $x = button_dict[k]['var'][1] #get variable value from var entry
                    textbutton "[bttn_label]" action [SetVariable(v,x), SetVariable("show_buttons",False)] #Add button for each value that sets assigned variable on click. For now it's a null action but it should actually do something.
           
        # Use the quick menu.
        use quick_menu
And the dictionary:

Code: Select all

        skinsh_questions = {
            'what_doing': 
                {'question': "What are we gonna do on the bed? :3c", 
                'answer1': {'dialogue':"Oh, you know", 'var': ['dial_disp', "My, my... aren't you bold?"]},
                'answer2': {'dialogue':"Nothing...", 'var': ['dial_disp', 'Are you sure?']},
                'answer3': {'dialogue':"Sleeping, of course. uvu", 'var': ['dial_disp', 'Why of course.']},
                }
            }
The traceback is also decidedly unhelpful, though I'll include it anyway just to be sure. Here it is below:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 22, in script
    call screen skinsh_character(_layer="characterInteraction")
  File "renpy/common/000statements.rpy", line 609, in execute_call_screen
    store._return = renpy.call_screen(name, *args, **kwargs)
  File "renpy/common/00action_data.rpy", line 79, in get_selected
    return __get_field(self.object, self.field, self.kind) == self.value
  File "renpy/common/00action_data.rpy", line 39, in _m1_00action_data__get_field
    raise NameError("The {} {} does not exist.".format(kind, name))
NameError: The variable dial_disp does not exist.

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "game/script.rpy", line 22, in script
    call screen skinsh_character(_layer="characterInteraction")
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\ast.py", line 2232, in execute
    self.call("execute")
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\ast.py", line 2220, in call
    return renpy.statements.call(method, parsed, *args, **kwargs)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\statements.py", line 281, in call
    return method(parsed, *args, **kwargs)
  File "renpy/common/000statements.rpy", line 609, in execute_call_screen
    store._return = renpy.call_screen(name, *args, **kwargs)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\exports.py", line 3181, in call_screen
    rv = renpy.ui.interact(mouse="screen", type="screen", roll_forward=roll_forward)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\ui.py", line 299, in interact
    rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\core.py", line 3377, in interact
    repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, pause=pause, pause_start=pause_start, pause_modal=pause_modal, **kwargs) # type: ignore
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\core.py", line 3810, in interact_core
    root_widget.visit_all(lambda i : i.per_interact())
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\core.py", line 582, in visit_all
    d.visit_all(callback, seen)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\core.py", line 582, in visit_all
    d.visit_all(callback, seen)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\core.py", line 582, in visit_all
    d.visit_all(callback, seen)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\screen.py", line 456, in visit_all
    self.child.visit_all(callback, seen=None)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\core.py", line 582, in visit_all
    d.visit_all(callback, seen)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\core.py", line 582, in visit_all
    d.visit_all(callback, seen)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\core.py", line 584, in visit_all
    callback(self)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\core.py", line 3810, in <lambda>
    root_widget.visit_all(lambda i : i.per_interact())
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\behavior.py", line 968, in per_interact
    if self.is_selected():
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\behavior.py", line 956, in is_selected
    return is_selected(self.action)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\behavior.py", line 398, in is_selected
    return any(is_selected(i) for i in action)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\behavior.py", line 398, in <genexpr>
    return any(is_selected(i) for i in action)
  File "D:\Downloads\renpy-8.0.3-sdk\renpy\display\behavior.py", line 401, in is_selected
    return action.get_selected()
  File "renpy/common/00action_data.rpy", line 79, in get_selected
    return __get_field(self.object, self.field, self.kind) == self.value
  File "renpy/common/00action_data.rpy", line 39, in _m1_00action_data__get_field
    raise NameError("The {} {} does not exist.".format(kind, name))
NameError: The variable dial_disp does not exist.

Windows-10-10.0.19043 AMD64
Ren'Py 8.0.3.22090809
smol udd test 0.0
Mon Sep 12 14:08:12 2022


Any help would be appreciated, as I'm rather stumped.

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: NameError: Variable does not exist in screen

#2 Post by PyTom » Mon Sep 12, 2022 7:51 pm

You want to use SetScreenVariable, not SetVariable, to set variables used inside screens.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

Post Reply

Who is online

Users browsing this forum: No registered users