Ren'Py Basic phone system

SPkiller31

Professional Degenerate
Game Developer
Dec 20, 2020
143
203
Hi there again.

For some time (longer than I would like to admit) I'm trying to implement very basic phone system, or rather bunch of screens and textbuttons but I'm currently going bald while trying to do that.

My game features option to choose location that player wishes to visit via choice menu. I want to add simple "check phone" option in addition to going somewhere or skipping day that will display scrollable list of contacts.(I tried to add option of sorting them depending on which contact player aquired first but that's not most important right now) Contact upon clicking will simply display 3 choices/textbuttons like: Call (which will jump to the certain label depending on character), Messages (that player will be able to read) and going back to choice menu during free time. (Ofcourse while having some basic png of phone in the background but art part of code is kinda irrelevant).
There is a high chance that I already checked 80% if not more, of all already existing examples of phone systems (With the one from being closest to working perfectly, thanks a lot :D) but I always struggled with one thing.

Phones mostly work well from the get-go but I can't make them display correctly via choice menu. I already tried using call/show/jump depending on which code I was trying but it always either closed game and went immediately to main menu or weirdly auto selected other option in choice menu when I was closing/hiding phone screen (for example when having go somewhere, check phone, go to sleep, when closing phone it autosellecst go somewhere).

I assume that maybe my free_time label is f*cked up (unlikely? maybe) or I simply don't know about something obvious (very likely).
I can quite reliably modify code to store messages of each character, display images with an option of making them full screen etc. but act of showing phone itself is just black magic for me, which is little bit embarrasing.
It's very likely that implementing this basic calling/msg system is the last thing I need to do from technical/mechanical part of game. Obviously I'm trying to learn how to do that from scratch/using free examples as I can't currently afford hiring programmer.


Here is my crude free time label in which I would like to include phone option. Weekend is working on very simillar manner besides checking specifically for Saturday or Sunday so I assume it's irrelevant but that why there is else at the start. Code was hugely reduced, namely I deleted all my flags and checks regarding story but that's basically how it looks.
Any tips/examples that will help me are most welcome, thank you in advance,and maybe it will help future folks struggling with that as well.

Python:
else:
    label menu_weekday:
        scene free_time
        menu:
            "Go somewhere":
                label menu_weekday_choices:               
                menu:
                    "City Center":                         
                        menu:
                            "Library":
                                    jump library_first
                            "Bar":
                                    jump bar_first
                            "Go back":
                                jump menu_weekday_choices                                                                                                   
                    "Streets":                                 
                        menu:
                            "Alleways":
                                    jump alleys_first
                            "Cafe":
                                jump cafe_first
                            "Go back":
                                jump menu_weekday_choices                               
                    "Go back":
                        jump menu_weekday
            "Check phone":
                #here I already tried few things like showing screen or jumping to appropiate label
            "Go back to your room and sleep":
                jump sleeping
 

rayminator

Engaged Member
Respected User
Sep 26, 2018
3,130
3,194
show screen cell_phone or call screen cell_phone

I would use call screen cell_phone with a textbutton or a imagebutton to hide the screen
 
  • Like
Reactions: SPkiller31

MidnightArrow

Active Member
Aug 22, 2021
500
451
The big problem I see is that you're a newbie programmer using goto (or "jump") statements and putting labels in the middle of your subroutines to jump to, which has basically been a sin in programming since the 1960s unless you're experienced enough to know how and when it's appropriate to use them (carefully and rarely).

The reason you're returning to the main menu is probably because you reach the end of an execution block, and since the call stack is empty the program has nowhere to go except to terminate.

Every label should be accessed with a call statement, start at the beginning, and run until it reaches a return statement. Even though Ren'py allows you to perform an unstructured jump into the middle of a subroutine, that usually leads to a giant plate of spaghetti code. So pretend the "jump" statement doesn't exist. Each label should be treated as a single execution block that runs until it terminates, and then passes control back to the point it was called instead of deciding where to go next.

Code:
default freeroam_loop = False
default freeroam_phone = False

label main_loop:
    
    $ freeroam_loop = True
    
    while freeroam_loop:
        menu:
            "Go to town.":
                call freeroam_town
            "Use cell phone.":
                call freeroam_phone
            "End freeroam.":
                $ freeroam_loop = False
    
    return


label freeroam_town:
    "I went to town."
    return


label freeroam_phone:

    $ freeroam_phone = True

    while freeroam_phone:
        menu:
            "Who do I want to call?"
            "Beverly." if beverly_unlocked:
                call phone_beverly
            "Dana." if dana_unlocked:
                call phone_dana
            "Rachael." if rachael_unlocked:
                call phone_rachael
            "Nobody.":
                $ freeroam_phone = False
    
    return
There's better ways to code it, but for your skill level this should be fine.
 
  • Heart
Reactions: SPkiller31

SPkiller31

Professional Degenerate
Game Developer
Dec 20, 2020
143
203
Thank you for answer. I honestly did not know jump statement is so problematic and probably 90% of various examples I've seen used that in many ways so thanks for clarifying that for me, I will try to tidy up my code. Guess that's good example of learning by experience.

Code:
label freeroam_phone:

    $ freeroam_phone = True

    while freeroam_phone:
        menu:
            "Who do I want to call?"
            "Beverly." if beverly_unlocked:
                call phone_beverly
            "Dana." if dana_unlocked:
                call phone_dana
            "Rachael." if rachael_unlocked:
                call phone_rachael
            "Nobody.":
                $ freeroam_phone = False
   
    return
I kinda need something little bit more advanced but it should be much easier to make with your example. I thought about using simple menu with options as shown above to call characters but later I realized that additional message system and simple phone panel will add much more depth to my title. But keeping in mind that I'm beginner I might end up using simple choice menu as given in your code, after all I don't want to over-waste time on single mechanic.

Thanks a lot for explanation of labels, I would probably end up using jumps to the very end as it seemed like most fool-proof option. Cheers.
 

MidnightArrow

Active Member
Aug 22, 2021
500
451
Thank you for answer. I honestly did not know jump statement is so problematic and probably 90% of various examples I've seen used that in many ways so thanks for clarifying that for me, I will try to tidy up my code. Guess that's good example of learning by experience.
That's because most people who pick up Ren'py have no programming experience so they don't know best practice.

In theory if you have an extremely linear game that reaches the end of one label and then jumps straight to the next label it's relatively harmless (though I still wouldn't use it even then), and I think PyTom assumed most people want to make extremely linear visual novels since that's the convention of the genre. But any decently experienced programmer would know using goto statements to restart a loop is the kind of shit you do in assembly language, not high-level code.

If you want to do something more complicated then you'll need to rely on screen language. But the essence is the same. Wrap it inside a while loop with a boolean flag to ensure the screen keeps reappearing after you choose an option ("ending the interaction", as PyTom calls it) and branch to the scene in question.

Code:
default freeroam_phone_loop = False

screen cell_phone_options:

    vbox:
        if beverly_unlocked:
            textbutton "Call Beverly":
                action Call("freeroam_call_beverly")

    textbutton "Exit phone":
        action [ SetVariable("freeroam_phone_loop", False), Return() ]

label freeroam_phone:
    $ freeroam_phone_loop = True
    while freeroam_phone_loop:
        call screen cell_phone_options
    return
 
Last edited: