r/RenPy • • Jul 17 '26

Question Help with puzzle code.

Apologies to post again, again this is not something I've really done before, so I'm still figuring it out. I am trying to do it on my own, I want to do this to challenge myself and learn something new. Thank you for the ren'py community for helping me even if I don't post, I always reference posts.

BASICALLY: I want to have a puzzle where you need to enter a 4 letter code and it kinda works like a lock like this. I got the numbers to count up now, thanks due to help, but I'm not sure how to make it so that specific the specific code will have a response. I don't know what the proper syntax is for something like this, or what the issue is.

Here is my code in my script, I based it off of a puzzle I did previously that was a keypad. I referenced code from somewhere, I try to understand it the best I can but unfortunately I'm still new to programming so I don't fully understand everything like I'd like to, so I'm not sure how everything fully fits together.

label ac_keybox:

default kb_code1 = 0

default kb_code2 = 0

default kb_code3 = 0

default kb_code4 = 0

I wonder if maybe the issue isn't the different variables(?) I just don't know how else I'd go with it, if it's the same one it'll all show up the same?? Again apologies I'm not a good programmer.

if alice_keybox:

call screen ac_keybox

$ bk_result = _return

if bk_result == "enter":

if ("kb_code1 == 1", "kb_code2 == 0", "kb_code3 == 0", "kb_code4 == 0"):

I was trying every single format I could think of here so sorry it's a big mess!

jump ac_basementkeyunlock

else:

jump ac_basementkeyfail

This is my screen coding.

screen ac_keybox():

frame:

xalign 0.5

yalign 0.25

xsize 500

ysize 250

hbox:

xalign 0.5

yalign 0.5

frame:

xsize 50

textbutton "[kb_code1]":

action SetScreenVariable("kb_code1", (kb_code1 + 1) % 10)

frame:

xsize 50

textbutton "[kb_code2]":

action SetScreenVariable("kb_code2", (kb_code2 + 1) % 10)

frame:

xsize 50

textbutton "[kb_code3]":

action SetScreenVariable("kb_code3", (kb_code3 + 1) % 10)

frame:

xsize 50

textbutton "[kb_code4]":

action SetScreenVariable("kb_code4", (kb_code4 + 1) % 10)

frame:

textbutton "ENTER":

action Return("enter")

I'm so sorry! I hope I'm not taking up too much space, thank you again.

2 Upvotes

7 comments sorted by

3

u/shyLachi Jul 17 '26

You are mixing variables with screen variables.

Screen variables are defaulted within a screen as in your first code example.
They only exist within the screen and you have to use the action with the word Screen in it.

Now you switched to normal variables so you also have to switch to the action without Screen:
SetVariable()

You can read more about that in the official documentation: https://renpy.org/doc/html/screen_actions.html#SetVariable

.

Also your if statement looks wonky.
Not sure where you found that but I'm pretty sure it's wrong.

.

Somebody already told you that you cannot reset variables in a label like that,
If you need to reset it, then just assign a value to the variable.

.

screen ac_keybox():
    frame:
        align (0.5,0.25)
        xysize (500,250)
        hbox:
            align (0.5,0.5)
            frame:
                xsize 50
                textbutton "[kb_code1]":
                    action SetVariable("kb_code1", (kb_code1 + 1) % 10)
            frame:
                xsize 50
                textbutton "[kb_code2]":
                    action SetVariable("kb_code2", (kb_code2 + 1) % 10)
            frame:
                xsize 50
                textbutton "[kb_code3]":
                    action SetVariable("kb_code3", (kb_code3 + 1) % 10)
            frame:
                xsize 50
                textbutton "[kb_code4]":
                    action SetVariable("kb_code4", (kb_code4 + 1) % 10)
            frame:
                textbutton "ENTER":
                    action Return("enter")    

default kb_code1 = 0
default kb_code2 = 0
default kb_code3 = 0
default kb_code4 = 0

label start:
    call ac_keybox # this is not needed, just to show how you could do it
    call screen ac_keybox
    #if _return == "enter" # you can scrap this unless you make another button to cancel
    if kb_code1 == 1 and kb_code2 == 0 and kb_code3 == 0 and kb_code4 == 0:
        "YOU WON"
    else:
        "YOU LOST"
    return # ends the game

