Variables and Menus

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
Shake0615
Regular
Posts: 30
Joined: Thu May 07, 2009 9:42 am
Location: United Statesia
Contact:

Variables and Menus

#1 Post by Shake0615 »

I have a question about the "best" way to code something and programming logic in general. I did a test run and got this error:

Code: Select all

I'm sorry, but an exception occured while executing your Ren'Py
script.

NameError: name 'menu_item1_unlocked' is not defined

While running game code:
 - script at line 1584 of /Applications/Tests/game/script.rpy
 - python at line 1584 of /Applications/Tests/game/script.rpy.

Code: Select all

if result == "button":
        if menu_item1_unlocked:
            "This is the second run-through."
            "You already have item1."
            jump beginning
        else:
            c "This is the first run through."
            c "You get Item 1"
            $ menu_item1_unlocked=True
            jump beginning
So I think the problem is that when it first runs the code, it notices that the variable "menu_item1_unlocked" isn't defined because in order to actually define it, the if statement has to return false and go to the else statement (correct?). My question is if this doesn't work, what is the best way to get the following out of a code:

1. Player investigates a certain area (a button).
2. Player receives an item.

3. If player clicks on that button again, a different result (e.g. "You already got item1 you greedy S.O.B.").

Would it be a good idea to start off the label:start block by setting all variables to false so that when they come up in code, they are defined? Or is there a better way?

Thanks!

delta
Epitome of Generic
Posts: 525
Joined: Sat Dec 22, 2007 12:59 pm
Projects: yes
Contact:

Re: Variables and Menus

#2 Post by delta »

If you're doing an unlockable your whole question is beside the point, because that has to be a field on the persistent object and you can always test for those without things breaking.

In general though, either initialize them to some value in the init block or test for existence with hasattr(store, "variable").
The rest is left as an exercise for the reader.

Shake0615
Regular
Posts: 30
Joined: Thu May 07, 2009 9:42 am
Location: United Statesia
Contact:

Re: Variables and Menus

#3 Post by Shake0615 »

Ok. Having an unlockable is part of the script though it wasn't in my original question. Essentially what I want to happen in this script is that the player clicks a button, it adds an item to the inventory (which can be viewed via image map-based menu, this is where the unlockable part comes in), and if the player decides to click the button again, it returns a different outcome because they have already gotten the item.

I used JQuartz's code for unlockable image map buttons, but the problem is that every time the game starts up, the variable is set to false again even if the save file should have it as true (I assume this is because the variable is in the init block).

Could you elaborate on the persistent object part or direct me to a resource? Thanks

Shake0615
Regular
Posts: 30
Joined: Thu May 07, 2009 9:42 am
Location: United Statesia
Contact:

Re: Variables and Menus

#4 Post by Shake0615 »

I tried changing the variable to $ persistent.what_ever but that tampers with any other game save files. I only want the unlocked part to be visible within that certain game file, not the others. What else can get this to work?

delta
Epitome of Generic
Posts: 525
Joined: Sat Dec 22, 2007 12:59 pm
Projects: yes
Contact:

Re: Variables and Menus

#5 Post by delta »

Don't use the persistent object and set the default value of the variable directly after the start label. There are fancier ways to do it but you are struggling as it is.
The rest is left as an exercise for the reader.

JQuartz
Eileen-Class Veteran
Posts: 1265
Joined: Fri Aug 31, 2007 7:02 am
Projects: 0 completed game. Still haven't made any meaningfully completed games...
Contact:

Re: Variables and Menus

#6 Post by JQuartz »

Shake0615 wrote:I did a test run and got this error:
You need to set menu_item1_unlocked=False in the init like so:

Code: Select all

init:
    $ menu_item1_unlocked=False
label start:
    "Game starts"
    
label end:
    "Game ends"
    "Credit rolls"
    "Presses the button"
    $ result="button"
    if result == "button":
        if menu_item1_unlocked:
            "This is the second run-through."
            "You already have item1."
            jump beginning
        else:
            c "This is the first run through."
            c "You get Item 1"
            $ menu_item1_unlocked=True
            jump beginning
            
label beginning:
    jump start