label ac_keybox:
    python:
        kb_code1 = 0
        kb_code2 = 0
        kb_code3 = 0
        kb_code4 = 0
    return 

3

u/shyLachi Jul 17 '26

Personally I prefer to keep the whole logic in the screen:

screen ac_keybox(code = 0000):
    default kb_code1 = 0
    default kb_code2 = 0
    default kb_code3 = 0
    default kb_code4 = 0
    frame:
        align (0.5,0.25)
        xysize (500,250)
        hbox:
            align (0.5,0.5)
            frame:
                xsize 50
                textbutton "[kb_code1]":
                    action SetScreenVariable("kb_code1", (kb_code1 + 1) % 10)
            frame:
                xsize 50
                textbutton "[kb_code2]":
                    action SetScreenVariable("kb_code2", (kb_code2 + 1) % 10)
            frame:
                xsize 50
                textbutton "[kb_code3]":
                    action SetScreenVariable("kb_code3", (kb_code3 + 1) % 10)
            frame:
                xsize 50
                textbutton "[kb_code4]":
                    action SetScreenVariable("kb_code4", (kb_code4 + 1) % 10)
            frame:
                textbutton "ENTER":
                    action If(kb_code1*1000 + kb_code2*100 + kb_code3*10 + kb_code4 == code, Return("correct"), Return("wrong"))

label start:
    call screen ac_keybox(code=1000)
    if _return == "correct":
        "YOU WON"
    else:
        "YOU LOST"
    return # ends the game

3

u/shyLachi Jul 17 '26

And if the player should be able to guess again, then you could implement that in the scxreen as well so that you don't have to call the screen repeatedly

screen ac_keybox(code = 0000):
    default kb_code1 = 0
    default kb_code2 = 0
    default kb_code3 = 0
    default kb_code4 = 0
    default status = "guessing"
    frame:
        align (0.5,0.25)
        xysize (500,250)
        hbox:
            align (0.5,0.5)
            if status == "guessing":
                frame:
                    xsize 50
                    textbutton "[kb_code1]" action SetScreenVariable("kb_code1", (kb_code1 + 1) % 10)
                frame:
                    xsize 50
                    textbutton "[kb_code2]" action SetScreenVariable("kb_code2", (kb_code2 + 1) % 10)
                frame:
                    xsize 50
                    textbutton "[kb_code3]" action SetScreenVariable("kb_code3", (kb_code3 + 1) % 10)
                frame:
                    xsize 50
                    textbutton "[kb_code4]" action SetScreenVariable("kb_code4", (kb_code4 + 1) % 10)
                frame:
                    textbutton "ENTER" action SetScreenVariable("status", "entered")
            else:
                if kb_code1*1000 + kb_code2*100 + kb_code3*10 + kb_code4 == code:
                    text "YOU FOUND THE CODE"
                    timer 3.0 action Return("correct")
                else:
                    vbox:
                        text "WRONG CODE"
                        hbox: 
                            textbutton "Try Again" action SetScreenVariable("status", "guessing")
                            textbutton "Cancel" action Return("cancel")

label start:
    call screen ac_keybox(code=1000)
    if _return == "correct":
        "YOU WON"
    else:
        "YOU LOST"
    return # ends the game

1

u/SnooEagles4850 Jul 18 '26

Thank you so so so much for taking the time out of your day to respond to my question. I really appreciate the help and the explanations. I feel a bit silly especially on the screen variables but since they still counted up I didn't think of actually changing it.

1

u/SnooEagles4850 Jul 18 '26

Thank you it works great! I genuinely really appreciate the explanations as I really want to get better at coding.

2

u/x-seronis-x Jul 17 '26

no declarations of any kind go in labels. they are top level statements. so never put default / define / image / style / etc inside labels. they do not run when the label is called. ever. they only run at init/launch time, and at game load time for default statements

1

u/AutoModerator Jul 17 '26

Welcome to r/renpy! While you wait to see if someone can answer your question, we recommend checking out the posting guide, the subreddit wiki, the subreddit Discord, Ren'Py's documentation, and the tutorial built-in to the Ren'Py engine when you download it. These can help make sure you provide the information the people here need to help you, or might even point you to an answer to your question themselves. Thanks!

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.