I suspect somebody is stealing my internet identity so don't believe everything I tell you via messages. I don't post or send messages anymore so don't believe anything I tell you via messages or posts.

User avatar
Showsni
Miko-Class Veteran
Posts: 563
Joined: Tue Jul 24, 2007 12:58 pm
Contact:

Re: Variables and Menus

#7 Post by Showsni »

Don't do it in the init block or it will be reset every time you start the game. Just define all your variables immediately after the start label. And you don't need to worry about persistent anything in this case.

You don't have to define it immediately after the start label; just make sure it's been defined before the game asks what it is.

JQuartz
Eileen-Class Veteran
Posts: 1265
Joined: Fri Aug 31, 2007 7:02 am
Projects: 0 completed game. Still haven't made any meaningfully completed games...
Contact:

Re: Variables and Menus

#8 Post by JQuartz »

Showsni wrote:Don't do it in the init block or it will be reset every time you start the game. Just define all your variables immediately after the start label.
Oops, sorry I forgot. I guess you should try this instead:

Code: Select all

label start:
    if not persistent.menu_item1_unlocked:
        $ persistent.menu_item1_unlocked=False
    "Game starts"
    
    
label end:
    "Game ends"
    "Credit rolls"
    "Presses the button"
    $ result="button"
    if result == "button":
        if persistent.menu_item1_unlocked:
            "This is the second run-through."
            "You already have item1."
            jump beginning
        else:
            c "This is the first run through."
            c "You get Item 1"
            $ persistent.menu_item1_unlocked=True
            jump beginning
           
label beginning:
    jump start
I suspect somebody is stealing my internet identity so don't believe everything I tell you via messages. I don't post or send messages anymore so don't believe anything I tell you via messages or posts.

chronoluminaire
Eileen-Class Veteran
Posts: 1153
Joined: Mon Jul 07, 2003 4:57 pm
Completed: Elven Relations, Cloud Fairy, When I Rule The World
Tumblr: alextfish
Skype: alextfish
Location: Cambridge, UK
Contact:

Re: Variables and Menus

#9 Post by chronoluminaire »

JQuartz's last answer is a little confused. To Shake0615, you need to decide: do you want the "unlock" to last 1) for the current game only, 2) for all games on this computer, or 3) something in between?

1) If you're making something that should behave the same way each time the player starts a new game, don't use persistent. Just initialise the variable at the start of the game, like this:

Code: Select all

label start:
# The start of the game. Initialise all in-game variables here.
$ menu_item1_unlocked=False

Code: Select all

  # later in the game
  if menu_item1_unlocked:
    "You already have item1."
    jump somewhere
  else:
    c "This is the first run through."
    c "You get Item 1"
    $ menu_item1_unlocked=True
    jump somewhere
2) If you're using persistent, there are special rules. You're allowed to refer to any old attribute of the persistent object without it throwing an error. But changes to persistent are preserved across all plays of the game on that computer: that's what they're for.

In particular, if you are using persistent, there's no need to do this kind of thing:

Code: Select all

label start:
    if not persistent.menu_item1_unlocked:
        $ persistent.menu_item1_unlocked=False
Because the persistent object is special and knows that attributes of it may not be defined, and allows you to query them anyway. (If that wasn't the case, this code would error on the first line, because you can't use "if not" to test if a property exists at all. One way to do that is what delta mentioned - using hasattr - but you shouldn't need to do that.)

3) If you want something inbetween... that is possible, but it's rather harder. You need to do something like hack the persistent object in the splash_screen code.
I released 3 VNs, many moons ago: Elven Relations (IntRenAiMo 2007), When I Rule The World (NaNoRenO 2005), and Cloud Fairy (the Cute Light & Fluffy Project, 2009).
More recently I designed the board game Steam Works (published in 2015), available from a local gaming store near you!

Shake0615
Regular
Posts: 30
Joined: Thu May 07, 2009 9:42 am
Location: United Statesia
Contact:

Re: Variables and Menus

#10 Post by Shake0615 »

Thanks everyone for the help!

I set all the relative variables to false right after the start label and then I just turn them on as I need them. I figured it would work that way but I didn't know if there was a better way to do it.

Post Reply

Who is online

Users browsing this forum: No registered users